Module: wine Branch: master Commit: edb78187a9277de615d7e9c2039505a8302a2940 URL: http://source.winehq.org/git/wine.git/?a=commit;h=edb78187a9277de615d7e9c203...
Author: Stefan Dösinger stefan@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;