Stefan Dösinger : wined3d: Move applying shader constants to the state table.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jan 8 14:44:05 CST 2007


Module: wine
Branch: master
Commit: 8e37fcd266ad0bfd445f09be74b176dc32e72d6e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8e37fcd266ad0bfd445f09be74b176dc32e72d6e

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sat Jan  6 18:17:27 2007 +0100

wined3d: Move applying shader constants to the state table.

---

 dlls/wined3d/device.c          |   12 ++++++++++
 dlls/wined3d/drawprim.c        |    6 +----
 dlls/wined3d/state.c           |   47 ++++++++++++++++++++++++++++++++-------
 dlls/wined3d/wined3d_private.h |    7 +++++-
 4 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 14e305a..e955a8b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3328,6 +3328,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         This->updateStateBlock->set.vertexShaderConstantsB[i]     = TRUE;
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+
     return WINED3D_OK;
 }
 
@@ -3375,6 +3377,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         This->updateStateBlock->set.vertexShaderConstantsI[i]     = TRUE;
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+
     return WINED3D_OK;
 }
 
@@ -3427,6 +3431,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         This->updateStateBlock->changed.vertexShaderConstantsF[i] = TRUE;
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+
     return WINED3D_OK;
 }
 
@@ -3606,6 +3612,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         This->updateStateBlock->set.pixelShaderConstantsB[i]     = TRUE;
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
+
     return WINED3D_OK;
 }
 
@@ -3653,6 +3661,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         This->updateStateBlock->set.pixelShaderConstantsI[i]     = TRUE;
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
+
     return WINED3D_OK;
 }
 
@@ -3705,6 +3715,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         This->updateStateBlock->changed.pixelShaderConstantsF[i] = TRUE;
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
+
     return WINED3D_OK;
 }
 
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 33c7480..54db1e7 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1106,10 +1106,7 @@ inline static void drawPrimitiveDrawStri
     int minIndex,
     long StartIdx) {
 
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-    /* Load any global constants/uniforms that may have been set by the application */
-    This->shader_backend->shader_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction);
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;    
 
     /* Draw vertex-by-vertex */
     if (This->useDrawStridedSlow)
@@ -1272,7 +1269,6 @@ void drawPrimitive(IWineD3DDevice *iface
     }
     This->numDirtyEntries = 0; /* This makes the whole list clean */
 
-
     if (TRACE_ON(d3d_draw) && wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
         check_fbo_status(iface);
     }
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 70a374f..768bd12 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -1810,6 +1810,22 @@ static void sampler(DWORD state, IWineD3
     }
 }
 
+static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock) {
+    IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
+
+    /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
+     * has an update pending
+     */
+    if(isStateDirty(device, STATE_VDECL) ||
+       isStateDirty(device, STATE_PIXELSHADER)) {
+       return;
+    }
+    
+    device->shader_backend->shader_load_constants((IWineD3DDevice *) device,
+        stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function,
+        stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function);
+}
+
 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock) {
     int i;
 
@@ -1838,6 +1854,10 @@ static void pixelshader(DWORD state, IWi
                     (IWineD3DDevice *) stateblock->wineD3DDevice,
                     TRUE,
                     !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
+            
+            if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT)) {
+                shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
+            }
         }
         stateblock->wineD3DDevice->last_was_pshader = TRUE;
     } else {
@@ -1856,6 +1876,10 @@ static void pixelshader(DWORD state, IWi
                     (IWineD3DDevice *) stateblock->wineD3DDevice,
                     FALSE,
                     !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
+
+            if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT)) {
+                shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
+            }
         }
     }
 }
@@ -2649,16 +2673,20 @@ static void vertexdeclaration(DWORD stat
          * in order to determine if we need to do any swizzling for D3DCOLOR
          * registers. If the shader is already compiled this call will do nothing. */
         IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
+    }
 
-        /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
-         * application
-         */
-        if(!isStateDirty(device, STATE_PIXELSHADER)) {
-            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)) {
+        BOOL usePixelShaderFunction = device->ps_selected_mode != SHADER_NONE && 
+                                        stateblock->pixelShader &&
+                                        ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
+
+        device->shader_backend->shader_select((IWineD3DDevice *) device, usePixelShaderFunction, useVertexShaderFunction);
 
-            device->shader_backend->shader_select((IWineD3DDevice *) device, usePixelShaderFunction, useVertexShaderFunction);
+        if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
+            shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
         }
     }
 
@@ -3704,5 +3732,6 @@ const struct StateEntry StateTable[] =
     { /*   , STATE_VDECL                            */      STATE_VDECL,                                        vertexdeclaration   },
     { /*   , STATE_VSHADER                          */      STATE_VDECL,                                        vertexdeclaration   },
     { /*   , STATE_VIEWPORT                         */      STATE_VIEWPORT,                                     viewport            },
-
+    { /*   , STATE_VERTEXSHADERCONSTANT             */      STATE_VERTEXSHADERCONSTANT,                         shaderconstant      },
+    { /*   , STATE_PIXELSHADERCONSTANT              */      STATE_VERTEXSHADERCONSTANT,                         shaderconstant      },
 };
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2eefa60..8b7170f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -436,7 +436,12 @@ typedef void (*APPLYSTATEFUNC)(DWORD sta
 #define STATE_VIEWPORT (STATE_VSHADER + 1)
 #define STATE_IS_VIEWPORT(a) ((a) == STATE_VIEWPORT)
 
-#define STATE_HIGHEST (STATE_VIEWPORT)
+#define STATE_VERTEXSHADERCONSTANT (STATE_VIEWPORT + 1)
+#define STATE_PIXELSHADERCONSTANT (STATE_VERTEXSHADERCONSTANT + 1)
+#define STATE_IS_VERTEXSHADERCONSTANT(a) ((a) == STATE_VERTEXSHADERCONSTANT)
+#define STATE_IS_PIXELSHADERCONSTANT(a) ((a) == STATE_PIXELSHADERCONSTANT)
+
+#define STATE_HIGHEST (STATE_PIXELSHADERCONSTANT)
 
 struct StateEntry
 {




More information about the wine-cvs mailing list