From 83be6a2b20280043074d0fc3a4f04c342a5b925f Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Wed, 17 Jun 2009 23:24:25 +0200 Subject: [wined3d] add ps_np2fixup_info structure --- dlls/wined3d/glsl_shader.c | 23 ++++++++++++++++++----- dlls/wined3d/wined3d_private.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index e065296..893cc27 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -114,6 +114,7 @@ struct glsl_shader_prog_link { struct vs_compile_args vs_args; struct ps_compile_args ps_args; UINT constant_version; + const struct ps_np2fixup_info *np2Fixup_info; }; typedef struct { @@ -126,11 +127,13 @@ typedef struct { struct shader_glsl_ctx_priv { const struct vs_compile_args *cur_vs_args; const struct ps_compile_args *cur_ps_args; + struct ps_np2fixup_info *cur_np2fixup_info; }; struct glsl_ps_compiled_shader { struct ps_compile_args args; + struct ps_np2fixup_info np2fixup; GLhandleARB prgId; }; @@ -3631,7 +3634,7 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD /* GL locking is done by the caller */ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShaderImpl *This, - SHADER_BUFFER *buffer, const struct ps_compile_args *args) + SHADER_BUFFER *buffer, const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info) { const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps; CONST DWORD *function = This->baseShader.function; @@ -3644,6 +3647,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShaderImpl *This, memset(&priv_ctx, 0, sizeof(priv_ctx)); priv_ctx.cur_ps_args = args; + priv_ctx.cur_np2fixup_info = np2fixup_info; shader_addline(buffer, "#version 120\n"); @@ -3806,13 +3810,15 @@ static GLuint shader_glsl_generate_vshader(IWineD3DVertexShaderImpl *This, return shader_obj; } -static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args) +static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args, + const struct ps_np2fixup_info **np2fixup_info) { UINT i; DWORD new_size; struct glsl_ps_compiled_shader *new_array; + struct glsl_pshader_private *shader_data; + struct ps_np2fixup_info *np2fixup = NULL; SHADER_BUFFER buffer; - struct glsl_pshader_private *shader_data; GLhandleARB ret; if(!shader->backend_priv) { @@ -3826,6 +3832,7 @@ static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const stru */ for(i = 0; i < shader_data->num_gl_shaders; i++) { if(memcmp(&shader_data->gl_shaders[i].args, args, sizeof(*args)) == 0) { + if(args->np2_fixup) *np2fixup_info = &shader_data->gl_shaders[i].np2fixup; return shader_data->gl_shaders[i].prgId; } } @@ -3852,13 +3859,17 @@ static GLhandleARB find_glsl_pshader(IWineD3DPixelShaderImpl *shader, const stru shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args; + memset(&shader_data->gl_shaders[shader_data->num_gl_shaders].np2fixup, 0, sizeof(struct ps_np2fixup_info)); + if (args->np2_fixup) np2fixup = &shader_data->gl_shaders[shader_data->num_gl_shaders].np2fixup; + pixelshader_update_samplers(&shader->baseShader.reg_maps, ((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures); shader_buffer_init(&buffer); - ret = shader_glsl_generate_pshader(shader, &buffer, args); + ret = shader_glsl_generate_pshader(shader, &buffer, args, np2fixup); shader_buffer_free(&buffer); shader_data->gl_shaders[shader_data->num_gl_shaders++].prgId = ret; + *np2fixup_info = np2fixup; return ret; } @@ -3970,6 +3981,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use entry->vs_args = vs_compile_args; entry->ps_args = ps_compile_args; entry->constant_version = 0; + entry->np2Fixup_info = NULL; /* Add the hash table entry */ add_glsl_program_entry(priv, entry); @@ -4020,7 +4032,8 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use /* Attach GLSL pshader */ if (pshader) { - GLhandleARB pshader_id = find_glsl_pshader((IWineD3DPixelShaderImpl *)pshader, &ps_compile_args); + GLhandleARB pshader_id = find_glsl_pshader((IWineD3DPixelShaderImpl *)pshader, &ps_compile_args, + &entry->np2Fixup_info); TRACE("Attaching GLSL shader object %u to program %u\n", pshader_id, programId); GL_EXTCALL(glAttachObjectARB(programId, pshader_id)); checkGLcall("glAttachObjectARB"); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b7c5592..11b8ff5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2705,6 +2705,24 @@ void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockIm /***************************************************************************** * IDirect3DPixelShader implementation structure */ + +/* Using additional shader constants (uniforms in GLSL / program environment + * or local parameters in ARB) is costly: + * ARB only knows float4 parameters and GLSL compiler are not really smart + * when it comes to efficiently pack float2 uniforms, so no space is wasted + * (in fact most compilers map a float2 to a full float4 uniform). + * + * For NP2 texcoord fixup we only need 2 floats (width and height) for each + * 2D texture used in the shader. We therefore pack fixup info for 2 textures + * into a single shader constant (uniform / program parameter). + * + * This structure is shared between the GLSL and the ARB backend.*/ +struct ps_np2fixup_info { + unsigned char idx[MAX_FRAGMENT_SAMPLERS]; /* indices to the real constant */ + WORD active; /* bitfield indicating if we can apply the fixup */ + WORD num_consts; +}; + typedef struct IWineD3DPixelShaderImpl { /* IUnknown parts */ const IWineD3DPixelShaderVtbl *lpVtbl; -- 1.6.0.6