[1/2] wined3d: Always select the correct shader pair in the vertexdeclaration() state handler

H. Verbeet hverbeet at gmail.com
Mon Feb 12 19:24:02 CST 2007


The current code only calls shader_select() when the vertex shader has
changed. However, when the pixelshader() handler detects the vertex
shader state is dirty, it will let the vertexdeclaration() handler do
the setting instead, which can cause the pixelshader state to not be
properly applied. This patch fixes a regression in C&C Generals.

Changelog:
  - Always select the correct shader pair in the vertexdeclaration()
state handler
-------------- next part --------------
---

 dlls/wined3d/state.c |   25 +++++++++++--------------
 1 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 40d4fa4..c5f54ab 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -2662,6 +2662,8 @@ static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVer
 
 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
     BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
+    BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
+            && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
     BOOL transformed;
     /* Some stuff is in the device until we have per context tracking */
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
@@ -2757,24 +2759,19 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
         IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
     }
 
-    if(useVertexShaderFunction || device->last_was_vshader) {
-        BOOL usePixelShaderFunction = device->ps_selected_mode != SHADER_NONE && 
-                                      stateblock->pixelShader &&
-                                      ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
-
-        /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
-         * application
-         */
-        if(!isStateDirty(device, STATE_PIXELSHADER)) {
-            device->shader_backend->shader_select((IWineD3DDevice *) device, usePixelShaderFunction, useVertexShaderFunction);
+    /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
+     * application
+     */
+    if (!isStateDirty(device, STATE_PIXELSHADER)) {
+        device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
 
-            if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
-                shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
-            }
+        if (!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
+            shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
         }
-        device->last_was_vshader = useVertexShaderFunction;
     }
 
+    device->last_was_vshader = useVertexShaderFunction;
+
     if(updateFog) {
         state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock);
     }


More information about the wine-patches mailing list