Module: wine Branch: master Commit: 3c3272dc413d6ffb78c4a91ae7c2e69de6521c17 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3c3272dc413d6ffb78c4a91ae7...
Author: Stefan Dösinger stefan@codeweavers.com Date: Mon Jan 19 18:39:36 2009 +0100
wined3d: Don't single-allocate new gl shaders.
---
dlls/wined3d/arb_program_shader.c | 1 + dlls/wined3d/glsl_shader.c | 1 + dlls/wined3d/pixelshader.c | 31 +++++++++++++++++++------------ dlls/wined3d/wined3d_private.h | 2 +- 4 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 7ff3cd4..c5f7718 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1857,6 +1857,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) { HeapFree(GetProcessHeap(), 0, This->gl_shaders); This->gl_shaders = NULL; This->num_gl_shaders = 0; + This->shader_array_size = 0; } else { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index d1e1bae..4024269 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3652,6 +3652,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { HeapFree(GetProcessHeap(), 0, ps->gl_shaders); ps->gl_shaders = NULL; ps->num_gl_shaders = 0; + ps->shader_array_size = 0; } else { TRACE("Deleting shader object %u\n", vs->prgId); ENTER_GL(); diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 9f96c59..9dcf37f 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -520,10 +520,12 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args) { UINT i; - struct ps_compiled_shader *old_array; + DWORD new_size; + struct ps_compiled_shader *new_array;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2), - * so a linear search is more performant than a hashmap + * so a linear search is more performant than a hashmap or a binary search + * (cache coherency etc) */ for(i = 0; i < shader->num_gl_shaders; i++) { if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) { @@ -532,17 +534,22 @@ GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_ }
TRACE("No matching GL shader found, compiling a new shader\n"); - old_array = shader->gl_shaders; - if(old_array) { - shader->gl_shaders = HeapReAlloc(GetProcessHeap(), 0, old_array, - (shader->num_gl_shaders + 1) * sizeof(*shader->gl_shaders)); - } else { - shader->gl_shaders = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders)); - } + if(shader->shader_array_size == shader->num_gl_shaders) { + if(shader->gl_shaders) { + new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2); + new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders, + new_size * sizeof(*shader->gl_shaders)); + } else { + new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders)); + new_size = 1; + }
- if(!shader->gl_shaders) { - ERR("Out of memory\n"); - return 0; + if(!new_array) { + ERR("Out of memory\n"); + return 0; + } + shader->gl_shaders = new_array; + shader->shader_array_size = new_size; }
shader->gl_shaders[shader->num_gl_shaders].args = *args; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 80f6c72..f7f724b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2382,7 +2382,7 @@ typedef struct IWineD3DPixelShaderImpl {
/* The GL shader */ struct ps_compiled_shader *gl_shaders; - UINT num_gl_shaders; + UINT num_gl_shaders, shader_array_size;
/* Some information about the shader behavior */ struct stb_const_desc bumpenvmatconst[MAX_TEXTURES];