[WINED3D 6] Move register count pass to SetFunction

Ivan Gyurdiev ivg231 at gmail.com
Tue Jul 4 03:01:46 CDT 2006


- move register count pass to SetFunction.
  That way it can be used to figure out input semantics for software 
shaders as well.

- move semantics pointers out of the reg_maps, make them persistent data 
in the shader (again, for future software shaders)
  The vertex shader input semantics are already persistent - rename 
arrayUsageMap to semantics_in. Note that I plan to re-work the way this 
map works in a future patch, but I don't plan on changing its location.

-------------- next part --------------
---
 dlls/wined3d/arb_program_shader.c |   12 +++++++-----
 dlls/wined3d/baseshader.c         |    6 ++++--
 dlls/wined3d/drawprim.c           |    2 +-
 dlls/wined3d/glsl_shader.c        |   12 ++++++------
 dlls/wined3d/pixelshader.c        |   32 +++++++++++++++-----------------
 dlls/wined3d/vertexshader.c       |   33 +++++++++++++++------------------
 dlls/wined3d/wined3d_private.h    |   17 +++++++++--------
 7 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 753789f..47791bc 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -317,6 +317,8 @@ static void pshader_get_register_name(co
 /* TODO: merge with pixel shader */
 static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, BOOL is_input, char *hwLine) {
 
+  IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) arg->shader;
+
   /* oPos, oFog and oPts in D3D */
   static const char* hwrastout_reg_names[] = { "result.position", "result.fogcoord", "result.pointsize" };
 
@@ -338,16 +340,16 @@ static void vshader_program_add_param(SH
     break;
   case D3DSPR_INPUT:
 
-    if (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
-        reg == (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
+    if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
+        reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
         is_color = TRUE;
 
-    if (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
-        reg == (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
+    if (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
+        reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
         is_color = TRUE;
 
     /* FIXME: Shaders in 8.1 appear to not require a dcl statement - use
-     * the reg value from the vertex declaration. However, usage map is not initialized
+     * the reg value from the vertex declaration. However, semantics are not initialized
      * in that case - how can we know if an input contains color data or not? */
 
     sprintf(tmpReg, "vertex.attrib[%lu]", reg);
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index a0ea438..8ed85ef 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -295,6 +295,8 @@ static void shader_parse_decl_usage(
 void shader_get_registers_used(
     IWineD3DBaseShader *iface,
     shader_reg_maps* reg_maps,
+    DWORD* semantics_in,
+    DWORD* semantics_out,
     CONST DWORD* pToken) {
 
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
@@ -348,12 +350,12 @@ void shader_get_registers_used(
                 else
                     reg_maps->packed_input[regnum] = 1;
 
-                shader_parse_decl_usage(reg_maps->semantics_in, usage, param);
+                shader_parse_decl_usage(semantics_in, usage, param);
 
             /* Vshader: mark 3.0 output registers used, save token */
             } else if (D3DSPR_OUTPUT == regtype) {
                 reg_maps->packed_output[regnum] = 1;
-                shader_parse_decl_usage(reg_maps->semantics_out, usage, param);
+                shader_parse_decl_usage(semantics_out, usage, param);
 
             /* Save sampler usage token */
             } else if (D3DSPR_SAMPLER == regtype)
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index ff1c23c..a31946e 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1951,7 +1951,7 @@ #endif
 
             /* load the array data using ordinal mapping */
             loadNumberedArrays(iface, dataLocations, 
-                ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->arrayUsageMap);
+                ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->semantics_in);
 
             useDrawStridedSlow = FALSE;
         } else { /* If this happens we must drawStridedSlow later on */ 
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 94871c0..d15874c 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -501,18 +501,18 @@ static void shader_glsl_get_register_nam
                     strcpy(tmpStr, "gl_SecondaryColor");
             }
         } else {
-            IWineD3DVertexShaderImpl *vshader = (IWineD3DVertexShaderImpl*) arg->shader;
+            IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl*) arg->shader;
 
-            if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
-                reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
+            if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
+                reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
                 *is_color = TRUE;
 
-            if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] &&
-                reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
+            if (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
+                reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
                 *is_color = TRUE;
 
             /* FIXME: Shaders in 8.1 appear to not require a dcl statement - use
-             * the reg value from the vertex declaration. However, arrayUsageMap is not initialized
+             * the reg value from the vertex declaration. However, semantics are not initialized
               * in that case - how can we know if an input contains color data or not? */
 
             sprintf(tmpStr, "attrib%lu", reg);
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 933cfc3..bc15dc9 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -798,22 +798,12 @@ static void pshader_set_limits(
     or GLSL and send it to the card */
 inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
     IWineD3DPixelShader *iface,
+    shader_reg_maps* reg_maps,
     CONST DWORD *pFunction) {
 
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     SHADER_BUFFER buffer;
 
-    /* First pass: figure out which registers are used, what the semantics are, etc.. */
-    shader_reg_maps reg_maps;
-    DWORD semantics_in[WINED3DSHADERDECLUSAGE_MAX_USAGE];
-
-    memset(&reg_maps, 0, sizeof(shader_reg_maps));
-    memset(semantics_in, 0, WINED3DSHADERDECLUSAGE_MAX_USAGE * sizeof(DWORD));
-    reg_maps.semantics_in = semantics_in;
-    reg_maps.semantics_out = NULL;
-    shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps, pFunction);
-    /* FIXME: validate against OpenGL */
-
 #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) {
@@ -835,14 +825,14 @@ #endif
         GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
 
         /* Base Declarations */
-        shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
+        shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
 
         /* Pack 3.0 inputs */
         if (This->baseShader.hex_version >= D3DPS_VERSION(3,0))
-            pshader_glsl_input_pack(&buffer, semantics_in);
+            pshader_glsl_input_pack(&buffer, This->semantics_in);
 
         /* Base Shader Body */
-        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
+        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
 
         /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
         if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
@@ -871,10 +861,10 @@ #endif
         shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
 
         /* Base Declarations */
-        shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
+        shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
 
         /* Base Shader Body */
-        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
+        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
 
         if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
             shader_addline(&buffer, "MOV result.color, R0;\n");
@@ -908,15 +898,23 @@ #endif
 static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
 
     IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
+    shader_reg_maps reg_maps;
 
+    /* First pass: trace shader */
     shader_trace_init((IWineD3DBaseShader*) This, pFunction);
     pshader_set_limits(This);
 
+    /* Second pass: figure out which registers are used, what the semantics are, etc.. */
+    memset(&reg_maps, 0, sizeof(shader_reg_maps)); 
+    shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
+        This->semantics_in, NULL, pFunction);
+    /* FIXME: validate reg_maps against OpenGL */
+
     /* Generate HW shader in needed */
     This->baseShader.shader_mode = wined3d_settings.ps_selected_mode;
     if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) {
         TRACE("(%p) : Generating hardware program\n", This);
-        IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction);
+        IWineD3DPixelShaderImpl_GenerateShader(iface, &reg_maps, pFunction);
     }
 
     TRACE("(%p) : Copying the function\n", This);
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index aa68081..df0fd99 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -611,24 +611,14 @@ static void vshader_set_limits(
 
 /** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
     or GLSL and send it to the card */
-inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
+static VOID IWineD3DVertexShaderImpl_GenerateShader(
     IWineD3DVertexShader *iface,
+    shader_reg_maps* reg_maps,
     CONST DWORD *pFunction) {
 
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     SHADER_BUFFER buffer;
 
-    /* First pass: figure out which registers are used, what the semantics are, etc.. */
-    shader_reg_maps reg_maps;
-    DWORD semantics_out[WINED3DSHADERDECLUSAGE_MAX_USAGE];
-
-    memset(&reg_maps, 0, sizeof(shader_reg_maps));
-    memset(semantics_out, 0, WINED3DSHADERDECLUSAGE_MAX_USAGE * sizeof(DWORD));
-    reg_maps.semantics_in = This->arrayUsageMap;
-    reg_maps.semantics_out = semantics_out;
-    shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps, pFunction);
-    /* FIXME: validate against OpenGL */
-
 #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) {
@@ -650,14 +640,14 @@ #endif
         GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
 
         /* Base Declarations */
-        shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
+        shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
 
         /* Base Shader Body */
-        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
+        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
 
         /* Unpack 3.0 outputs */
         if (This->baseShader.hex_version >= D3DVS_VERSION(3,0))
-            vshader_glsl_output_unpack(&buffer, semantics_out);
+            vshader_glsl_output_unpack(&buffer, This->semantics_out);
 
         shader_addline(&buffer, "}\n\0");
 
@@ -680,10 +670,10 @@ #endif
                 min(95, This->baseShader.limits.constant_float);
 
         /* Base Declarations */
-        shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
+        shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
 
         /* Base Shader Body */
-        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
+        shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
 
         shader_addline(&buffer, "END\n\0"); 
 
@@ -1050,14 +1040,21 @@ static HRESULT WINAPI IWineD3DVertexShad
 static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
 
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
+    shader_reg_maps reg_maps;
 
+    /* First pass: trace shader */
     shader_trace_init((IWineD3DBaseShader*) This, pFunction);
     vshader_set_limits(This);
 
+    /* Second pass: figure out registers used, semantics, etc.. */
+    memset(&reg_maps, 0, sizeof(shader_reg_maps));
+    shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
+       This->semantics_in, This->semantics_out, pFunction);
+
     /* Generate HW shader in needed */
     This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
     if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) 
-        IWineD3DVertexShaderImpl_GenerateShader(iface, pFunction);
+        IWineD3DVertexShaderImpl_GenerateShader(iface, &reg_maps, pFunction);
 
     /* copy the function ... because it will certainly be released by application */
     if (NULL != pFunction) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0f354c1..a71539a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1297,11 +1297,6 @@ typedef struct shader_reg_maps {
     char constantsI[MAX_CONST_I];           /* pixel & vertex >= 2.0 */
     char constantsB[MAX_CONST_B];           /* pixel & vertex >= 2.0 */
     
-    /* Semantics maps (semantic -> reg_token)
-     * Use 0 as default (bit 31 is always 1 on a valid token) */
-    DWORD* semantics_in;                    /* vertex, pixel */
-    DWORD* semantics_out;                   /* vertex */
-
     /* Sampler usage tokens 
      * Use 0 as default (bit 31 is always 1 on a valid token) */
     DWORD samplers[MAX_SAMPLERS];
@@ -1480,6 +1475,8 @@ typedef struct IWineD3DBaseShaderImpl {
 extern void shader_get_registers_used(
     IWineD3DBaseShader *iface,
     shader_reg_maps* reg_maps,
+    DWORD* semantics_in,
+    DWORD* semantics_out,
     CONST DWORD* pToken);
 
 extern void shader_generate_glsl_declarations(
@@ -1561,9 +1558,10 @@ typedef struct IWineD3DVertexShaderImpl 
 
     DWORD usage;
 
-    /* vertex declaration array mapping */
-    DWORD arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE];
- 
+    /* Vertex shader input and output semantics */
+    DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
+    DWORD semantics_out [WINED3DSHADERDECLUSAGE_MAX_USAGE];
+
     /* run time datas...  */
     VSHADERDATA                *data;
     IWineD3DVertexDeclaration  *vertexDeclaration;
@@ -1591,6 +1589,9 @@ typedef struct IWineD3DPixelShaderImpl {
     IUnknown                   *parent;
     IWineD3DDeviceImpl         *wineD3DDevice;
 
+    /* Pixel shader input semantics */
+    DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
+
     /* run time data */
     PSHADERDATA                *data;
 
-- 
1.4.0



More information about the wine-patches mailing list