Module: wine Branch: master Commit: 7c21147dcda0fd8c0513abdc25f68e4a2e13c50c URL: http://source.winehq.org/git/wine.git/?a=commit;h=7c21147dcda0fd8c0513abdc25...
Author: Stefan Dösinger stefan@codeweavers.com Date: Sun Dec 14 17:00:21 2008 +0100
wined3d: Remove the pixelshader fogstart/fogend optimization.
---
dlls/wined3d/arb_program_shader.c | 9 ++- dlls/wined3d/glsl_shader.c | 4 +- dlls/wined3d/state.c | 103 ++++++++----------------------------- 3 files changed, 31 insertions(+), 85 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index cd6ba29..438b025 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1969,9 +1969,12 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF shader_addline(buffer, "MOV result.color, %s;\n", fragcolor); break; case FOG_LINEAR: - shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n"); - shader_addline(buffer, "LRP result.color.xyz, TMP_FOG.x, %s, state.fog.color;\n", fragcolor); - shader_addline(buffer, "MOV result.color.w, %s.w;\n", fragcolor); + shader_addline(buffer, "SUB TMP_FOG.x, state.fog.params.z, state.fog.params.y;\n"); + shader_addline(buffer, "RCP TMP_FOG, -TMP_FOG.x;\n"); + shader_addline(buffer, "MUL TMP_FOG.y, -TMP_FOG.y, state.fog.params.z;\n"); + shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, TMP_FOG.x, TMP_FOG.y;\n"); + shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;\n", fragcolor); + shader_addline(buffer, "MOV result.color.a, %s.a;\n", fragcolor); break; case FOG_EXP: FIXME("Implement EXP fog in ARB\n"); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 0acdcad..8dfb416 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3844,7 +3844,9 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU switch(args->fog) { case FOG_OFF: break; case FOG_LINEAR: - shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n"); + shader_addline(buffer, "float fogstart = -1.0 / (gl_Fog.end - gl_Fog.start);\n"); + shader_addline(buffer, "float fogend = gl_Fog.end * -fogstart;\n"); + shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * fogstart + fogend, 0.0, 1.0);\n"); shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor); break; case FOG_EXP: diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 9d97283..d05ed21 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -897,9 +897,6 @@ static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, }
static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { - BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE]; - IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *)stateblock->pixelShader; - BOOL is_ps3 = use_ps(stateblock) && ps_impl->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0); float fogstart, fogend;
union { @@ -907,7 +904,7 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo float f; } tmpvalue;
- if (!fogenable) { + if (!stateblock->renderState[WINED3DRS_FOGENABLE]) { /* No fog? Disable it, and we're done :-) */ glDisable(GL_FOG); checkGLcall("glDisable GL_FOG"); @@ -955,19 +952,9 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo * without shaders). */
- if( is_ps3 ) { - if (!use_vs(stateblock) && stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) - { - FIXME("Implement vertex fog for pixel shader >= 3.0 and fixed function pipeline\n"); - } - } - - if (use_vs(stateblock) && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) - { + if (use_vs(stateblock) && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) { if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) { - if(!is_ps3) FIXME("Implement table fog for foggy vertex shader\n"); - /* Disable fog */ - fogenable = FALSE; + FIXME("vertex shader with table fog used\n"); } else { /* Set fog computation in the rasterizer to pass through the value (just blend it) */ glFogi(GL_FOG_MODE, GL_LINEAR); @@ -983,47 +970,6 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo } context->last_was_foggy_shader = TRUE; } - else if (use_ps(stateblock)) - { - /* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but - * -1/(e-s) and e/(e-s) respectively to simplify fog computation in the shader. - */ - WINED3DFOGMODE mode; - context->last_was_foggy_shader = FALSE; - - /* If both fogmodes are set use the table fog mode */ - if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) - mode = stateblock->renderState[WINED3DRS_FOGVERTEXMODE]; - else - mode = stateblock->renderState[WINED3DRS_FOGTABLEMODE]; - - switch (mode) { - case WINED3DFOG_EXP: - case WINED3DFOG_EXP2: - if(!is_ps3) FIXME("Implement non linear fog for pixel shader < 3.0\n"); - /* Disable fog */ - fogenable = FALSE; - break; - - case WINED3DFOG_LINEAR: - fogstart = -1.0f/(fogend-fogstart); - fogend *= -fogstart; - break; - - case WINED3DFOG_NONE: - if(!is_ps3) FIXME("Implement software vertex fog for pixel shader < 3.0\n"); - /* Disable fog */ - fogenable = FALSE; - break; - default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]); - } - - if(context->fog_coord) { - glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); - checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)"); - context->fog_coord = FALSE; - } - } /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes, * the system will apply only pixel(=table) fog effects." */ @@ -1130,33 +1076,28 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo } }
- if(fogenable) { - glEnable(GL_FOG); - checkGLcall("glEnable GL_FOG"); + glEnable(GL_FOG); + checkGLcall("glEnable GL_FOG");
- if(fogstart != fogend) - { - glFogfv(GL_FOG_START, &fogstart); - checkGLcall("glFogf(GL_FOG_START, fogstart)"); - TRACE("Fog Start == %f\n", fogstart); + if(fogstart != fogend) + { + glFogfv(GL_FOG_START, &fogstart); + checkGLcall("glFogf(GL_FOG_START, fogstart)"); + TRACE("Fog Start == %f\n", fogstart);
- glFogfv(GL_FOG_END, &fogend); - checkGLcall("glFogf(GL_FOG_END, fogend)"); - TRACE("Fog End == %f\n", fogend); - } - else - { - glFogf(GL_FOG_START, -1.0 / 0.0); - checkGLcall("glFogf(GL_FOG_START, fogstart)"); - TRACE("Fog Start == %f\n", fogstart); + glFogfv(GL_FOG_END, &fogend); + checkGLcall("glFogf(GL_FOG_END, fogend)"); + TRACE("Fog End == %f\n", fogend); + } + else + { + glFogf(GL_FOG_START, -1.0 / 0.0); + checkGLcall("glFogf(GL_FOG_START, fogstart)"); + TRACE("Fog Start == %f\n", fogstart);
- glFogf(GL_FOG_END, 0.0); - checkGLcall("glFogf(GL_FOG_END, fogend)"); - TRACE("Fog End == %f\n", fogend); - } - } else { - glDisable(GL_FOG); - checkGLcall("glDisable GL_FOG"); + glFogf(GL_FOG_END, 0.0); + checkGLcall("glFogf(GL_FOG_END, fogend)"); + TRACE("Fog End == %f\n", fogend); } }