Commit 42b89791 authored by Ivan Gyurdiev's avatar Ivan Gyurdiev Committed by Alexandre Julliard

wined3d: Take predication tokens into account.

Each instruction can have a predication token. Account for it in the trace pass, register count pass, and store it in the SHADER_OPCODE_ARG structure for generation. MSDN claims the token is at the end of the instruction, but that's not true - testing a demo, which lets me manipulate the shader shows the predication token is the first source token immediately following the destination token.
parent fa62d9d3
...@@ -176,6 +176,7 @@ void shader_get_registers_used( ...@@ -176,6 +176,7 @@ void shader_get_registers_used(
while (D3DVS_END() != *pToken) { while (D3DVS_END() != *pToken) {
CONST SHADER_OPCODE* curOpcode; CONST SHADER_OPCODE* curOpcode;
DWORD opcode_token;
/* Skip version */ /* Skip version */
if (shader_is_version_token(*pToken)) { if (shader_is_version_token(*pToken)) {
...@@ -191,8 +192,8 @@ void shader_get_registers_used( ...@@ -191,8 +192,8 @@ void shader_get_registers_used(
} }
/* Fetch opcode */ /* Fetch opcode */
curOpcode = shader_get_opcode(iface, *pToken); opcode_token = *pToken++;
++pToken; curOpcode = shader_get_opcode(iface, opcode_token);
/* Unhandled opcode, and its parameters */ /* Unhandled opcode, and its parameters */
if (NULL == curOpcode) { if (NULL == curOpcode) {
...@@ -212,9 +213,19 @@ void shader_get_registers_used( ...@@ -212,9 +213,19 @@ void shader_get_registers_used(
/* Set texture registers, and temporary registers */ /* Set texture registers, and temporary registers */
} else { } else {
int i; int i, limit;
for (i = 0; i < curOpcode->num_params; ++i) { /* This will loop over all the registers and try to
* make a bitmask of the ones we're interested in.
*
* Relative addressing tokens are ignored, but that's
* okay, since we'll catch any address registers when
* they are initialized (required by spec) */
limit = (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED)?
curOpcode->num_params + 1: curOpcode->num_params;
for (i = 0; i < limit; ++i) {
DWORD param, addr_token, reg, regtype; DWORD param, addr_token, reg, regtype;
pToken += shader_get_param(iface, pToken, &param, &addr_token); pToken += shader_get_param(iface, pToken, &param, &addr_token);
...@@ -359,6 +370,8 @@ void shader_dump_param( ...@@ -359,6 +370,8 @@ void shader_dump_param(
TRACE("-"); TRACE("-");
else if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_COMP) else if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_COMP)
TRACE("1-"); TRACE("1-");
else if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NOT)
TRACE("!");
} }
switch (regtype) { switch (regtype) {
...@@ -445,10 +458,10 @@ void shader_dump_param( ...@@ -445,10 +458,10 @@ void shader_dump_param(
if (0 != (param & D3DSP_SRCMOD_MASK)) { if (0 != (param & D3DSP_SRCMOD_MASK)) {
DWORD mask = param & D3DSP_SRCMOD_MASK; DWORD mask = param & D3DSP_SRCMOD_MASK;
/*TRACE("_modifier(0x%08lx) ", mask);*/
switch (mask) { switch (mask) {
case D3DSPSM_NONE: break; case D3DSPSM_NONE: break;
case D3DSPSM_NEG: break; case D3DSPSM_NEG: break;
case D3DSPSM_NOT: break;
case D3DSPSM_BIAS: TRACE("_bias"); break; case D3DSPSM_BIAS: TRACE("_bias"); break;
case D3DSPSM_BIASNEG: TRACE("_bias"); break; case D3DSPSM_BIASNEG: TRACE("_bias"); break;
case D3DSPSM_SIGN: TRACE("_bx2"); break; case D3DSPSM_SIGN: TRACE("_bx2"); break;
...@@ -459,7 +472,7 @@ void shader_dump_param( ...@@ -459,7 +472,7 @@ void shader_dump_param(
case D3DSPSM_DZ: TRACE("_dz"); break; case D3DSPSM_DZ: TRACE("_dz"); break;
case D3DSPSM_DW: TRACE("_dw"); break; case D3DSPSM_DW: TRACE("_dw"); break;
default: default:
TRACE("_unknown(0x%08lx)", mask); TRACE("_unknown_modifier(%#lx)", mask >> D3DSP_SRCMOD_SHIFT);
} }
} }
...@@ -619,6 +632,9 @@ void generate_base_shader( ...@@ -619,6 +632,9 @@ void generate_base_shader(
hw_arg.dst = param; hw_arg.dst = param;
hw_arg.dst_addr = addr_token; hw_arg.dst_addr = addr_token;
if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED)
hw_arg.predicate = *pToken++;
for (i = 1; i < curOpcode->num_params; i++) { for (i = 1; i < curOpcode->num_params; i++) {
/* DEF* instructions have constant src parameters, not registers */ /* DEF* instructions have constant src parameters, not registers */
if (curOpcode->opcode == D3DSIO_DEF || if (curOpcode->opcode == D3DSIO_DEF ||
......
...@@ -1458,9 +1458,18 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C ...@@ -1458,9 +1458,18 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C
DWORD param, addr_token; DWORD param, addr_token;
int tokens_read; 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); TRACE("%s", curOpcode->name);
if (curOpcode->num_params > 0) { if (curOpcode->num_params > 0) {
/* Destination token */
tokens_read = shader_get_param((IWineD3DBaseShader*) This, tokens_read = shader_get_param((IWineD3DBaseShader*) This,
pToken, &param, &addr_token); pToken, &param, &addr_token);
pToken += tokens_read; pToken += tokens_read;
...@@ -1470,6 +1479,13 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C ...@@ -1470,6 +1479,13 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C
TRACE(" "); TRACE(" ");
shader_dump_param((IWineD3DBaseShader*) This, param, addr_token, 0); 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) { for (i = 1; i < curOpcode->num_params; ++i) {
tokens_read = shader_get_param((IWineD3DBaseShader*) This, tokens_read = shader_get_param((IWineD3DBaseShader*) This,
......
...@@ -1576,9 +1576,18 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, ...@@ -1576,9 +1576,18 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface,
DWORD param, addr_token; DWORD param, addr_token;
int tokens_read; 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); TRACE("%s", curOpcode->name);
if (curOpcode->num_params > 0) { if (curOpcode->num_params > 0) {
/* Destination token */
tokens_read = shader_get_param((IWineD3DBaseShader*) This, tokens_read = shader_get_param((IWineD3DBaseShader*) This,
pToken, &param, &addr_token); pToken, &param, &addr_token);
pToken += tokens_read; pToken += tokens_read;
...@@ -1588,6 +1597,13 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, ...@@ -1588,6 +1597,13 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface,
TRACE(" "); TRACE(" ");
shader_dump_param((IWineD3DBaseShader*) This, param, addr_token, 0); 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) { for (i = 1; i < curOpcode->num_params; ++i) {
tokens_read = shader_get_param((IWineD3DBaseShader*) This, tokens_read = shader_get_param((IWineD3DBaseShader*) This,
......
...@@ -1296,6 +1296,7 @@ typedef struct SHADER_OPCODE_ARG { ...@@ -1296,6 +1296,7 @@ typedef struct SHADER_OPCODE_ARG {
CONST SHADER_OPCODE* opcode; CONST SHADER_OPCODE* opcode;
DWORD dst; DWORD dst;
DWORD dst_addr; DWORD dst_addr;
DWORD predicate;
DWORD src[4]; DWORD src[4];
DWORD src_addr[4]; DWORD src_addr[4];
SHADER_BUFFER* buffer; SHADER_BUFFER* buffer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment