Module: wine Branch: master Commit: 96bce8d6d49d92b524cca2f1f6722c83181951cd URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=96bce8d6d49d92b524cca2f1...
Author: Stefan Dösinger stefan@codeweavers.com Date: Sat Sep 23 19:09:06 2006 +0200
wined3d: Avoid wasting a uniform.
---
dlls/wined3d/arb_program_shader.c | 3 +++ dlls/wined3d/drawprim.c | 19 +++---------------- dlls/wined3d/glsl_shader.c | 10 ++++++++++ dlls/wined3d/vertexshader.c | 32 ++++++++++++++------------------ dlls/wined3d/wined3d_private.h | 9 +++++++++ 5 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index e984b9d..47397d6 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -127,6 +127,9 @@ void shader_arb_load_constants( GL_LIMITS(vshader_constantsF), stateBlock->vertexShaderConstantF, &stateBlock->set_vconstantsF); + + /* Upload the position fixup */ + GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, ARB_SHADER_PRIVCONST_POS, vshader_impl->wineD3DDevice->posFixup)); }
if (usePixelShader) { diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 2c31eb9..ff465a8 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -311,22 +311,9 @@ static void primitiveInitState(
/* Vertex Shader output is already transformed, so set up identity matrices */ if (useVS) { - glMatrixMode(GL_MODELVIEW); - checkGLcall("glMatrixMode"); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - checkGLcall("glMatrixMode"); - glLoadIdentity(); - /* Window Coord 0 is the middle of the first pixel, so translate by half - a pixel (See comment above glTranslate above) */ - glTranslatef(0.9 / This->stateBlock->viewport.Width, -0.9 / This->stateBlock->viewport.Height, 0); - checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)"); - if (This->renderUpsideDown) { - glMultMatrixf(invymat); - checkGLcall("glMultMatrixf(invymat)"); - } - This->modelview_valid = FALSE; - This->proj_valid = FALSE; + This->posFixup[1] = This->renderUpsideDown ? -1.0 : 1.0; + This->posFixup[2] = 0.9 / This->stateBlock->viewport.Width; + This->posFixup[3] = -0.9 / This->stateBlock->viewport.Height; } This->last_was_rhw = FALSE;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 257b9e5..0554392 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -288,6 +288,7 @@ void shader_glsl_load_constants( if (useVertexShader) { IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader; IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) vshader; + GLint pos;
IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration; @@ -314,6 +315,12 @@ void shader_glsl_load_constants( shader_glsl_load_constantsB(vshader, gl_info, programId, MAX_CONST_B, stateBlock->vertexShaderConstantB, stateBlock->set.vertexShaderConstantsB); + + /* Upload the position fixup params */ + pos = GL_EXTCALL(glGetUniformLocationARB(programId, "posFixup")); + checkGLcall("glGetUniformLocationARB"); + glUniform4fvARB(pos, 1, &vshader_impl->wineD3DDevice->posFixup[0]); + checkGLcall("glUniform4fvARB"); }
if (usePixelShader) { @@ -375,6 +382,9 @@ void shader_generate_glsl_declarations( if (This->baseShader.limits.constant_bool > 0) shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, This->baseShader.limits.constant_bool);
+ if(!pshader) + shader_addline(buffer, "uniform vec4 posFixup;\n"); + /* Declare texture samplers */ for (i = 0; i < This->baseShader.limits.sampler; i++) { if (reg_maps->samplers[i]) { diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 9719264..2d7ab58 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -737,17 +737,16 @@ #endif /* Write the final position. * * OpenGL coordinates specify the center of the pixel while d3d coords specify - * the corner. For that reason a translation is done with the projection matrix, - * which sets the offsets to move in the w coords of the matrix(see glTranslate manpage) - * Add the w coordinates to x and y, this avoids the need for a full matrix - * multiplication. The matrix is set up in drawprim.c, primitiveInitState. + * the corner. The offsets are stored in z and w in the 2nd row of the projection + * matrix to avoid wasting a free shader constant. Add them to the w and z coord + * of the 2nd row */ - shader_addline(&buffer, "gl_Position.x = gl_Position.x + gl_ProjectionMatrix[3][0];\n"); - shader_addline(&buffer, "gl_Position.y = gl_Position.y + gl_ProjectionMatrix[3][1];\n"); + shader_addline(&buffer, "gl_Position.x = gl_Position.x + posFixup[2];\n"); + shader_addline(&buffer, "gl_Position.y = gl_Position.y + posFixup[3];\n"); /* Account for any inverted textures (render to texture case) by reversing the y coordinate * (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) */ - shader_addline(&buffer, "gl_Position.y = gl_Position.y * gl_ProjectionMatrix[1][1];\n"); + shader_addline(&buffer, "gl_Position.y = gl_Position.y * posFixup[1];\n");
shader_addline(&buffer, "}\n\0");
@@ -771,10 +770,9 @@ #endif
/* Base Declarations */ shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION); - - /* We need the projection matrix to correctly render upside-down objects (render to texture) */ - shader_addline(&buffer, "PARAM PROJECTIONX = state.matrix.projection.row[0];\n"); - shader_addline(&buffer, "PARAM PROJECTIONY = state.matrix.projection.row[1];\n"); + + /* We need a constant to fixup the final position */ + shader_addline(&buffer, "PARAM posFixup = program.env[%d];\n", ARB_SHADER_PRIVCONST_POS);
if (reg_maps->fog) { This->usesFog = 1; @@ -792,17 +790,15 @@ #endif /* Write the final position. * * OpenGL coordinates specify the center of the pixel while d3d coords specify - * the corner. For that reason a translation is done with the projection matrix, - * which sets the offsets to move in the w coords of the matrix(see glTranslate manpage) - * Add the w coordinates to x and y, this avoids the need for a full matrix - * multiplication. The matrix is set up in drawprim.c, primitiveInitState. + * the corner. The offsets are stored in the 2nd row of the projection matrix, + * the x offset in z and the y offset in w. Add them to the resulting position */ - shader_addline(&buffer, "ADD result.position.x, TMP_OUT.x, PROJECTIONX.w;\n"); - shader_addline(&buffer, "ADD result.position.y, TMP_OUT.y, PROJECTIONY.w;\n"); + shader_addline(&buffer, "ADD result.position.x, TMP_OUT.x, posFixup.z;\n"); + shader_addline(&buffer, "ADD result.position.y, TMP_OUT.y, posFixup.w;\n"); /* Account for any inverted textures (render to texture case) by reversing the y coordinate * (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) */ - shader_addline(&buffer, "MUL result.position.y, TMP_OUT.y, PROJECTIONY.y;\n"); + shader_addline(&buffer, "MUL result.position.y, TMP_OUT.y, posFixup.y;\n");
shader_addline(&buffer, "END\n\0");
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a4fae10..9921d4c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -581,6 +581,9 @@ #define NEEDS_DI /* List of GLSL shader programs and their associated vertex & pixel shaders */ struct list glsl_shader_progs;
+ + /* Final position fixup constant */ + float posFixup[4]; } IWineD3DDeviceImpl;
extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl; @@ -1667,6 +1670,12 @@ inline static BOOL shader_is_comment(DWO return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK); }
+/* Internally used shader constants. Applications can use constants 0 to GL_LIMITS(vshader_constantsF) - 1, + * so upload them above that + */ +#define ARB_SHADER_PRIVCONST_BASE GL_LIMITS(vshader_constantsF) +#define ARB_SHADER_PRIVCONST_POS ARB_SHADER_PRIVCONST_BASE + 0 + /***************************************************************************** * IDirect3DVertexShader implementation structure */