Stefan Dösinger : wined3d: Hardcode local constants with glUniform4fvARB.

Alexandre Julliard julliard at winehq.org
Tue Jun 3 04:52:21 CDT 2008


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

Author: Stefan Dösinger <stefandoesinger at gmx.at>
Date:   Mon Jun  2 21:44:06 2008 +0200

wined3d: Hardcode local constants with glUniform4fvARB.

---

 dlls/wined3d/glsl_shader.c |   35 +++++++++++++++++++++++++++++++----
 1 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index a0c793b..8aec21d 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -699,12 +699,13 @@ void shader_generate_glsl_declarations(
     shader_addline(buffer, "vec4 tmp0;\n");
     shader_addline(buffer, "vec4 tmp1;\n");
 
-    /* Hardcodable local constants */
+    /* Local constants use a different name so they can be loaded once at shader link time
+     * They can't be hardcoded into the shader text via LC = {x, y, z, w}; because the
+     * float -> string conversion can cause precision loss.
+     */
     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 %cLC%u = vec4(%f, %f, %f, %f);\n", prefix, lconst->idx,
-                           value[0], value[1], value[2], value[3]);
+            shader_addline(buffer, "uniform vec4 %cLC%u;\n", prefix, lconst->idx);
         }
     }
 
@@ -3076,6 +3077,21 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     return ret;
 }
 
+static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, WineD3D_GL_Info *gl_info, GLhandleARB programId, char prefix) {
+    local_constant* lconst;
+    GLuint tmp_loc;
+    float *value;
+    char glsl_name[8];
+
+    LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry) {
+        value = (float *) lconst->value;
+        snprintf(glsl_name, sizeof(glsl_name), "%cLC%u", prefix, lconst->idx);
+        tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
+        GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, value));
+    }
+    checkGLcall("Hardcoding local constants\n");
+}
+
 /** Sets the GLSL program ID for the given pixel and vertex shader combination.
  * It sets the programId on the current StateBlock (because it should be called
  * inside of the DrawPrimitive() part of the render loop).
@@ -3228,6 +3244,17 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
         /* Load pixel shader samplers */
         shader_glsl_load_psamplers(gl_info, (IWineD3DStateBlock*)This->stateBlock, programId);
     }
+
+    /* If the local constants do not have to be loaded with the environment constants,
+     * load them now to have them hardcoded in the GLSL program. This saves some CPU cycles
+     * later
+     */
+    if(pshader && !((IWineD3DPixelShaderImpl*)pshader)->baseShader.load_local_constsF) {
+        hardcode_local_constants((IWineD3DBaseShaderImpl *) pshader, gl_info, programId, 'P');
+    }
+    if(vshader && !((IWineD3DVertexShaderImpl*)vshader)->baseShader.load_local_constsF) {
+        hardcode_local_constants((IWineD3DBaseShaderImpl *) vshader, gl_info, programId, 'V');
+    }
 }
 
 static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info) {




More information about the wine-cvs mailing list