Stefan Dösinger : wined3d: Hardcode local constants into the shader if possible.

Alexandre Julliard julliard at winehq.org
Wed Nov 14 07:30:23 CST 2007


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Nov  9 14:48:47 2007 +0100

wined3d: Hardcode local constants into the shader if possible.

---

 dlls/wined3d/baseshader.c      |   16 ++++++++++------
 dlls/wined3d/glsl_shader.c     |   35 +++++++++++++++++++++++++++++++++--
 dlls/wined3d/pixelshader.c     |    1 +
 dlls/wined3d/vertexshader.c    |    1 +
 dlls/wined3d/wined3d_private.h |    2 ++
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 520554f..7f69927 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -447,12 +447,16 @@ HRESULT shader_get_registers_used(
                 else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader)
                     reg_maps->vpos = 1;
 
-                else if(WINED3DSPR_CONST == regtype && !pshader &&
-                        param & WINED3DSHADER_ADDRMODE_RELATIVE) {
-                    if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) {
-                        ((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg;
-                    } else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) {
-                        ((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg;
+                else if(WINED3DSPR_CONST == regtype) {
+                    if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
+                        if(!pshader) {
+                            if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) {
+                                ((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg;
+                            } else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) {
+                                ((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg;
+                            }
+                        }
+                        reg_maps->usesrelconstF = TRUE;
                     }
                 }
             }
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 73fb0f6..01206e1 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -199,6 +199,11 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL
     }
     checkGLcall("glUniform4fvARB()");
 
+    if(!This->baseShader.load_local_constsF) {
+        TRACE("No need to load local float constants for this shader\n");
+        return;
+    }
+
     /* Load immediate constants */
     if (TRACE_ON(d3d_shader)) {
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
@@ -464,6 +469,7 @@ void shader_generate_glsl_declarations(
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
     int i;
     unsigned int extra_constants_needed = 0;
+    local_constant* lconst;
 
     /* There are some minor differences between pixel and vertex shaders */
     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
@@ -640,6 +646,15 @@ void shader_generate_glsl_declarations(
     shader_addline(buffer, "vec4 tmp0;\n");
     shader_addline(buffer, "vec4 tmp1;\n");
 
+    /* Hardcodeable local constants */
+    if(!This->baseShader.load_local_constsF) {
+        LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
+            float *value = (float *) lconst->value;
+            shader_addline(buffer, "const vec4 LC%u = vec4(%f, %f, %f, %f);\n", lconst->idx,
+                           value[0], value[1], value[2], value[3]);
+        }
+    }
+
     /* Start the main program */
     shader_addline(buffer, "void main() {\n");
     if(pshader && reg_maps->vpos) {
@@ -734,6 +749,17 @@ static void shader_glsl_gen_modifier (
     }
 }
 
+static BOOL constant_is_local(IWineD3DBaseShaderImpl* This, DWORD reg) {
+    local_constant* lconst;
+
+    if(This->baseShader.load_local_constsF) return FALSE;
+    LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
+        if(lconst->idx == reg) return TRUE;
+    }
+    return FALSE;
+
+}
+
 /** Writes the GLSL variable name that corresponds to the register that the
  * DX opcode parameter is trying to access */
 static void shader_glsl_get_register_name(
@@ -819,8 +845,13 @@ static void shader_glsl_get_register_name(
                }
            }
 
-        } else
-             sprintf(tmpStr, "%s[%u]", prefix, reg);
+        } else {
+            if(constant_is_local(This, reg)) {
+                sprintf(tmpStr, "LC%u", reg);
+            } else {
+                sprintf(tmpStr, "%s[%u]", prefix, reg);
+            }
+        }
 
         break;
     }
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 62a9fe6..2c8424d 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -586,6 +586,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
             }
         }
     }
+    This->baseShader.load_local_constsF = FALSE;
 
     This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
 
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 286565a..e957eb4 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -587,6 +587,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
             This->rel_offset = 0;
         }
     }
+    This->baseShader.load_local_constsF = This->baseShader.reg_maps.usesrelconstF && !list_empty(&This->baseShader.constantsF);
 
     /* 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 4100ad9..8fbf866 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1669,6 +1669,7 @@ typedef struct shader_reg_maps {
     DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
     char bumpmat, luminanceparams;
     char usesnrm, vpos, usesdsy;
+    char usesrelconstF;
 
     /* Whether or not loops are used in this shader, and nesting depth */
     unsigned loop_depth;
@@ -1898,6 +1899,7 @@ typedef struct IWineD3DBaseShaderClass
     GLuint                          prgId;
     BOOL                            is_compiled;
     UINT                            cur_loop_depth, cur_loop_regno;
+    BOOL                            load_local_constsF;
 
     /* Type of shader backend */
     int shader_mode;




More information about the wine-cvs mailing list