[WINED3D 4/13] Resend: Further split up GenerateProgramArbHW for pixelshaders

Jason Green jave27 at gmail.com
Tue May 9 21:30:11 CDT 2006


-------------- next part --------------
Subject: [PATCH 04/13] wined3d: Further split up GenerateProgramArbHW for pixelshaders

---

 dlls/wined3d/pixelshader.c     |  229 ++++++++++++++++++++++------------------
 dlls/wined3d/vertexshader.c    |    2 
 dlls/wined3d/wined3d_private.h |    8 +
 3 files changed, 136 insertions(+), 103 deletions(-)

f034918af7f40b59ed473c81b949a37d4793e46e
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 6f51ec7..a93178a 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 7b11d28..8a67a1a 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 d02974a..31a8b83 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1236,6 +1236,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(
@@ -1254,6 +1261,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;
-- 
1.1.3


More information about the wine-patches mailing list