From d0d681c81ef537ae3e8d0a6cc67310758b9f63f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 26 May 2009 13:43:43 +0200 Subject: [PATCH] wined3d: Make find_gl_pshader backend private. --- dlls/wined3d/arb_program_shader.c | 59 +++++++++++++++++++++++++-- dlls/wined3d/baseshader.c | 7 ---- dlls/wined3d/glsl_shader.c | 55 +++++++++++++++++++++++++- dlls/wined3d/pixelshader.c | 66 +------------------------------ dlls/wined3d/wined3d_private.h | 4 +- 5 files changed, 111 insertions(+), 80 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index db19fe57b0f..6ae72d86e73 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1926,6 +1926,60 @@ static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, en return program_id; } +static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, + SHADER_BUFFER *buffer, const struct ps_compile_args *args); + +/* GL locking is done by the caller */ +static GLuint find_arb_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args) +{ + UINT i; + DWORD new_size; + struct ps_compiled_shader *new_array; + SHADER_BUFFER buffer; + + /* 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 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) { + return shader->gl_shaders[i].prgId; + } + } + + TRACE("No matching GL shader found, compiling a new shader\n"); + if(shader->shader_array_size == shader->num_gl_shaders) { + if (shader->num_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(!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; + + pixelshader_update_samplers(&shader->baseShader.reg_maps, + ((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures); + + shader_buffer_init(&buffer); + shader->gl_shaders[shader->num_gl_shaders].prgId = + shader_arb_generate_pshader((IWineD3DPixelShader *)shader, &buffer, args); + shader_buffer_free(&buffer); + + return shader->gl_shaders[shader->num_gl_shaders++].prgId; +} + /* GL locking is done by the caller */ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -1957,8 +2011,8 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) { struct ps_compile_args compile_args; TRACE("Using pixel shader\n"); find_ps_compile_args((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, This->stateBlock, &compile_args); - priv->current_fprogram_id = find_gl_pshader((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, - &compile_args); + priv->current_fprogram_id = find_arb_pshader((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, + &compile_args); /* Bind the fragment program */ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id)); @@ -2539,7 +2593,6 @@ const shader_backend_t arb_program_shader_backend = { shader_arb_alloc, shader_arb_free, shader_arb_dirty_const, - shader_arb_generate_pshader, shader_arb_generate_vshader, shader_arb_get_caps, shader_arb_color_fixup_supported, diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index dbbca56e7cf..d62c91c49bc 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -1283,12 +1283,6 @@ static void shader_none_destroy(IWineD3DBaseShader *iface) {} static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;} static void shader_none_free(IWineD3DDevice *iface) {} static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;} -static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, - SHADER_BUFFER *buffer, const struct ps_compile_args *args) -{ - FIXME("NONE shader backend asked to generate a pixel shader\n"); - return 0; -} static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { @@ -1338,7 +1332,6 @@ const shader_backend_t none_shader_backend = { shader_none_alloc, shader_none_free, shader_none_dirty_const, - shader_none_generate_pshader, shader_none_generate_vshader, shader_none_get_caps, shader_none_color_fixup_supported, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 8eaffe89ce7..2780d8c053c 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3608,6 +3608,58 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD checkGLcall("Hardcoding local constants\n"); } +static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, + SHADER_BUFFER *buffer, const struct ps_compile_args *args); + +static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args) +{ + UINT i; + DWORD new_size; + struct ps_compiled_shader *new_array; + SHADER_BUFFER buffer; + + /* 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 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) { + return shader->gl_shaders[i].prgId; + } + } + + TRACE("No matching GL shader found, compiling a new shader\n"); + if(shader->shader_array_size == shader->num_gl_shaders) { + if (shader->num_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(!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; + + pixelshader_update_samplers(&shader->baseShader.reg_maps, + ((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures); + shader_buffer_init(&buffer); + shader->gl_shaders[shader->num_gl_shaders].prgId = + shader_glsl_generate_pshader((IWineD3DPixelShader*) shader, &buffer, args); + shader_buffer_free(&buffer); + + return shader->gl_shaders[shader->num_gl_shaders++].prgId; +} + /** 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). @@ -3715,7 +3767,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use } if(use_ps) { - pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args); + pshader_id = find_glsl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args); } else { pshader_id = 0; } @@ -4512,7 +4564,6 @@ const shader_backend_t glsl_shader_backend = { shader_glsl_alloc, shader_glsl_free, shader_glsl_dirty_const, - shader_glsl_generate_pshader, shader_glsl_generate_vshader, shader_glsl_get_caps, shader_glsl_color_fixup_supported, diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index f1966a1e10a..6ac145c1ae2 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -299,7 +299,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i return WINED3D_OK; } -static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures) +void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures) { WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type; unsigned int i; @@ -343,28 +343,6 @@ static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD } } -/* GL locking is done by the caller */ -static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args) -{ - CONST DWORD *function = This->baseShader.function; - GLuint retval; - SHADER_BUFFER buffer; - IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; - - TRACE("(%p) : function %p\n", This, function); - - pixelshader_update_samplers(&This->baseShader.reg_maps, - ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures); - - /* Generate the HW shader */ - TRACE("(%p) : Generating hardware program\n", This); - shader_buffer_init(&buffer); - retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args); - shader_buffer_free(&buffer); - - return retval; -} - const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl = { /*** IUnknown methods ***/ @@ -443,45 +421,3 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp } } } - -/* GL locking is done by the caller */ -GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args) -{ - UINT i; - 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 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) { - return shader->gl_shaders[i].prgId; - } - } - - TRACE("No matching GL shader found, compiling a new shader\n"); - if(shader->shader_array_size == shader->num_gl_shaders) { - if (shader->num_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(!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; - shader->gl_shaders[shader->num_gl_shaders].prgId = pixelshader_compile(shader, args); - return shader->gl_shaders[shader->num_gl_shaders++].prgId; -} diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c830d355659..cf9a6ca4fb8 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -809,8 +809,6 @@ typedef struct { HRESULT (*shader_alloc_private)(IWineD3DDevice *iface); void (*shader_free_private)(IWineD3DDevice *iface); BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface); - GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, - SHADER_BUFFER *buffer, const struct ps_compile_args *args); GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args); void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps); @@ -2729,7 +2727,7 @@ typedef struct IWineD3DPixelShaderImpl { } IWineD3DPixelShaderImpl; extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl; -GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args); +void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures); void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args); /* sRGB correction constants */