Stefan Dösinger : wined3d: Don' t single-allocate new gl shaders.
Alexandre Julliard
julliard at winehq.org
Tue Jan 20 08:27:49 CST 2009
Module: wine
Branch: master
Commit: 3c3272dc413d6ffb78c4a91ae7c2e69de6521c17
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3c3272dc413d6ffb78c4a91ae7c2e69de6521c17
Author: Stefan Dösinger <stefan at 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];
More information about the wine-cvs
mailing list