Module: wine Branch: master Commit: 4c29105cb2726ab1aead2b51ef1e70321848073c URL: http://source.winehq.org/git/wine.git/?a=commit;h=4c29105cb2726ab1aead2b51ef...
Author: Stefan Dösinger stefan@codeweavers.com Date: Tue May 5 20:45:32 2009 +0200
wined3d: Pack hardcoded local constants in ARB.
This makes the location of used program.local parameters more predictable and eases sharing this space with other private constants.
---
dlls/wined3d/arb_program_shader.c | 45 ++++++++++++++++++++++++++++-------- 1 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 1fcae76..67422b4 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -270,9 +270,29 @@ static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count + 1); }
+static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This) +{ + DWORD *ret; + DWORD idx = 0; + const local_constant *lconst; + + if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) return NULL; + + ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * This->baseShader.limits.temporary); + if(!ret) { + ERR("Out of memory\n"); + return NULL; + } + + LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { + ret[lconst->idx] = idx++; + } + return ret; +} + /* Generate the variable & register declarations for the ARB_vertex_program output target */ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps, - SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info) + SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info, DWORD *lconst_map) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; @@ -353,10 +373,10 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh /* Load local constants using the program-local space, * this avoids reloading them each time the shader is used */ - if(!This->baseShader.load_local_constsF) { + if(lconst_map) { LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { shader_addline(buffer, "PARAM C%u = program.local[%u];\n", lconst->idx, - lconst->idx); + lconst_map[lconst->idx]); } }
@@ -366,7 +386,7 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh * local constants do not declare the loaded constants as an array because ARB compilers usually * do not optimize unused constants away */ - if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) { + if(!lconst_map || list_empty(&This->baseShader.constantsF)) { /* Need to PARAM the environment parameters (constants) so we can use relative addressing */ shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n", max_constantsF, max_constantsF - 1); @@ -1980,6 +2000,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, const local_constant *lconst; GLuint retval; const char *fragcolor; + DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This);
/* Create the hw ARB shader */ shader_addline(buffer, "!!ARBfp1.0\n"); @@ -2017,7 +2038,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, }
/* Base Declarations */ - shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION); + shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, lconst_map);
/* Base Shader Body */ shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function); @@ -2048,12 +2069,13 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, }
/* Load immediate constants */ - if(!This->baseShader.load_local_constsF) { + if(lconst_map) { LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { const float *value = (const float *)lconst->value; - GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst->idx, value)); + GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value)); checkGLcall("glProgramLocalParameter4fvARB"); } + HeapFree(GetProcessHeap(), 0, lconst_map); }
return retval; @@ -2069,6 +2091,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, const WineD3D_GL_Info *gl_info = &device->adapter->gl_info; const local_constant *lconst; GLuint ret; + DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This);
/* Create the hw ARB shader */ shader_addline(buffer, "!!ARBvp1.0\n"); @@ -2082,7 +2105,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, shader_addline(buffer, "TEMP TMP;\n");
/* Base Declarations */ - shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION); + shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, lconst_map);
/* We need a constant to fixup the final position */ shader_addline(buffer, "PARAM posFixup = program.env[%d];\n", ARB_SHADER_PRIVCONST_POS); @@ -2165,13 +2188,15 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, ret = -1; } else { /* Load immediate constants */ - if(!This->baseShader.load_local_constsF) { + if(lconst_map) { LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) { const float *value = (const float *)lconst->value; - GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value)); + GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst_map[lconst->idx], value)); } } } + HeapFree(GetProcessHeap(), 0, lconst_map); + return ret; }