Stefan Dösinger : wined3d: Implement the varying map.

Alexandre Julliard julliard at winehq.org
Wed Nov 7 06:45:54 CST 2007


Module: wine
Branch: master
Commit: 1b23dd1ba1e4bc557e842d77ce21432e5eda5dae
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1b23dd1ba1e4bc557e842d77ce21432e5eda5dae

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Nov  6 12:34:22 2007 +0100

wined3d: Implement the varying map.

---

 dlls/wined3d/baseshader.c      |   20 ++++++++++++++++++--
 dlls/wined3d/glsl_shader.c     |    3 +++
 dlls/wined3d/pixelshader.c     |   35 +++++++++++++++++++++++++++++++++--
 dlls/wined3d/wined3d_private.h |    1 +
 4 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 2d1c5d9..df0ac0c 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -422,8 +422,24 @@ HRESULT shader_get_registers_used(
                 else if (WINED3DSPR_TEMP == regtype)
                     reg_maps->temporary[reg] = 1;
 
-                else if (WINED3DSPR_INPUT == regtype && !pshader)
-                    reg_maps->attributes[reg] = 1;
+                else if (WINED3DSPR_INPUT == regtype) {
+                    if( !pshader)
+                        reg_maps->attributes[reg] = 1;
+                    else {
+                        if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
+                            /* If relative addressing is used, we must assume that all registers
+                             * are used. Even if it is a construct like v3[aL], we can't assume
+                             * that v0, v1 and v2 aren't read because aL can be negative
+                             */
+                            unsigned int i;
+                            for(i = 0; i < MAX_REG_INPUT; i++) {
+                                ((IWineD3DPixelShaderImpl *) This)->input_reg_used[i] = TRUE;
+                            }
+                        } else {
+                            ((IWineD3DPixelShaderImpl *) This)->input_reg_used[reg] = TRUE;
+                        }
+                    }
+                }
 
                 else if (WINED3DSPR_RASTOUT == regtype && reg == 1)
                     reg_maps->fog = 1;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 3dfca51..4083d56 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2670,6 +2670,9 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, semantic *semantics_in, sema
         if(map[i] >= (GL_LIMITS(glsl_varyings) / 4)) {
             FIXME("More input varyings declared than supported, expect issues\n");
             continue;
+        } else if(map[i] == -1) {
+            /* Declared, but not read register */
+            continue;
         }
         register_token = semantics_in[i].reg;
 
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index daeae42..138e419 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -543,7 +543,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) > 1) {
         shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
         HRESULT hr;
-        unsigned int i;
+        unsigned int i, j, highest_reg_used = 0, num_regs_used = 0;
 
         /* Second pass: figure out which registers are used, what the semantics are, etc.. */
         memset(reg_maps, 0, sizeof(shader_reg_maps));
@@ -553,7 +553,38 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
         /* FIXME: validate reg_maps against OpenGL */
 
         for(i = 0; i < MAX_REG_INPUT; i++) {
-            This->input_reg_map[i] = i;
+            if(This->input_reg_used[i]) {
+                num_regs_used++;
+                highest_reg_used = i;
+            }
+        }
+
+        /* Don't do any register mapping magic if it is not needed, or if we can't
+         * achive anything anyway
+         */
+        if(highest_reg_used < (GL_LIMITS(glsl_varyings) / 4) ||
+           num_regs_used >= (GL_LIMITS(glsl_varyings) / 4) ) {
+            if(num_regs_used >= (GL_LIMITS(glsl_varyings) / 4)) {
+                /* This happens with relative addressing. The input mapper function
+                 * warns about this if the higher registers are declared too, so
+                 * don't write a FIXME here
+                 */
+                WARN("More varying registers used than supported\n");
+            }
+
+            for(i = 0; i < MAX_REG_INPUT; i++) {
+                This->input_reg_map[i] = i;
+            }
+        } else {
+            j = 0;
+            for(i = 0; i < MAX_REG_INPUT; i++) {
+                if(This->input_reg_used[i]) {
+                    This->input_reg_map[i] = j;
+                    j++;
+                } else {
+                    This->input_reg_map[i] = -1;
+                }
+            }
         }
     }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1fab9aa..56ba569 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2084,6 +2084,7 @@ typedef struct IWineD3DPixelShaderImpl {
     /* Pixel shader input semantics */
     semantic semantics_in [MAX_REG_INPUT];
     DWORD                 input_reg_map[MAX_REG_INPUT];
+    BOOL                  input_reg_used[MAX_REG_INPUT];
 
     /* run time data */
     PSHADERDATA                *data;




More information about the wine-cvs mailing list