wined3d: Share trace pass
Now that the declaration function is out of the way, the tracing pass, which is very long and 100% the same can be shared between pixel and vertex shaders. The new function is called shader_trace_init(), and is responsible for: - tracing the shader - initializing the function length - setting the shader version [needed very early]
This commit is contained in:
parent
9bae7755ab
commit
17b0d26c1e
|
@ -68,7 +68,6 @@ const SHADER_OPCODE* shader_get_opcode(
|
||||||
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl*) iface;
|
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl*) iface;
|
||||||
|
|
||||||
DWORD i = 0;
|
DWORD i = 0;
|
||||||
DWORD version = This->baseShader.version;
|
|
||||||
DWORD hex_version = This->baseShader.hex_version;
|
DWORD hex_version = This->baseShader.hex_version;
|
||||||
const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
|
const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
|
||||||
|
|
||||||
|
@ -81,8 +80,8 @@ const SHADER_OPCODE* shader_get_opcode(
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
FIXME("Unsupported opcode %lx(%ld) masked %lx version %ld\n",
|
FIXME("Unsupported opcode %#lx(%ld) masked %#lx, shader version %#lx\n",
|
||||||
code, code, code & D3DSI_OPCODE_MASK, version);
|
code, code, code & D3DSI_OPCODE_MASK, hex_version);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +391,7 @@ void shader_get_registers_used(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shader_program_dump_decl_usage(
|
static void shader_dump_decl_usage(
|
||||||
DWORD decl,
|
DWORD decl,
|
||||||
DWORD param) {
|
DWORD param) {
|
||||||
|
|
||||||
|
@ -897,4 +896,144 @@ void shader_hw_def(SHADER_OPCODE_ARG* arg) {
|
||||||
arg->reg_maps->constantsF[reg] = 1;
|
arg->reg_maps->constantsF[reg] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First pass: trace shader, initialize length and version */
|
||||||
|
void shader_trace_init(
|
||||||
|
IWineD3DBaseShader *iface,
|
||||||
|
const DWORD* pFunction) {
|
||||||
|
|
||||||
|
IWineD3DBaseShaderImpl *This =(IWineD3DBaseShaderImpl *)iface;
|
||||||
|
|
||||||
|
const DWORD* pToken = pFunction;
|
||||||
|
const SHADER_OPCODE* curOpcode = NULL;
|
||||||
|
DWORD opcode_token;
|
||||||
|
unsigned int len = 0;
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
|
TRACE("(%p) : Parsing programme\n", This);
|
||||||
|
|
||||||
|
if (NULL != pToken) {
|
||||||
|
while (D3DVS_END() != *pToken) {
|
||||||
|
if (shader_is_version_token(*pToken)) { /** version */
|
||||||
|
This->baseShader.hex_version = *pToken;
|
||||||
|
TRACE("%s_%lu_%lu\n", shader_is_pshader_version(This->baseShader.hex_version)? "ps": "vs",
|
||||||
|
D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version),
|
||||||
|
D3DSHADER_VERSION_MINOR(This->baseShader.hex_version));
|
||||||
|
++pToken;
|
||||||
|
++len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (shader_is_comment(*pToken)) { /** comment */
|
||||||
|
DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
|
||||||
|
++pToken;
|
||||||
|
TRACE("//%s\n", (char*)pToken);
|
||||||
|
pToken += comment_len;
|
||||||
|
len += comment_len + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
opcode_token = *pToken++;
|
||||||
|
curOpcode = shader_get_opcode(iface, opcode_token);
|
||||||
|
len++;
|
||||||
|
|
||||||
|
if (NULL == curOpcode) {
|
||||||
|
int tokens_read;
|
||||||
|
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||||
|
tokens_read = shader_skip_unrecognized(iface, pToken);
|
||||||
|
pToken += tokens_read;
|
||||||
|
len += tokens_read;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (curOpcode->opcode == D3DSIO_DCL) {
|
||||||
|
|
||||||
|
DWORD usage = *pToken;
|
||||||
|
DWORD param = *(pToken + 1);
|
||||||
|
|
||||||
|
shader_dump_decl_usage(usage, param);
|
||||||
|
shader_dump_ins_modifiers(param);
|
||||||
|
TRACE(" ");
|
||||||
|
shader_dump_param(iface, param, 0, 0);
|
||||||
|
pToken += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
} else if (curOpcode->opcode == D3DSIO_DEF) {
|
||||||
|
|
||||||
|
unsigned int offset = shader_get_float_offset(*pToken);
|
||||||
|
|
||||||
|
TRACE("def c%u = %f, %f, %f, %f", offset,
|
||||||
|
*(float *)(pToken + 1),
|
||||||
|
*(float *)(pToken + 2),
|
||||||
|
*(float *)(pToken + 3),
|
||||||
|
*(float *)(pToken + 4));
|
||||||
|
|
||||||
|
pToken += 5;
|
||||||
|
len += 5;
|
||||||
|
} else if (curOpcode->opcode == D3DSIO_DEFI) {
|
||||||
|
|
||||||
|
TRACE("defi i%lu = %ld, %ld, %ld, %ld", *pToken & D3DSP_REGNUM_MASK,
|
||||||
|
(long) *(pToken + 1),
|
||||||
|
(long) *(pToken + 2),
|
||||||
|
(long) *(pToken + 3),
|
||||||
|
(long) *(pToken + 4));
|
||||||
|
|
||||||
|
pToken += 5;
|
||||||
|
len += 5;
|
||||||
|
|
||||||
|
} else if (curOpcode->opcode == D3DSIO_DEFB) {
|
||||||
|
|
||||||
|
TRACE("defb b%lu = %s", *pToken & D3DSP_REGNUM_MASK,
|
||||||
|
*(pToken + 1)? "true": "false");
|
||||||
|
|
||||||
|
pToken += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
DWORD param, addr_token;
|
||||||
|
int tokens_read;
|
||||||
|
|
||||||
|
/* Print out predication source token first - it follows
|
||||||
|
* the destination token. */
|
||||||
|
if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED) {
|
||||||
|
TRACE("(");
|
||||||
|
shader_dump_param(iface, *(pToken + 2), 0, 1);
|
||||||
|
TRACE(") ");
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("%s", curOpcode->name);
|
||||||
|
if (curOpcode->num_params > 0) {
|
||||||
|
|
||||||
|
/* Destination token */
|
||||||
|
tokens_read = shader_get_param(iface, pToken, ¶m, &addr_token);
|
||||||
|
pToken += tokens_read;
|
||||||
|
len += tokens_read;
|
||||||
|
|
||||||
|
shader_dump_ins_modifiers(param);
|
||||||
|
TRACE(" ");
|
||||||
|
shader_dump_param(iface, param, addr_token, 0);
|
||||||
|
|
||||||
|
/* Predication token - already printed out, just skip it */
|
||||||
|
if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED) {
|
||||||
|
pToken++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
/* Other source tokens */
|
||||||
|
for (i = 1; i < curOpcode->num_params; ++i) {
|
||||||
|
|
||||||
|
tokens_read = shader_get_param(iface, pToken, ¶m, &addr_token);
|
||||||
|
pToken += tokens_read;
|
||||||
|
len += tokens_read;
|
||||||
|
|
||||||
|
TRACE(", ");
|
||||||
|
shader_dump_param(iface, param, addr_token, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
This->baseShader.functionLength = (len + 1) * sizeof(DWORD);
|
||||||
|
} else {
|
||||||
|
This->baseShader.functionLength = 1; /* no Function defined use fixed function vertex processing */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Move other shared code here */
|
/* TODO: Move other shared code here */
|
||||||
|
|
|
@ -217,7 +217,7 @@ static void shader_glsl_get_register_name(
|
||||||
if (param & D3DVS_ADDRMODE_RELATIVE) {
|
if (param & D3DVS_ADDRMODE_RELATIVE) {
|
||||||
/* Relative addressing on shaders 2.0+ have a relative address token,
|
/* Relative addressing on shaders 2.0+ have a relative address token,
|
||||||
* prior to that, it was hard-coded as "A0.x" because there's only 1 register */
|
* prior to that, it was hard-coded as "A0.x" because there's only 1 register */
|
||||||
if (This->baseShader.version >= 20) {
|
if (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2) {
|
||||||
char relStr[100], relReg[50], relMask[6];
|
char relStr[100], relReg[50], relMask[6];
|
||||||
shader_glsl_add_param(arg, addr_token, 0, TRUE, relReg, relMask, relStr);
|
shader_glsl_add_param(arg, addr_token, 0, TRUE, relReg, relMask, relStr);
|
||||||
sprintf(tmpStr, "C[%s + %lu]", relStr, reg);
|
sprintf(tmpStr, "C[%s + %lu]", relStr, reg);
|
||||||
|
@ -713,7 +713,7 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) {
|
||||||
|
|
||||||
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||||
SHADER_BUFFER* buffer = arg->buffer;
|
SHADER_BUFFER* buffer = arg->buffer;
|
||||||
DWORD version = This->baseShader.version;
|
DWORD hex_version = This->baseShader.hex_version;
|
||||||
|
|
||||||
char dst_str[100], dst_reg[50], dst_mask[6];
|
char dst_str[100], dst_reg[50], dst_mask[6];
|
||||||
char src0_str[100], src0_reg[50], src0_mask[6];
|
char src0_str[100], src0_reg[50], src0_mask[6];
|
||||||
|
@ -724,18 +724,18 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) {
|
||||||
shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
|
shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
|
||||||
|
|
||||||
/* 1.0-1.3: Use destination register as coordinate source.
|
/* 1.0-1.3: Use destination register as coordinate source.
|
||||||
2.0+: Use provided coordinate source register. */
|
* 2.0+: Use provided coordinate source register. */
|
||||||
if (version == 14) {
|
if (hex_version == D3DPS_VERSION(1,4)) {
|
||||||
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
||||||
sprintf(src1_str, "mytex%lu", reg_dest_code);
|
sprintf(src1_str, "mytex%lu", reg_dest_code);
|
||||||
} else if (version > 14) {
|
} else if (hex_version > D3DPS_VERSION(1,4)) {
|
||||||
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
||||||
shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
|
shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1.0-1.4: Use destination register number as texture code.
|
/* 1.0-1.4: Use destination register number as texture code.
|
||||||
2.0+: Use provided sampler number as texure code. */
|
* 2.0+: Use provided sampler number as texure code. */
|
||||||
if (version < 14) {
|
if (hex_version < D3DPS_VERSION(1,4)) {
|
||||||
shader_addline(buffer, "%s = texture2D(mytex%lu, gl_TexCoord[%lu].st);\n",
|
shader_addline(buffer, "%s = texture2D(mytex%lu, gl_TexCoord[%lu].st);\n",
|
||||||
dst_str, reg_dest_code, reg_dest_code);
|
dst_str, reg_dest_code, reg_dest_code);
|
||||||
} else {
|
} else {
|
||||||
|
@ -749,7 +749,7 @@ void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) {
|
||||||
|
|
||||||
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
|
||||||
SHADER_BUFFER* buffer = arg->buffer;
|
SHADER_BUFFER* buffer = arg->buffer;
|
||||||
DWORD version = This->baseShader.version;
|
DWORD hex_version = This->baseShader.hex_version;
|
||||||
|
|
||||||
char tmpStr[100];
|
char tmpStr[100];
|
||||||
char tmpReg[50];
|
char tmpReg[50];
|
||||||
|
@ -758,7 +758,7 @@ void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) {
|
||||||
|
|
||||||
shader_glsl_add_param(arg, arg->dst, 0, FALSE, tmpReg, tmpMask, tmpStr);
|
shader_glsl_add_param(arg, arg->dst, 0, FALSE, tmpReg, tmpMask, tmpStr);
|
||||||
|
|
||||||
if (version != 14) {
|
if (hex_version != D3DPS_VERSION(1,4)) {
|
||||||
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
|
||||||
shader_addline(buffer, "%s = gl_TexCoord[%lu];\n", tmpReg, reg);
|
shader_addline(buffer, "%s = gl_TexCoord[%lu];\n", tmpReg, reg);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -937,32 +937,26 @@ static void pshader_gen_input_modifier_line (
|
||||||
sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr);
|
sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pshader_set_version(
|
static void pshader_set_limits(
|
||||||
IWineD3DPixelShaderImpl *This,
|
IWineD3DPixelShaderImpl *This) {
|
||||||
DWORD version) {
|
|
||||||
|
|
||||||
DWORD major = (version >> 8) & 0x0F;
|
|
||||||
DWORD minor = version & 0x0F;
|
|
||||||
|
|
||||||
This->baseShader.hex_version = version;
|
|
||||||
This->baseShader.version = major * 10 + minor;
|
|
||||||
TRACE("ps_%lu_%lu\n", major, minor);
|
|
||||||
|
|
||||||
This->baseShader.limits.attributes = 0;
|
This->baseShader.limits.attributes = 0;
|
||||||
This->baseShader.limits.address = 0;
|
This->baseShader.limits.address = 0;
|
||||||
|
|
||||||
switch (This->baseShader.version) {
|
switch (This->baseShader.hex_version) {
|
||||||
case 10:
|
case D3DPS_VERSION(1,0):
|
||||||
case 11:
|
case D3DPS_VERSION(1,1):
|
||||||
case 12:
|
case D3DPS_VERSION(1,2):
|
||||||
case 13: This->baseShader.limits.temporary = 2;
|
case D3DPS_VERSION(1,3):
|
||||||
|
This->baseShader.limits.temporary = 2;
|
||||||
This->baseShader.limits.constant_float = 8;
|
This->baseShader.limits.constant_float = 8;
|
||||||
This->baseShader.limits.constant_int = 0;
|
This->baseShader.limits.constant_int = 0;
|
||||||
This->baseShader.limits.constant_bool = 0;
|
This->baseShader.limits.constant_bool = 0;
|
||||||
This->baseShader.limits.texture = 4;
|
This->baseShader.limits.texture = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 14: This->baseShader.limits.temporary = 6;
|
case D3DPS_VERSION(1,4):
|
||||||
|
This->baseShader.limits.temporary = 6;
|
||||||
This->baseShader.limits.constant_float = 8;
|
This->baseShader.limits.constant_float = 8;
|
||||||
This->baseShader.limits.constant_int = 0;
|
This->baseShader.limits.constant_int = 0;
|
||||||
This->baseShader.limits.constant_bool = 0;
|
This->baseShader.limits.constant_bool = 0;
|
||||||
|
@ -970,15 +964,17 @@ static void pshader_set_version(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */
|
/* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */
|
||||||
case 20:
|
case D3DPS_VERSION(2,0):
|
||||||
case 21: This->baseShader.limits.temporary = 32;
|
case D3DPS_VERSION(2,1):
|
||||||
|
This->baseShader.limits.temporary = 32;
|
||||||
This->baseShader.limits.constant_float = 32;
|
This->baseShader.limits.constant_float = 32;
|
||||||
This->baseShader.limits.constant_int = 16;
|
This->baseShader.limits.constant_int = 16;
|
||||||
This->baseShader.limits.constant_bool = 16;
|
This->baseShader.limits.constant_bool = 16;
|
||||||
This->baseShader.limits.texture = 8;
|
This->baseShader.limits.texture = 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30: This->baseShader.limits.temporary = 32;
|
case D3DPS_VERSION(3,0):
|
||||||
|
This->baseShader.limits.temporary = 32;
|
||||||
This->baseShader.limits.constant_float = 224;
|
This->baseShader.limits.constant_float = 224;
|
||||||
This->baseShader.limits.constant_int = 16;
|
This->baseShader.limits.constant_int = 16;
|
||||||
This->baseShader.limits.constant_bool = 16;
|
This->baseShader.limits.constant_bool = 16;
|
||||||
|
@ -990,7 +986,8 @@ static void pshader_set_version(
|
||||||
This->baseShader.limits.constant_int = 0;
|
This->baseShader.limits.constant_int = 0;
|
||||||
This->baseShader.limits.constant_bool = 0;
|
This->baseShader.limits.constant_bool = 0;
|
||||||
This->baseShader.limits.texture = 8;
|
This->baseShader.limits.texture = 8;
|
||||||
FIXME("Unrecognized pixel shader version %lx!\n", version);
|
FIXME("Unrecognized pixel shader version %#lx\n",
|
||||||
|
This->baseShader.hex_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,7 +1112,7 @@ static void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
|
||||||
DWORD dst = arg->dst;
|
DWORD dst = arg->dst;
|
||||||
DWORD* src = arg->src;
|
DWORD* src = arg->src;
|
||||||
SHADER_BUFFER* buffer = arg->buffer;
|
SHADER_BUFFER* buffer = arg->buffer;
|
||||||
DWORD version = This->baseShader.version;
|
DWORD hex_version = This->baseShader.hex_version;
|
||||||
|
|
||||||
char reg_dest[40];
|
char reg_dest[40];
|
||||||
char reg_coord[40];
|
char reg_coord[40];
|
||||||
|
@ -1128,14 +1125,14 @@ static void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
|
||||||
|
|
||||||
/* 1.0-1.3: Use destination register as coordinate source.
|
/* 1.0-1.3: Use destination register as coordinate source.
|
||||||
2.0+: Use provided coordinate source register. */
|
2.0+: Use provided coordinate source register. */
|
||||||
if (version < 14)
|
if (hex_version < D3DPS_VERSION(1,4))
|
||||||
strcpy(reg_coord, reg_dest);
|
strcpy(reg_coord, reg_dest);
|
||||||
else
|
else
|
||||||
pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, arg->reg_maps->constantsF);
|
pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, arg->reg_maps->constantsF);
|
||||||
|
|
||||||
/* 1.0-1.4: Use destination register number as texture code.
|
/* 1.0-1.4: Use destination register number as texture code.
|
||||||
2.0+: Use provided sampler number as texure code. */
|
2.0+: Use provided sampler number as texure code. */
|
||||||
if (version < 20)
|
if (hex_version < D3DPS_VERSION(2,0))
|
||||||
reg_sampler_code = reg_dest_code;
|
reg_sampler_code = reg_dest_code;
|
||||||
else
|
else
|
||||||
reg_sampler_code = src[1] & D3DSP_REGNUM_MASK;
|
reg_sampler_code = src[1] & D3DSP_REGNUM_MASK;
|
||||||
|
@ -1150,11 +1147,11 @@ static void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg) {
|
||||||
DWORD dst = arg->dst;
|
DWORD dst = arg->dst;
|
||||||
DWORD* src = arg->src;
|
DWORD* src = arg->src;
|
||||||
SHADER_BUFFER* buffer = arg->buffer;
|
SHADER_BUFFER* buffer = arg->buffer;
|
||||||
DWORD version = This->baseShader.version;
|
DWORD hex_version = This->baseShader.hex_version;
|
||||||
|
|
||||||
char tmp[20];
|
char tmp[20];
|
||||||
get_write_mask(dst, tmp);
|
get_write_mask(dst, tmp);
|
||||||
if (version != 14) {
|
if (hex_version != D3DPS_VERSION(1,4)) {
|
||||||
DWORD reg = dst & D3DSP_REGNUM_MASK;
|
DWORD reg = dst & D3DSP_REGNUM_MASK;
|
||||||
shader_addline(buffer, "MOV T%lu%s, fragment.texcoord[%lu];\n", reg, tmp, reg);
|
shader_addline(buffer, "MOV T%lu%s, fragment.texcoord[%lu];\n", reg, tmp, reg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1398,158 +1395,19 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
|
static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
|
||||||
|
|
||||||
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
|
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
|
||||||
const DWORD* pToken = pFunction;
|
|
||||||
const SHADER_OPCODE *curOpcode = NULL;
|
|
||||||
DWORD opcode_token;
|
|
||||||
DWORD len = 0;
|
|
||||||
DWORD i;
|
|
||||||
TRACE("(%p) : Parsing programme\n", This);
|
|
||||||
|
|
||||||
if (NULL != pToken) {
|
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
|
||||||
while (D3DPS_END() != *pToken) {
|
pshader_set_limits(This);
|
||||||
if (shader_is_pshader_version(*pToken)) { /** version */
|
|
||||||
pshader_set_version(This, *pToken);
|
|
||||||
++pToken;
|
|
||||||
++len;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (shader_is_comment(*pToken)) { /** comment */
|
|
||||||
DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
|
|
||||||
++pToken;
|
|
||||||
TRACE("//%s\n", (char*)pToken);
|
|
||||||
pToken += comment_len;
|
|
||||||
len += comment_len + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!This->baseShader.version) {
|
|
||||||
WARN("(%p) : pixel shader doesn't have a valid version identifier\n", This);
|
|
||||||
}
|
|
||||||
opcode_token = *pToken++;
|
|
||||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
|
||||||
len++;
|
|
||||||
if (NULL == curOpcode) {
|
|
||||||
int tokens_read;
|
|
||||||
|
|
||||||
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
|
||||||
tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
|
||||||
pToken += tokens_read;
|
|
||||||
len += tokens_read;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (curOpcode->opcode == D3DSIO_DCL) {
|
|
||||||
DWORD usage = *pToken;
|
|
||||||
DWORD param = *(pToken + 1);
|
|
||||||
DWORD regtype = shader_get_regtype(param);
|
|
||||||
|
|
||||||
/* Only print extended declaration for samplers or 3.0 input registers */
|
|
||||||
if (regtype == D3DSPR_SAMPLER ||
|
|
||||||
(This->baseShader.version >= 30 && regtype == D3DSPR_INPUT))
|
|
||||||
shader_program_dump_decl_usage(usage, param);
|
|
||||||
else
|
|
||||||
TRACE("dcl");
|
|
||||||
|
|
||||||
shader_dump_ins_modifiers(param);
|
|
||||||
TRACE(" ");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, param, 0, 0);
|
|
||||||
pToken += 2;
|
|
||||||
len += 2;
|
|
||||||
|
|
||||||
} else if (curOpcode->opcode == D3DSIO_DEF) {
|
|
||||||
|
|
||||||
unsigned int offset = shader_get_float_offset(*pToken);
|
|
||||||
|
|
||||||
TRACE("def c%u = %f, %f, %f, %f", offset,
|
|
||||||
*(float *)(pToken + 1),
|
|
||||||
*(float *)(pToken + 2),
|
|
||||||
*(float *)(pToken + 3),
|
|
||||||
*(float *)(pToken + 4));
|
|
||||||
|
|
||||||
pToken += 5;
|
|
||||||
len += 5;
|
|
||||||
|
|
||||||
} else if (curOpcode->opcode == D3DSIO_DEFI) {
|
|
||||||
|
|
||||||
TRACE("defi i%lu = %ld, %ld, %ld, %ld", *pToken & D3DSP_REGNUM_MASK,
|
|
||||||
(long) *(pToken + 1),
|
|
||||||
(long) *(pToken + 2),
|
|
||||||
(long) *(pToken + 3),
|
|
||||||
(long) *(pToken + 4));
|
|
||||||
|
|
||||||
pToken += 5;
|
|
||||||
len += 5;
|
|
||||||
|
|
||||||
} else if (curOpcode->opcode == D3DSIO_DEFB) {
|
|
||||||
|
|
||||||
TRACE("defb b%lu = %s", *pToken & D3DSP_REGNUM_MASK,
|
|
||||||
*(pToken + 1)? "true": "false");
|
|
||||||
|
|
||||||
pToken += 2;
|
|
||||||
len += 2;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
DWORD param, addr_token;
|
|
||||||
int tokens_read;
|
|
||||||
|
|
||||||
/* Print out predication source token first - it follows
|
|
||||||
* the destination token. */
|
|
||||||
if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED) {
|
|
||||||
TRACE("(");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, *(pToken + 2), 0, 1);
|
|
||||||
TRACE(") ");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("%s", curOpcode->name);
|
|
||||||
if (curOpcode->num_params > 0) {
|
|
||||||
|
|
||||||
/* Destination token */
|
|
||||||
tokens_read = shader_get_param((IWineD3DBaseShader*) This,
|
|
||||||
pToken, ¶m, &addr_token);
|
|
||||||
pToken += tokens_read;
|
|
||||||
len += tokens_read;
|
|
||||||
|
|
||||||
shader_dump_ins_modifiers(param);
|
|
||||||
TRACE(" ");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, param, addr_token, 0);
|
|
||||||
|
|
||||||
/* Predication token - already printed out, just skip it */
|
|
||||||
if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED) {
|
|
||||||
pToken++;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Other source tokens */
|
|
||||||
for (i = 1; i < curOpcode->num_params; ++i) {
|
|
||||||
|
|
||||||
tokens_read = shader_get_param((IWineD3DBaseShader*) This,
|
|
||||||
pToken, ¶m, &addr_token);
|
|
||||||
pToken += tokens_read;
|
|
||||||
len += tokens_read;
|
|
||||||
|
|
||||||
TRACE(", ");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, param, addr_token, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
This->baseShader.functionLength = (len + 1) * sizeof(DWORD);
|
|
||||||
} else {
|
|
||||||
This->baseShader.functionLength = 1; /* no Function defined use fixed function vertex processing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate HW shader in needed */
|
/* Generate HW shader in needed */
|
||||||
if (NULL != pFunction && wined3d_settings.vs_mode == VS_HW) {
|
if (NULL != pFunction && wined3d_settings.vs_mode == VS_HW) {
|
||||||
TRACE("(%p) : Generating hardware program\n", This);
|
TRACE("(%p) : Generating hardware program\n", This);
|
||||||
#if 1
|
|
||||||
IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction);
|
IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("(%p) : Copying the function\n", This);
|
TRACE("(%p) : Copying the function\n", This);
|
||||||
/* copy the function ... because it will certainly be released by application */
|
|
||||||
if (NULL != pFunction) {
|
if (NULL != pFunction) {
|
||||||
This->baseShader.function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
|
This->baseShader.function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
|
||||||
memcpy((void *)This->baseShader.function, pFunction, This->baseShader.functionLength);
|
memcpy((void *)This->baseShader.function, pFunction, This->baseShader.functionLength);
|
||||||
|
|
|
@ -709,16 +709,8 @@ inline static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vshader_set_version(
|
static void vshader_set_limits(
|
||||||
IWineD3DVertexShaderImpl *This,
|
IWineD3DVertexShaderImpl *This) {
|
||||||
DWORD version) {
|
|
||||||
|
|
||||||
DWORD major = (version >> 8) & 0x0F;
|
|
||||||
DWORD minor = version & 0x0F;
|
|
||||||
|
|
||||||
This->baseShader.hex_version = version;
|
|
||||||
This->baseShader.version = major * 10 + minor;
|
|
||||||
TRACE("vs_%lu_%lu\n", major, minor);
|
|
||||||
|
|
||||||
This->baseShader.limits.texture = 0;
|
This->baseShader.limits.texture = 0;
|
||||||
This->baseShader.limits.attributes = 16;
|
This->baseShader.limits.attributes = 16;
|
||||||
|
@ -726,22 +718,25 @@ static void vshader_set_version(
|
||||||
/* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
|
/* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
|
||||||
This->baseShader.limits.constant_float = WINED3D_VSHADER_MAX_CONSTANTS;
|
This->baseShader.limits.constant_float = WINED3D_VSHADER_MAX_CONSTANTS;
|
||||||
|
|
||||||
switch (This->baseShader.version) {
|
switch (This->baseShader.hex_version) {
|
||||||
case 10:
|
case D3DVS_VERSION(1,0):
|
||||||
case 11: This->baseShader.limits.temporary = 12;
|
case D3DVS_VERSION(1,1):
|
||||||
|
This->baseShader.limits.temporary = 12;
|
||||||
This->baseShader.limits.constant_bool = 0;
|
This->baseShader.limits.constant_bool = 0;
|
||||||
This->baseShader.limits.constant_int = 0;
|
This->baseShader.limits.constant_int = 0;
|
||||||
This->baseShader.limits.address = 1;
|
This->baseShader.limits.address = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 20:
|
case D3DVS_VERSION(2,0):
|
||||||
case 21: This->baseShader.limits.temporary = 12;
|
case D3DVS_VERSION(2,1):
|
||||||
|
This->baseShader.limits.temporary = 12;
|
||||||
This->baseShader.limits.constant_bool = 16;
|
This->baseShader.limits.constant_bool = 16;
|
||||||
This->baseShader.limits.constant_int = 16;
|
This->baseShader.limits.constant_int = 16;
|
||||||
This->baseShader.limits.address = 1;
|
This->baseShader.limits.address = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30: This->baseShader.limits.temporary = 32;
|
case D3DVS_VERSION(3,0):
|
||||||
|
This->baseShader.limits.temporary = 32;
|
||||||
This->baseShader.limits.constant_bool = 32;
|
This->baseShader.limits.constant_bool = 32;
|
||||||
This->baseShader.limits.constant_int = 32;
|
This->baseShader.limits.constant_int = 32;
|
||||||
This->baseShader.limits.address = 1;
|
This->baseShader.limits.address = 1;
|
||||||
|
@ -751,7 +746,8 @@ static void vshader_set_version(
|
||||||
This->baseShader.limits.constant_bool = 0;
|
This->baseShader.limits.constant_bool = 0;
|
||||||
This->baseShader.limits.constant_int = 0;
|
This->baseShader.limits.constant_int = 0;
|
||||||
This->baseShader.limits.address = 1;
|
This->baseShader.limits.address = 1;
|
||||||
FIXME("Unrecognized vertex shader version %lx!\n", version);
|
FIXME("Unrecognized vertex shader version %#lx\n",
|
||||||
|
This->baseShader.hex_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1316,140 +1312,11 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader*
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
|
static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
|
||||||
|
|
||||||
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
||||||
const DWORD* pToken = pFunction;
|
|
||||||
const SHADER_OPCODE* curOpcode = NULL;
|
|
||||||
DWORD opcode_token;
|
|
||||||
DWORD len = 0;
|
|
||||||
DWORD i;
|
|
||||||
TRACE("(%p) : Parsing programme\n", This);
|
|
||||||
|
|
||||||
if (NULL != pToken) {
|
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
|
||||||
while (D3DVS_END() != *pToken) {
|
vshader_set_limits(This);
|
||||||
if (shader_is_vshader_version(*pToken)) { /** version */
|
|
||||||
vshader_set_version(This, *pToken);
|
|
||||||
++pToken;
|
|
||||||
++len;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (shader_is_comment(*pToken)) { /** comment */
|
|
||||||
DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
|
|
||||||
++pToken;
|
|
||||||
TRACE("//%s\n", (char*)pToken);
|
|
||||||
pToken += comment_len;
|
|
||||||
len += comment_len + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
opcode_token = *pToken++;
|
|
||||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
|
||||||
len++;
|
|
||||||
|
|
||||||
if (NULL == curOpcode) {
|
|
||||||
int tokens_read;
|
|
||||||
|
|
||||||
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
|
||||||
tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
|
||||||
pToken += tokens_read;
|
|
||||||
len += tokens_read;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (curOpcode->opcode == D3DSIO_DCL) {
|
|
||||||
|
|
||||||
DWORD usage = *pToken;
|
|
||||||
DWORD param = *(pToken + 1);
|
|
||||||
|
|
||||||
shader_program_dump_decl_usage(usage, param);
|
|
||||||
shader_dump_ins_modifiers(param);
|
|
||||||
TRACE(" ");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, param, 0, 0);
|
|
||||||
pToken += 2;
|
|
||||||
len += 2;
|
|
||||||
|
|
||||||
} else if (curOpcode->opcode == D3DSIO_DEF) {
|
|
||||||
|
|
||||||
unsigned int offset = shader_get_float_offset(*pToken);
|
|
||||||
|
|
||||||
TRACE("def c%u = %f, %f, %f, %f", offset,
|
|
||||||
*(float *)(pToken + 1),
|
|
||||||
*(float *)(pToken + 2),
|
|
||||||
*(float *)(pToken + 3),
|
|
||||||
*(float *)(pToken + 4));
|
|
||||||
|
|
||||||
pToken += 5;
|
|
||||||
len += 5;
|
|
||||||
|
|
||||||
} else if (curOpcode->opcode == D3DSIO_DEFI) {
|
|
||||||
|
|
||||||
TRACE("defi i%lu = %ld, %ld, %ld, %ld", *pToken & D3DSP_REGNUM_MASK,
|
|
||||||
(long) *(pToken + 1),
|
|
||||||
(long) *(pToken + 2),
|
|
||||||
(long) *(pToken + 3),
|
|
||||||
(long) *(pToken + 4));
|
|
||||||
|
|
||||||
pToken += 5;
|
|
||||||
len += 5;
|
|
||||||
|
|
||||||
} else if (curOpcode->opcode == D3DSIO_DEFB) {
|
|
||||||
|
|
||||||
TRACE("defb b%lu = %s", *pToken & D3DSP_REGNUM_MASK,
|
|
||||||
*(pToken + 1)? "true": "false");
|
|
||||||
|
|
||||||
pToken += 2;
|
|
||||||
len += 2;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
DWORD param, addr_token;
|
|
||||||
int tokens_read;
|
|
||||||
|
|
||||||
/* Print out predication source token first - it follows
|
|
||||||
* the destination token. */
|
|
||||||
if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED) {
|
|
||||||
TRACE("(");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, *(pToken + 2), 0, 1);
|
|
||||||
TRACE(") ");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("%s", curOpcode->name);
|
|
||||||
if (curOpcode->num_params > 0) {
|
|
||||||
|
|
||||||
/* Destination token */
|
|
||||||
tokens_read = shader_get_param((IWineD3DBaseShader*) This,
|
|
||||||
pToken, ¶m, &addr_token);
|
|
||||||
pToken += tokens_read;
|
|
||||||
len += tokens_read;
|
|
||||||
|
|
||||||
shader_dump_ins_modifiers(param);
|
|
||||||
TRACE(" ");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, param, addr_token, 0);
|
|
||||||
|
|
||||||
/* Predication token - already printed out, just skip it */
|
|
||||||
if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED) {
|
|
||||||
pToken++;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Other source tokens */
|
|
||||||
for (i = 1; i < curOpcode->num_params; ++i) {
|
|
||||||
|
|
||||||
tokens_read = shader_get_param((IWineD3DBaseShader*) This,
|
|
||||||
pToken, ¶m, &addr_token);
|
|
||||||
pToken += tokens_read;
|
|
||||||
len += tokens_read;
|
|
||||||
|
|
||||||
TRACE(", ");
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, param, addr_token, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
This->baseShader.functionLength = (len + 1) * sizeof(DWORD);
|
|
||||||
} else {
|
|
||||||
This->baseShader.functionLength = 1; /* no Function defined use fixed function vertex processing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate HW shader in needed */
|
/* Generate HW shader in needed */
|
||||||
if (NULL != pFunction && wined3d_settings.vs_mode == VS_HW)
|
if (NULL != pFunction && wined3d_settings.vs_mode == VS_HW)
|
||||||
|
|
|
@ -1349,7 +1349,6 @@ extern void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg);
|
||||||
*/
|
*/
|
||||||
typedef struct IWineD3DBaseShaderClass
|
typedef struct IWineD3DBaseShaderClass
|
||||||
{
|
{
|
||||||
DWORD version;
|
|
||||||
DWORD hex_version;
|
DWORD hex_version;
|
||||||
SHADER_LIMITS limits;
|
SHADER_LIMITS limits;
|
||||||
SHADER_PARSE_STATE parse_state;
|
SHADER_PARSE_STATE parse_state;
|
||||||
|
@ -1368,10 +1367,6 @@ typedef struct IWineD3DBaseShaderImpl {
|
||||||
IWineD3DBaseShaderClass baseShader;
|
IWineD3DBaseShaderClass baseShader;
|
||||||
} IWineD3DBaseShaderImpl;
|
} IWineD3DBaseShaderImpl;
|
||||||
|
|
||||||
extern void shader_program_dump_decl_usage(
|
|
||||||
DWORD dcl,
|
|
||||||
DWORD param);
|
|
||||||
|
|
||||||
extern void shader_get_registers_used(
|
extern void shader_get_registers_used(
|
||||||
IWineD3DBaseShader *iface,
|
IWineD3DBaseShader *iface,
|
||||||
shader_reg_maps* reg_maps,
|
shader_reg_maps* reg_maps,
|
||||||
|
@ -1392,6 +1387,10 @@ extern void shader_dump_param(
|
||||||
const DWORD addr_token,
|
const DWORD addr_token,
|
||||||
int input);
|
int input);
|
||||||
|
|
||||||
|
extern void shader_trace_init(
|
||||||
|
IWineD3DBaseShader *iface,
|
||||||
|
const DWORD* pFunction);
|
||||||
|
|
||||||
extern int shader_get_param(
|
extern int shader_get_param(
|
||||||
IWineD3DBaseShader* iface,
|
IWineD3DBaseShader* iface,
|
||||||
const DWORD* pToken,
|
const DWORD* pToken,
|
||||||
|
|
Loading…
Reference in New Issue