From 42b89791ff4328ec8a92916ff8b0435748b16ee1 Mon Sep 17 00:00:00 2001 From: Ivan Gyurdiev Date: Wed, 17 May 2006 21:09:56 -0400 Subject: [PATCH] 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. --- dlls/wined3d/baseshader.c | 28 ++++++++++++++++++++++------ dlls/wined3d/pixelshader.c | 18 +++++++++++++++++- dlls/wined3d/vertexshader.c | 16 ++++++++++++++++ dlls/wined3d/wined3d_private.h | 1 + 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index a9e847a540a..f9f939f7029 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -176,6 +176,7 @@ void shader_get_registers_used( while (D3DVS_END() != *pToken) { CONST SHADER_OPCODE* curOpcode; + DWORD opcode_token; /* Skip version */ if (shader_is_version_token(*pToken)) { @@ -191,8 +192,8 @@ void shader_get_registers_used( } /* Fetch opcode */ - curOpcode = shader_get_opcode(iface, *pToken); - ++pToken; + opcode_token = *pToken++; + curOpcode = shader_get_opcode(iface, opcode_token); /* Unhandled opcode, and its parameters */ if (NULL == curOpcode) { @@ -212,9 +213,19 @@ void shader_get_registers_used( /* Set texture registers, and temporary registers */ } 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; pToken += shader_get_param(iface, pToken, ¶m, &addr_token); @@ -359,6 +370,8 @@ void shader_dump_param( TRACE("-"); else if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_COMP) TRACE("1-"); + else if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NOT) + TRACE("!"); } switch (regtype) { @@ -445,10 +458,10 @@ void shader_dump_param( if (0 != (param & D3DSP_SRCMOD_MASK)) { DWORD mask = param & D3DSP_SRCMOD_MASK; - /*TRACE("_modifier(0x%08lx) ", mask);*/ switch (mask) { case D3DSPSM_NONE: break; case D3DSPSM_NEG: break; + case D3DSPSM_NOT: break; case D3DSPSM_BIAS: TRACE("_bias"); break; case D3DSPSM_BIASNEG: TRACE("_bias"); break; case D3DSPSM_SIGN: TRACE("_bx2"); break; @@ -459,7 +472,7 @@ void shader_dump_param( case D3DSPSM_DZ: TRACE("_dz"); break; case D3DSPSM_DW: TRACE("_dw"); break; default: - TRACE("_unknown(0x%08lx)", mask); + TRACE("_unknown_modifier(%#lx)", mask >> D3DSP_SRCMOD_SHIFT); } } @@ -619,6 +632,9 @@ void generate_base_shader( hw_arg.dst = param; hw_arg.dst_addr = addr_token; + if (opcode_token & D3DSHADER_INSTRUCTION_PREDICATED) + hw_arg.predicate = *pToken++; + for (i = 1; i < curOpcode->num_params; i++) { /* DEF* instructions have constant src parameters, not registers */ if (curOpcode->opcode == D3DSIO_DEF || diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 918de803ab1..bafcd289cd8 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -1458,9 +1458,18 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C 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; @@ -1469,7 +1478,14 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C 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, diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 6dfbd118a39..58a1963d818 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -1576,9 +1576,18 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, 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; @@ -1588,6 +1597,13 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, 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, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7a619219f3f..6b905446bf1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1296,6 +1296,7 @@ typedef struct SHADER_OPCODE_ARG { CONST SHADER_OPCODE* opcode; DWORD dst; DWORD dst_addr; + DWORD predicate; DWORD src[4]; DWORD src_addr[4]; SHADER_BUFFER* buffer; -- 2.11.4.GIT