wined3d: Further split up GenerateProgramArbHW for pixelshaders

Jason Green jave27 at gmail.com
Wed May 3 22:35:55 CDT 2006


This patch moves all of the D3DSIO_TEXM#x#___ opcode cases out of the
GenerateProgramArbHW() function in pixelshader.c and into separate
functions which are now referenced by the lookup table.  To do this,
we have to add a SHADER_PARSE_STATE setting to our baseShader to keep
track of which row of the matrix we are working with when parsing
these calls (these opcodes have to be strung together to do anything).
 I've checked against a couple of sample apps which use these opcodes
and the TRACE output is identical, with the exception of removing an
extraneous TRACE() call inside of GenerateProgramArbHW.

This also gets rid of an unused char* variable in vertexshader.c which
was missed during my last patchset.

This applies against Mike's git tree.
-------------- next part --------------
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 0e75020..798708d 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -617,6 +617,12 @@ void pshader_hw_texreg2ar(SHADER_OPCODE_
 void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg);
 void pshader_hw_texbem(SHADER_OPCODE_ARG* arg);
 void pshader_hw_def(SHADER_OPCODE_ARG* arg);
+void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg);
+void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg);
+void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg);
+void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg);
+void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg);
+void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg);
 
 /**
  * log, exp, frc, m*x* seems to be macros ins ... to see
@@ -709,13 +715,13 @@ CONST SHADER_OPCODE IWineD3DPixelShaderI
     {D3DSIO_TEXREG2AR,"texreg2ar","undefined",   2, pshader_texreg2ar,   pshader_hw_texreg2ar, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXREG2GB,"texreg2gb","undefined",   2, pshader_texreg2gb,   pshader_hw_texreg2gb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXREG2RGB,   "texreg2rgb",   GLNAME_REQUIRE_GLSL,   2, pshader_texreg2rgb,  NULL, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXM3x2PAD,   "texm3x2pad",   "undefined",   2, pshader_texm3x2pad,   NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXM3x2TEX,   "texm3x2tex",   "undefined",   2, pshader_texm3x2tex,   NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXM3x3PAD,   "texm3x3pad",   "undefined",   2, pshader_texm3x3pad,   NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x2PAD,   "texm3x2pad",   "undefined",   2, pshader_texm3x2pad,   pshader_hw_texm3x2pad, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x2TEX,   "texm3x2tex",   "undefined",   2, pshader_texm3x2tex,   pshader_hw_texm3x2tex, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x3PAD,   "texm3x3pad",   "undefined",   2, pshader_texm3x3pad,   pshader_hw_texm3x3pad, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x3DIFF,  "texm3x3diff",  GLNAME_REQUIRE_GLSL,   2, pshader_texm3x3diff,  NULL, D3DPS_VERSION(0,0), D3DPS_VERSION(0,0)},
-    {D3DSIO_TEXM3x3SPEC,  "texm3x3spec",  "undefined",   3, pshader_texm3x3spec,  NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXM3x3VSPEC, "texm3x3vspe",  "undefined",   2, pshader_texm3x3vspec, NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXM3x3TEX,   "texm3x3tex",   "undefined",   2, pshader_texm3x3tex,   NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x3SPEC,  "texm3x3spec",  "undefined",   3, pshader_texm3x3spec,  pshader_hw_texm3x3spec, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x3VSPEC, "texm3x3vspe",  "undefined",   2, pshader_texm3x3vspec, pshader_hw_texm3x3vspec, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x3TEX,   "texm3x3tex",   "undefined",   2, pshader_texm3x3tex,   pshader_hw_texm3x3tex, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXDP3TEX,    "texdp3tex",    GLNAME_REQUIRE_GLSL,   2, pshader_texdp3tex,   NULL, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL,   2, pshader_texm3x2depth, NULL, D3DPS_VERSION(1,3), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXDP3,   "texdp3",   GLNAME_REQUIRE_GLSL,  2, pshader_texdp3,   NULL, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
@@ -1180,6 +1186,119 @@ void pshader_hw_def(SHADER_OPCODE_ARG* a
 
     shader->constants[reg] = 1;
 }
+
+void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) {
+
+    IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    SHADER_BUFFER* buffer = arg->buffer;
+    char tmpLine[256];
+    char buf[50];
+
+    if (gen_input_modifier_line(arg->src[0], 0, buf, tmpLine, shader->constants)) 
+        shader_addline(buffer, tmpLine);
+    shader_addline(buffer, "DP3 TMP.x, T%lu, %s;\n", reg, buf);
+}
+
+void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) {
+
+    IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    SHADER_BUFFER* buffer = arg->buffer;
+    char tmpLine[256];
+    char buf[50];
+
+    if (gen_input_modifier_line(arg->src[0], 0, buf, tmpLine, shader->constants)) 
+        shader_addline(buffer, tmpLine);
+    shader_addline(buffer, "DP3 TMP.y, T%lu, %s;\n", reg, buf);
+    shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg, reg);
+}
+
+void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) {
+
+    IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    SHADER_BUFFER* buffer = arg->buffer;
+    SHADER_PARSE_STATE current_state = shader->baseShader.parse_state;
+    char tmpLine[256];
+    char buf[50];
+
+    if (gen_input_modifier_line(arg->src[0], 0, buf, tmpLine, shader->constants)) 
+        shader_addline(buffer, tmpLine);
+    shader_addline(buffer, "DP3 TMP.%c, T%lu, %s;\n", 'x' + current_state.current_row, reg, buf);
+    current_state.texcoord_w[current_state.current_row++] = reg;
+}
+
+void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) {
+
+    IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    SHADER_BUFFER* buffer = arg->buffer;
+    SHADER_PARSE_STATE current_state = shader->baseShader.parse_state;
+    char tmpLine[256];
+    char buf[50];
+
+    if (gen_input_modifier_line(arg->src[0], 0, buf, tmpLine, shader->constants)) 
+        shader_addline(buffer, tmpLine);
+    shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
+
+    /* Cubemap textures will be more used than 3D ones. */
+    shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
+    current_state.current_row = 0;
+}
+
+void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
+
+    IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    SHADER_BUFFER* buffer = arg->buffer;
+    SHADER_PARSE_STATE current_state = shader->baseShader.parse_state;
+    char tmpLine[256];
+    char buf[50];
+
+    if (gen_input_modifier_line(arg->src[0], 0, buf, tmpLine, shader->constants)) 
+        shader_addline(buffer, tmpLine);
+    shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
+
+    /* Construct the eye-ray vector from w coordinates */
+    shader_addline(buffer, "MOV TMP2.x, fragment.texcoord[%lu].w;\n", current_state.texcoord_w[0]);
+    shader_addline(buffer, "MOV TMP2.y, fragment.texcoord[%lu].w;\n", current_state.texcoord_w[1]);
+    shader_addline(buffer, "MOV TMP2.z, fragment.texcoord[%lu].w;\n", reg);
+
+    /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
+    shader_addline(buffer, "DP3 TMP.w, TMP, TMP2;\n");
+    shader_addline(buffer, "MUL TMP, TMP.w, TMP;\n");
+    shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -TMP2;\n");
+
+    /* Cubemap textures will be more used than 3D ones. */
+    shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
+    current_state.current_row = 0;
+}
+
+void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) {
+
+    IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    DWORD reg3 = arg->src[1] & D3DSP_REGNUM_MASK;
+    SHADER_PARSE_STATE current_state = shader->baseShader.parse_state;
+    SHADER_BUFFER* buffer = arg->buffer;
+    char tmpLine[256];
+    char buf[50];
+
+    if (gen_input_modifier_line(arg->src[0], 0, buf, tmpLine, shader->constants)) 
+        shader_addline(buffer, tmpLine);
+    shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
+
+    /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
+    shader_addline(buffer, "DP3 TMP.w, TMP, C[%lu];\n", reg3);
+    shader_addline(buffer, "MUL TMP, TMP.w, TMP;\n");
+    shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -C[%lu];\n", reg3);
+
+    /* Cubemap textures will be more used than 3D ones. */
+    shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
+    current_state.current_row = 0;
+}
+
                     
 /* NOTE: A description of how to parse tokens can be found at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/graphics/hh/graphics/usermodedisplaydriver_shader_cc8e4e05-f5c3-4ec0-8853-8ce07c1551b2.xml.asp */
 inline static VOID IWineD3DPixelShaderImpl_GenerateProgramArbHW(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
@@ -1187,15 +1306,14 @@ inline static VOID IWineD3DPixelShaderIm
     const DWORD *pToken = pFunction;
     const SHADER_OPCODE *curOpcode = NULL;
     DWORD i;
-    char  tmpLine[255];
     SHADER_BUFFER buffer;
 
-    int row = 0; /* not sure, something to do with macros? */
-    DWORD tcw[2];
-
     /* Keep bitmaps of used temporary and texture registers */
     DWORD tempsUsed, texUsed;
 
+    /* Initialize current parsing state */
+    This->baseShader.parse_state.current_row = 0;
+
 #if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
         it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
     if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
@@ -1320,98 +1438,7 @@ inline static VOID IWineD3DPixelShaderIm
                 /* Build opcode for GL vertex_program */
                 switch (curOpcode->opcode) {
                 case D3DSIO_NOP:
-                case D3DSIO_PHASE:
                     break;
-                case D3DSIO_TEXM3x2PAD:
-                {
-                    DWORD reg = *pToken & D3DSP_REGNUM_MASK;
-                    char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
-                        shader_addline(&buffer, tmpLine);
-                    shader_addline(&buffer, "DP3 TMP.x, T%lu, %s;\n", reg, buf);
-                    ++pToken;
-                }
-                break;
-                case D3DSIO_TEXM3x2TEX:
-                {
-                    DWORD reg = *pToken & D3DSP_REGNUM_MASK;
-                    char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
-                        shader_addline(&buffer, tmpLine);
-                    shader_addline(&buffer, "DP3 TMP.y, T%lu, %s;\n", reg, buf);
-                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg, reg);
-                    ++pToken;
-                }
-                break;
-                case D3DSIO_TEXM3x3PAD:
-                {
-                    DWORD reg = *pToken & D3DSP_REGNUM_MASK;
-                    char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
-                        shader_addline(&buffer, tmpLine);
-                    shader_addline(&buffer, "DP3 TMP.%c, T%lu, %s;\n", 'x'+row, reg, buf);
-                    tcw[row++] = reg;
-                    ++pToken;
-                }
-                break;
-                case D3DSIO_TEXM3x3TEX:
-                {
-                    DWORD reg = *pToken & D3DSP_REGNUM_MASK;
-                    char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
-                        shader_addline(&buffer, tmpLine);
-                    shader_addline(&buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
-
-                    /* Cubemap textures will be more used than 3D ones. */
-                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
-                    row = 0;
-                    ++pToken;
-                }
-                break;
-                case D3DSIO_TEXM3x3VSPEC:
-                {
-                    DWORD reg = *pToken & D3DSP_REGNUM_MASK;
-                    char buf[50];
-                    if (gen_input_modifier_line(*++pToken, 0, buf, tmpLine, This->constants)) 
-                        shader_addline(&buffer, tmpLine);
-                    shader_addline(&buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
-
-                    /* Construct the eye-ray vector from w coordinates */
-                    shader_addline(&buffer, "MOV TMP2.x, fragment.texcoord[%lu].w;\n", tcw[0]);
-                    shader_addline(&buffer, "MOV TMP2.y, fragment.texcoord[%lu].w;\n", tcw[1]);
-                    shader_addline(&buffer, "MOV TMP2.z, fragment.texcoord[%lu].w;\n", reg);
-
-                    /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
-                    shader_addline(&buffer, "DP3 TMP.w, TMP, TMP2;\n");
-                    shader_addline(&buffer, "MUL TMP, TMP.w, TMP;\n");
-                    shader_addline(&buffer, "MAD TMP, coefmul.x, TMP, -TMP2;\n");
-
-                    /* Cubemap textures will be more used than 3D ones. */
-                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
-                    row = 0;
-                    ++pToken;
-                }
-                break;
-                case D3DSIO_TEXM3x3SPEC:
-                {
-                    DWORD reg = *pToken & D3DSP_REGNUM_MASK;
-                    DWORD reg3 = *(pToken + 2) & D3DSP_REGNUM_MASK;
-                    char buf[50];
-                    if (gen_input_modifier_line(*(pToken + 1), 0, buf, tmpLine, This->constants)) 
-                        shader_addline(&buffer, tmpLine);
-                    shader_addline(&buffer, "DP3 TMP.z, T%lu, %s;\n", reg, buf);
-
-                    /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
-                    shader_addline(&buffer, "DP3 TMP.w, TMP, C[%lu];\n", reg3);
-                    shader_addline(&buffer, "MUL TMP, TMP.w, TMP;\n");
-                    shader_addline(&buffer, "MAD TMP, coefmul.x, TMP, -C[%lu];\n", reg3);
-
-                    /* Cubemap textures will be more used than 3D ones. */
-                    shader_addline(&buffer, "TEX T%lu, TMP, texture[%lu], CUBE;\n", reg, reg);
-                    row = 0;
-                    pToken += 3;
-                }
-                break;
 
                 default:
                     FIXME("Can't handle opcode %s in hwShader\n", curOpcode->name);
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 81c015d..0d60adf 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -1136,7 +1136,6 @@ inline static VOID IWineD3DVertexShaderI
     const SHADER_OPCODE* curOpcode = NULL;
     DWORD i;
     SHADER_BUFFER buffer;
-    char  tmpLine[255];
     DWORD addressUsed, tempsUsed;
 
 #if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
@@ -1191,7 +1190,6 @@ inline static VOID IWineD3DVertexShaderI
 
   if (NULL != pToken) {
     while (1) {
-      tmpLine[0] = 0;
 
       if (D3DVS_END() == *pToken)
             break;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4422eb0..0ed390a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1217,6 +1217,13 @@ typedef struct SHADER_LIMITS {
     unsigned int address;
 } SHADER_LIMITS;
 
+/** Keeps track of details for TEX_M#x# shader opcodes which need to 
+    maintain state information between multiple codes */
+typedef struct SHADER_PARSE_STATE {
+    unsigned int current_row;
+    DWORD texcoord_w[2];
+} SHADER_PARSE_STATE;
+
 /* Base Shader utility functions. 
  * (may move callers into the same file in the future) */
 extern int shader_addline(
@@ -1250,6 +1257,7 @@ typedef struct IWineD3DBaseShaderClass
     DWORD                           version;
     DWORD                           hex_version;
     SHADER_LIMITS                   limits;
+    SHADER_PARSE_STATE              parse_state;
     CONST SHADER_OPCODE             *shader_ins;
     CONST DWORD                     *function;
     UINT                            functionLength;







More information about the wine-patches mailing list