Module: wine
Branch: master
Commit: cd7825c89374fb9dd4c20aef2dbfd258713efe6a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=cd7825c89374fb9dd4c20aef2…
Author: Stefan Dösinger <stefandoesinger(a)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) {