Module: wine Branch: master Commit: 38239be58ca709ca107752ca7d3fee0763832725 URL: http://source.winehq.org/git/wine.git/?a=commit;h=38239be58ca709ca107752ca7d...
Author: Tobias Jakobi liquid.acid@gmx.net Date: Thu Mar 26 03:19:41 2009 +0100
wined3d: GLSL: Implement texrect coord fixup.
---
dlls/wined3d/glsl_shader.c | 53 +++++++++++++++++++++++++++++++++++++++++++- dlls/wined3d/state.c | 17 ++++++++++++- 2 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index da0b1a8..c92f99b 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -100,6 +100,7 @@ struct glsl_shader_prog_link { GLint vuniformI_locations[MAX_CONST_I]; GLint puniformI_locations[MAX_CONST_I]; GLint posFixup_location; + GLint rectFixup_location[MAX_FRAGMENT_SAMPLERS]; GLint bumpenvmat_location[MAX_TEXTURES]; GLint luminancescale_location[MAX_TEXTURES]; GLint luminanceoffset_location[MAX_TEXTURES]; @@ -587,6 +588,24 @@ static void shader_glsl_load_constants( } GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params)); } + + /* Constant loading for texture rect coord fixup. */ + if (prog->ps_args.texrect_fixup) { + UINT fixup = prog->ps_args.texrect_fixup; + + for (i = 0; fixup; fixup >>= 1, ++i) { + if (-1 != prog->rectFixup_location[i]) { + const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i]; + if (!tex) { + FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n"); + continue; + } else { + const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]}; + GL_EXTCALL(glUniform2fvARB(prog->rectFixup_location[i], 1, tex_dim)); + } + } + } + } }
if (priv->next_constant_version == UINT_MAX) @@ -774,6 +793,14 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s } else { shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); } + + if(ps_args->texrect_fixup & (1 << i)) { + /* RECT textures in OpenGL use texcoords in the range [0,width]x[0,height] + * while D3D has them in the (normalized) [0,1]x[0,1] range. + * samplerRectFixup stores texture dimensions and is updated through + * shader_glsl_load_constants when the sampler changes. */ + shader_addline(buffer, "uniform vec2 %csamplerRectFixup%u;\n", prefix, i); + } break; case WINED3DSTT_CUBE: shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i); @@ -1475,6 +1502,7 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const SHADER_OPCODE_AR const char *sampler_base; char dst_swizzle[6]; struct color_fixup_desc fixup; + BOOL rect_fixup = FALSE; va_list args;
shader_glsl_get_swizzle(swizzle, FALSE, arg->dst, dst_swizzle); @@ -1483,6 +1511,14 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const SHADER_OPCODE_AR IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) arg->shader; fixup = This->cur_args->color_fixup[sampler]; sampler_base = "Psampler"; + + if(This->cur_args->texrect_fixup & (1 << sampler)) { + if(bias) { + FIXME("Biased sampling from RECT textures is unsupported\n"); + } else { + rect_fixup = TRUE; + } + } } else { sampler_base = "Vsampler"; fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */ @@ -1499,7 +1535,11 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const SHADER_OPCODE_AR if(bias) { shader_addline(arg->buffer, ", %s)%s);\n", bias, dst_swizzle); } else { - shader_addline(arg->buffer, ")%s);\n", dst_swizzle); + if (rect_fixup) { + shader_addline(arg->buffer, " * PsamplerRectFixup%u)%s);\n", sampler, dst_swizzle); + } else { + shader_addline(arg->buffer, ")%s);\n", dst_swizzle); + } }
if(!is_identity_fixup(fixup)) { @@ -3479,6 +3519,17 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use } }
+ if (use_ps && ps_compile_args.texrect_fixup) { + char name[32]; + for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) { + if (ps_compile_args.texrect_fixup & (1 << i)) { + sprintf(name, "PsamplerRectFixup%u", i); + entry->rectFixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name)); + } else { + entry->rectFixup_location[i] = -1; + } + } + }
entry->posFixup_location = GL_EXTCALL(glGetUniformLocationARB(programId, "posFixup")); entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection")); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 0953042..2aa2b78 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3022,8 +3022,12 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W if(generated) { FIXME("Non-power2 texture being used with generated texture coords\n"); } - TRACE("Non power two matrix multiply fixup\n"); - glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix); + /* NP2 texcoord fixup is implemented for pixelshaders (currently only in GLSL backend) so + only enable the fixed-function-pipeline fixup via pow2Matrix when no PS is used. */ + if (!use_ps(stateblock)) { + TRACE("Non power two matrix multiply fixup\n"); + glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix); + } } }
@@ -3375,6 +3379,15 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context); } } + + /* Trigger shader constant reloading (for NP2 texcoord fixup) + * Only do this if pshaders are used (note: fixup is currently only implemented in GLSL). */ + if (!tex_impl->baseTexture.pow2Matrix_identity && use_ps(stateblock)) { + IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice; + /* FIXME: add something like shader_load_rectfixup_consts to the backend to only reload the + * constants that are used for the fixup (and not the other ones too) */ + d3ddevice->shader_backend->shader_load_constants((IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock)); + } } else if(mapped_stage < GL_LIMITS(textures)) { if(sampler < stateblock->lowest_disabled_stage) { /* TODO: What should I do with pixel shaders here ??? */