Stefan Dösinger : wined3d: Apply shaders in their state handlers.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jan 8 14:44:04 CST 2007
Module: wine
Branch: master
Commit: 799770b992967f562b309fbacce31bf661980a31
URL: http://source.winehq.org/git/wine.git/?a=commit;h=799770b992967f562b309fbacce31bf661980a31
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Sat Jan 6 18:14:12 2007 +0100
wined3d: Apply shaders in their state handlers.
---
dlls/wined3d/arb_program_shader.c | 6 +++++
dlls/wined3d/drawprim.c | 14 +++++++-----
dlls/wined3d/state.c | 39 +++++++++++++++++++++---------------
3 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index a8e4c9a..073a3ad 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -946,6 +946,9 @@ static void shader_arb_select(IWineD3DDe
checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);");
TRACE("(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n",
This, ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.prgId);
+ } else if(GL_SUPPORT(GL_VERTEX_PROGRAM_ARB)) {
+ glDisable(GL_VERTEX_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
}
if (usePS) {
@@ -961,6 +964,9 @@ static void shader_arb_select(IWineD3DDe
checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");
TRACE("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n",
This, ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId);
+ } else if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
}
}
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index f2aec53..33c7480 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1108,9 +1108,6 @@ inline static void drawPrimitiveDrawStri
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- /* Make any shaders active */
- This->shader_backend->shader_select(iface, usePixelShaderFunction, useVertexShaderFunction);
-
/* Load any global constants/uniforms that may have been set by the application */
This->shader_backend->shader_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction);
@@ -1119,9 +1116,6 @@ inline static void drawPrimitiveDrawStri
drawStridedSlow(iface, dataLocations, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx, baseVIndex);
else
drawStridedFast(iface, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx, baseVIndex);
-
- /* Cleanup any shaders */
- This->shader_backend->shader_cleanup(usePixelShaderFunction, useVertexShaderFunction);
}
static void check_fbo_status(IWineD3DDevice *iface) {
@@ -1164,6 +1158,14 @@ static void depth_blt(IWineD3DDevice *if
glBindTexture(GL_TEXTURE_2D, old_binding);
glPopAttrib();
+
+ /* Reselect the old shaders. There doesn't seem to be any glPushAttrib bit for arb shaders,
+ * and this seems easier and more efficient than providing the shader backend with a private
+ * storage to read and restore the old shader settings
+ */
+ This->shader_backend->shader_select(iface,
+ This->stateBlock->pixelShader && ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function,
+ This->stateBlock->vertexShader && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function);
}
static void depth_copy(IWineD3DDevice *iface) {
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 34aa4bc..70a374f 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -1833,16 +1833,12 @@ static void pixelshader(DWORD state, IWi
/* Compile and bind the shader */
IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
-#if 0
- /* Can't do that here right now, because glsl shaders depend on having both pixel and vertex shader
- * setup at the same time. The shader_select call will be done by drawprim until vertex shaders are
- * moved to the state table too
- */
- stateblock->wineD3DDevice->shader_backend->shader_select(
- (IWineD3DDevice *) stateblock->wineD3DDevice,
- TRUE,
- !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
-#endif
+ if(!isStateDirty(stateblock->wineD3DDevice, StateTable[STATE_VSHADER].representative)) {
+ stateblock->wineD3DDevice->shader_backend->shader_select(
+ (IWineD3DDevice *) stateblock->wineD3DDevice,
+ TRUE,
+ !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
+ }
stateblock->wineD3DDevice->last_was_pshader = TRUE;
} else {
/* Disabled the pixel shader - color ops weren't applied
@@ -1855,12 +1851,12 @@ static void pixelshader(DWORD state, IWi
}
stateblock->wineD3DDevice->last_was_pshader = FALSE;
-#if 0
- stateblock->wineD3DDevice->shader_backend->shader_select(
- (IWineD3DDevice *) stateblock->wineD3DDevice,
- FALSE,
- !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
-#endif
+ if(!isStateDirty(stateblock->wineD3DDevice, StateTable[STATE_VSHADER].representative)) {
+ stateblock->wineD3DDevice->shader_backend->shader_select(
+ (IWineD3DDevice *) stateblock->wineD3DDevice,
+ FALSE,
+ !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
+ }
}
}
@@ -2653,6 +2649,17 @@ 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;
+
+ device->shader_backend->shader_select((IWineD3DDevice *) device, usePixelShaderFunction, useVertexShaderFunction);
+ }
}
if(updateFog) {
More information about the wine-cvs
mailing list