Module: wine Branch: master Commit: 9c6cdda1472b45deb4ed1d90ddb802e4f56f6fc2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9c6cdda1472b45deb4ed1d90dd...
Author: Stefan Dösinger stefan@codeweavers.com Date: Fri Sep 14 13:11:00 2007 +0200
wined3d: Reverse the position fixup if the pshader is reading vpos.
---
dlls/wined3d/baseshader.c | 3 +++ dlls/wined3d/glsl_shader.c | 36 +++++++++++++++++++++++++++++++++++- dlls/wined3d/pixelshader.c | 7 +++++++ dlls/wined3d/wined3d_private.h | 5 ++++- 4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 6533810..67888b2 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -418,6 +418,9 @@ HRESULT shader_get_registers_used(
else if (WINED3DSPR_RASTOUT == regtype && reg == 1) reg_maps->fog = 1; + + else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader) + reg_maps->vpos = 1; } } } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b0ca134..47859fe 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -469,6 +469,20 @@ void shader_glsl_load_constants( checkGLcall("glGetUniformLocationARB"); GL_EXTCALL(glUniform4fvARB(pos, 1, mul_low)); } + if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) { + float correction_params[4]; + pos = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection")); + checkGLcall("glGetUniformLocationARB"); + if(deviceImpl->render_offscreen) { + correction_params[0] = 0.0; + correction_params[1] = 1.0; + } else { + /* position is window relative, not viewport relative */ + correction_params[0] = ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height; + correction_params[1] = -1.0; + } + GL_EXTCALL(glUniform4fvARB(pos, 1, correction_params)); + } } }
@@ -528,6 +542,7 @@ void shader_generate_glsl_declarations( shader_addline(buffer, "uniform vec4 srgb_mul_low;\n"); shader_addline(buffer, "uniform vec4 srgb_comparison;\n"); ps_impl->srgb_mode_hardcoded = 0; + extra_constants_needed++; } else { ps_impl->srgb_mode_hardcoded = 1; shader_addline(buffer, "const vec4 srgb_mul_low = {%f, %f, %f, %f};\n", @@ -544,6 +559,22 @@ void shader_generate_glsl_declarations( ps_impl->srgb_enabled = 0; ps_impl->srgb_mode_hardcoded = 1; } + if(reg_maps->vpos) { + if(This->baseShader.limits.constant_float + extra_constants_needed + 1 < GL_LIMITS(pshader_constantsF)) { + shader_addline(buffer, "uniform vec4 ycorrection;\n"); + ((IWineD3DPixelShaderImpl *) This)->vpos_uniform = 1; + extra_constants_needed++; + } else { + /* This happens because we do not have proper tracking of the constant registers that are + * actually used, only the max limit of the shader version + */ + FIXME("Cannot find a free uniform for vpos correction params\n"); + shader_addline(buffer, "const vec4 ycorrection = {%f, %f, 0.0, 0.0};\n", + device->render_offscreen ? 0.0 : ((IWineD3DSurfaceImpl *) device->render_targets[0])->currentDesc.Height, + device->render_offscreen ? 1.0 : -1.0); + } + shader_addline(buffer, "vec4 vpos;\n"); + } }
/* Declare texture samplers */ @@ -621,6 +652,9 @@ void shader_generate_glsl_declarations(
/* Start the main program */ shader_addline(buffer, "void main() {\n"); + if(pshader && reg_maps->vpos) { + shader_addline(buffer, "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1) - 0.5;\n"); + } }
/***************************************************************************** @@ -836,7 +870,7 @@ static void shader_glsl_get_register_name( case WINED3DSPR_MISCTYPE: if (reg == 0) { /* vPos */ - sprintf(tmpStr, "gl_FragCoord"); + sprintf(tmpStr, "vpos"); } else { /* gl_FrontFacing could be used for vFace, but note that * gl_FrontFacing is a bool, while vFace is a float for diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 7b9a2c4..245c6b0 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -592,6 +592,13 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader WARN("Recompiling shader because srgb correction is different and hardcoded\n"); goto recompile; } + if(This->baseShader.reg_maps.vpos && !This->vpos_uniform) { + if(This->render_offscreen != deviceImpl->render_offscreen || + This->height != ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height) { + WARN("Recompiling shader because vpos is used, hard compiled and changed\n"); + goto recompile; + } + }
return WINED3D_OK;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9457615..1cfd622 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1652,7 +1652,7 @@ typedef struct shader_reg_maps { * Use 0 as default (bit 31 is always 1 on a valid token) */ DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)]; char bumpmat, luminanceparams; - char usesnrm; + char usesnrm, vpos;
/* Whether or not a loop is used in this shader */ char loop; @@ -2083,6 +2083,9 @@ typedef struct IWineD3DPixelShaderImpl { char srgb_mode_hardcoded; UINT srgb_low_const; UINT srgb_cmp_const; + char vpos_uniform; + BOOL render_offscreen; + UINT height;
#if 0 /* needs reworking */ PSHADERINPUTDATA input;