[WINED3D 4/9] Register map cleanups

Ivan Gyurdiev ivg231 at gmail.com
Mon Jun 12 01:55:30 CDT 2006


Various cleanups:
- do not use DWORD as a bitmask, that places artificial limit of 32 on 
registers
- track attributes that are used and declare only those
- move declarations function call in pshader/vshader to allow us to 
insert pixel or vertex specific code between the declarations and the 
rest of the code
- remove redundant 0 intializers
- remove useless continue statement

-------------- next part --------------
---

 dlls/wined3d/baseshader.c      |   64 +++++++++++++++++++---------------------
 dlls/wined3d/pixelshader.c     |    6 ++++
 dlls/wined3d/vertexshader.c    |    6 ++++
 dlls/wined3d/wined3d_private.h |   32 ++++++++++++++++----
 4 files changed, 67 insertions(+), 41 deletions(-)

7a198e7c28fddc0b35a621ba43d1b72f7587b2d8
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 774c313..6f53ce2 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -299,13 +299,12 @@ void shader_get_registers_used(
 
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
 
+    /* There are some minor differences between pixel and vertex shaders */
+    char pshader = shader_is_pshader_version(This->baseShader.hex_version);
+
     if (pToken == NULL)
         return;
 
-    reg_maps->temporary = 0;
-    reg_maps->texcoord = 0;
-    reg_maps->address = 0;
-
     while (D3DVS_END() != *pToken) {
         CONST SHADER_OPCODE* curOpcode;
         DWORD opcode_token;
@@ -331,7 +330,6 @@ void shader_get_registers_used(
         if (NULL == curOpcode) {
            while (*pToken & 0x80000000)
                ++pToken;
-           continue;
 
         /* Handle declarations */
         } else if (D3DSIO_DCL == curOpcode->opcode) {
@@ -339,8 +337,13 @@ void shader_get_registers_used(
             DWORD usage = *pToken++;
             DWORD param = *pToken++;
             DWORD regtype = shader_get_regtype(param);
+            unsigned int regnum = param & D3DSP_REGNUM_MASK;
 
             if (D3DSPR_INPUT == regtype) {
+
+                if (!pshader)
+                    reg_maps->attributes[regnum] = 1;
+
                 shader_parse_decl_usage(reg_maps->semantics_in, usage, param);
 
             } else if (D3DSPR_OUTPUT == regtype) {
@@ -352,7 +355,6 @@ void shader_get_registers_used(
         /* Skip definitions (for now) */
         } else if (D3DSIO_DEF == curOpcode->opcode) {
             pToken += curOpcode->num_params;
-            continue;
 
         /* Set texture registers, and temporary registers */
         } else {
@@ -378,14 +380,17 @@ void shader_get_registers_used(
 
                 if (D3DSPR_TEXTURE == regtype) { /* vs: D3DSPR_ADDR */
 
-                    if (shader_is_pshader_version(This->baseShader.hex_version))
-                        reg_maps->texcoord |= (1 << reg);
+                    if (pshader)
+                        reg_maps->texcoord[reg] = 1;
                     else
-                        reg_maps->address |= (1 << reg);
+                        reg_maps->address[reg] = 1;
                 }
 
-                if (D3DSPR_TEMP == regtype)
-                    reg_maps->temporary |= (1 << reg);
+                else if (D3DSPR_TEMP == regtype)
+                    reg_maps->temporary[reg] = 1;
+
+                else if (D3DSPR_INPUT == regtype && !pshader)
+                    reg_maps->attributes[reg] = 1;
              }
         }
     }
@@ -651,9 +656,8 @@ void shader_dump_param(
     }
 }
 
-/** Generate the variable & register declarations for the ARB_vertex_program
-    output target */
-void generate_arb_declarations(
+/* Generate the variable & register declarations for the ARB_vertex_program output target */
+void shader_generate_arb_declarations(
     IWineD3DBaseShader *iface,
     shader_reg_maps* reg_maps,
     SHADER_BUFFER* buffer) {
@@ -662,23 +666,23 @@ void generate_arb_declarations(
     DWORD i;
 
     for(i = 0; i < This->baseShader.limits.temporary; i++) {
-        if (reg_maps->temporary & (1 << i))
+        if (reg_maps->temporary[i])
             shader_addline(buffer, "TEMP R%lu;\n", i);
     }
 
     for (i = 0; i < This->baseShader.limits.address; i++) {
-        if (reg_maps->address & (1 << i))
+        if (reg_maps->address[i])
             shader_addline(buffer, "ADDRESS A%ld;\n", i);
     }
 
     for(i = 0; i < This->baseShader.limits.texture; i++) {
-        if (reg_maps->texcoord & (1 << i))
+        if (reg_maps->texcoord[i])
             shader_addline(buffer,"TEMP T%lu;\n", i);
     }
 
     /* Texture coordinate registers must be pre-loaded */
     for (i = 0; i < This->baseShader.limits.texture; i++) {
-        if (reg_maps->texcoord & (1 << i))
+        if (reg_maps->texcoord[i])
             shader_addline(buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
     }
 
@@ -688,9 +692,8 @@ void generate_arb_declarations(
                    This->baseShader.limits.constant_float - 1);
 }
 
-/** Generate the variable & register declarations for the GLSL
-    output target */
-void generate_glsl_declarations(
+/** Generate the variable & register declarations for the GLSL output target */
+void shader_generate_glsl_declarations(
     IWineD3DBaseShader *iface,
     shader_reg_maps* reg_maps,
     SHADER_BUFFER* buffer) {
@@ -711,25 +714,25 @@ void generate_glsl_declarations(
     
     /* Declare address variables */
     for (i = 0; i < This->baseShader.limits.address; i++) {
-        if (reg_maps->address & (1 << i))
+        if (reg_maps->address[i])
             shader_addline(buffer, "ivec4 A%ld;\n", i);
     }
 
-    /* Declare texture temporaries */
+    /* Declare texture coordinate temporaries and initialize them */
     for (i = 0; i < This->baseShader.limits.texture; i++) {
         shader_addline(buffer, "vec4 T%lu = gl_TexCoord[%lu];\n", i, i);
     }
 
     /* Declare temporary variables */
     for(i = 0; i < This->baseShader.limits.temporary; i++) {
-        if (reg_maps->temporary & (1 << i))
+        if (reg_maps->temporary[i])
             shader_addline(buffer, "vec4 R%lu;\n", i);
     }
 
-    /* Declare all named attributes (TODO: Add this to the reg_maps
-     * and only declare those that are needed) */
+    /* Declare attributes */
     for (i = 0; i < This->baseShader.limits.attributes; i++) {
-        shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
+        if (reg_maps->attributes[i])
+            shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
     }
 
     /* Temporary variables for matrix operations */
@@ -765,13 +768,6 @@ void shader_generate_main(
     hw_arg.reg_maps = reg_maps;
     This->baseShader.parse_state.current_row = 0;
 
-    /* Pre-declare registers */
-    if (wined3d_settings.shader_mode == SHADER_GLSL) {
-        generate_glsl_declarations(iface, reg_maps, buffer);
-    } else {
-        generate_arb_declarations(iface, reg_maps, buffer);
-    }
-
     /* Second pass, process opcodes */
     if (NULL != pToken) {
         while (D3DPS_END() != *pToken) {
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 055cf0d..7312811 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -1333,6 +1333,9 @@ #endif
         /* Create the hw GLSL shader object and assign it as the baseShader.prgId */
         GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
 
+        /* Base Declarations */
+        shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
+
         /* Base Shader Body */
         shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
 
@@ -1362,6 +1365,9 @@ #endif
         shader_addline(&buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
         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);
+
         /* Base Shader Body */
         shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
 
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 3d7db4d..c116595 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -864,6 +864,9 @@ #endif
         /* Create the hw GLSL shader program and assign it as the baseShader.prgId */
         GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
 
+        /* Base Declarations */
+        shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
+
         /* Base Shader Body */
         shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
 
@@ -887,6 +890,9 @@ #endif
             This->baseShader.limits.constant_float = 
                 min(95, This->baseShader.limits.constant_float);
 
+        /* Base Declarations */
+        shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
+
         /* Base Shader Body */
         shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8b67a7e..91c0082 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1248,17 +1248,25 @@ struct glsl_shader_prog_link {
     IWineD3DPixelShader*    pixelShader;
 };
 
+/* TODO: Make this dynamic, based on shader limits ? */
+#define MAX_REG_ADDR 1
+#define MAX_REG_TEMP 32
+#define MAX_REG_TEXCRD 8
+#define MAX_ATTRIBS 16
+#define MAX_CONST_F 256
+
 typedef struct shader_reg_maps {
-    DWORD texcoord;
-    DWORD temporary;
-    DWORD address;
 
-    /* Constants */
-    CHAR constantsF[256];  /* TODO: Make this dynamic */
+    char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
+    char temporary[MAX_REG_TEMP];           /* pixel, vertex */
+    char address[MAX_REG_ADDR];             /* vertex */
+    char attributes[MAX_ATTRIBS];           /* vertex */
+
+    char constantsF[MAX_CONST_F];           /* pixel, vertex */
     /* TODO: Integer and bool constants */
 
-    DWORD* semantics_in;
-    DWORD* semantics_out;
+    DWORD* semantics_in;                    /* vertex, pixel */
+    DWORD* semantics_out;                   /* vertex */
 
 } shader_reg_maps;
 
@@ -1373,6 +1381,16 @@ extern void shader_get_registers_used(
     shader_reg_maps* reg_maps,
     CONST DWORD* pToken);
 
+extern void shader_generate_glsl_declarations(
+    IWineD3DBaseShader *iface,
+    shader_reg_maps* reg_maps,
+    SHADER_BUFFER* buffer);
+
+extern void shader_generate_arb_declarations(
+    IWineD3DBaseShader *iface,
+    shader_reg_maps* reg_maps,
+    SHADER_BUFFER* buffer);
+
 extern void shader_generate_main(
     IWineD3DBaseShader *iface,
     SHADER_BUFFER* buffer,
-- 
1.3.3



More information about the wine-patches mailing list