Module: wine
Branch: master
Commit: 22e2a5aca5514f48970239d652cc24d4385677e8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=22e2a5aca5514f48970239d65…
Author: Stefan Dösinger <stefan(a)codeweavers.com>
Date: Tue Dec 19 23:22:19 2006 +0100
wined3d: Add pixel shaders to the state table.
---
dlls/wined3d/device.c | 31 ++++------------------
dlls/wined3d/drawprim.c | 8 -----
dlls/wined3d/state.c | 56 ++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 6 +++-
4 files changed, 67 insertions(+), 34 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 833c84b..1bc25c2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3690,37 +3690,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl
if (NULL != pShader) {
IWineD3DPixelShader_AddRef(pShader);
- if(oldShader == NULL) {
- /* Fixed function color ops deactivate the texture dimensions from the first stage which has colorop = disable
- * Pixel shaders require that this is enabled, so dirtify all samplers, they will enable the dimensions.
- * do not dirtify the colorop - it won't do anything when a ashader is bound
- * This is temporary until pixel shaders are handled by the state table too
- */
- int i;
- for(i = 0; i < MAX_SAMPLERS; i++) {
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
- }
- }
}
if (NULL != oldShader) {
IWineD3DPixelShader_Release(oldShader);
- if(pShader == NULL) {
- /* Fixed function pipeline color args conflict with pixel shader setup, so we do not apply them when a pshader is
- * bound. Due to that we have to reapply all color ops when disabling pixel shaders.
- * When pixel shaders are handled by the state table too, the pshader function will take care for that, and this
- * will also handle draw -> SetPixelShader(NULL) -> SetPixelShader(!= NULL) -> draw cases better
- */
- int i;
- for(i = 0; i < MAX_TEXTURES; i++) {
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP));
- }
- }
+ }
+
+ if (This->isRecordingState) {
+ TRACE("Recording... not performing anything\n");
+ return WINED3D_OK;
}
TRACE("(%p) : setting pShader(%p)\n", This, pShader);
- /**
- * TODO: merge HAL shaders context switching from prototype
- */
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADER);
return WINED3D_OK;
}
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index c550d04..a050bb2 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1781,14 +1781,6 @@ inline static void drawPrimitiveDrawStri
useDrawStridedSlow = TRUE;
}
- if(usePixelShaderFunction) {
- /* We compile the shader here because it depends on the texture stage state
- * setup of the bound textures. If the shader is already compiled and the texture stage
- * state setup matches the program this function will do nothing
- */
- IWineD3DPixelShader_CompileShader(This->stateBlock->pixelShader);
- }
-
/* Make any shaders active */
This->shader_backend->shader_select(iface, usePixelShaderFunction, useVertexShaderFunction);
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 89e2e2b..16057c4 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -1707,6 +1707,60 @@ static void sampler(DWORD state, IWineD3
}
}
+static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock) {
+ int i;
+
+ if(stateblock->pixelShader && ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.function != NULL) {
+ if(!stateblock->wineD3DDevice->last_was_pshader) {
+ /* Former draw without a pixel shader, some samplers
+ * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
+ * make sure to enable them
+ */
+ for(i=0; i < MAX_SAMPLERS; i++) {
+ if(!isStateDirty(stateblock->wineD3DDevice, STATE_SAMPLER(i))) {
+ sampler(STATE_SAMPLER(i), stateblock);
+ }
+ }
+ } else {
+ /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
+ * if a different texture was bound. I don't have to do anything.
+ */
+ }
+
+ /* 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
+ stateblock->wineD3DDevice->last_was_pshader = TRUE;
+ } else {
+ /* Disabled the pixel shader - color ops weren't applied
+ * while it was enabled, so re-apply them.
+ */
+ for(i=0; i < MAX_TEXTURES; i++) {
+ if(!isStateDirty(stateblock->wineD3DDevice, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
+ tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock);
+ }
+ }
+ 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
+ }
+}
+
const struct StateEntry StateTable[] =
{
/* State name representative, apply function */
@@ -2204,4 +2258,6 @@ const struct StateEntry StateTable[] =
{ /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
{ /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
{ /*15, Sampler 15 */ STATE_SAMPLER(15), sampler },
+ /* Pixel shader */
+ { /* , Pixel Shader */ STATE_PIXELSHADER, pixelshader },
};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 360ed7b..1df81bb 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -420,7 +420,10 @@ typedef void (*APPLYSTATEFUNC)(DWORD sta
#define STATE_SAMPLER(num) (STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE) + 1 + (num))
#define STATE_IS_SAMPLER(num) ((num) >= STATE_SAMPLER(0) && (num) <= STATE_SAMPLER(MAX_SAMPLERS - 1))
-#define STATE_HIGHEST (STATE_SAMPLER(MAX_SAMPLERS - 1))
+#define STATE_PIXELSHADER (STATE_SAMPLER(MAX_SAMPLERS - 1) + 1)
+#define STATE_IS_PIXELSHADER(a) ((a) == STATE_PIXELSHADER)
+
+#define STATE_HIGHEST (STATE_PIXELSHADER)
struct StateEntry
{
@@ -564,6 +567,7 @@ typedef struct IWineD3DDeviceImpl
BOOL texture_shader_active; /* TODO: Confirm use is correct */
BOOL last_was_notclipped;
BOOL untransformed;
+ BOOL last_was_pshader;
/* State block related */
BOOL isRecordingState;
Module: wine
Branch: master
Commit: 8365b2819ad5e9ab1e820876a35a50ba9f44532b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8365b2819ad5e9ab1e820876a…
Author: Stefan Dösinger <stefan(a)codeweavers.com>
Date: Tue Dec 19 23:17:17 2006 +0100
wined3d: Catch nop sampler changes.
---
dlls/wined3d/device.c | 13 ++++++++++++-
dlls/wined3d/stateblock.c | 3 ++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 6230146..833c84b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3368,6 +3368,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ DWORD oldValue = This->stateBlock->samplerState[Sampler][Type];
+
/**
* SetSampler is designed to allow for more than the standard up to 8 textures
* and Geforce has stopped supporting more than 6 standard textures in openGL.
@@ -3401,6 +3403,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
return WINED3D_OK;
}
+ if(oldValue == Value) {
+ TRACE("Application is setting the old value over, nothing to do\n");
+ return WINED3D_OK;
+ }
+
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(Sampler));
return WINED3D_OK;
@@ -4487,7 +4494,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl
This->stateBlock->textureDimensions[Stage] = IWineD3DBaseTexture_GetTextureDimensions(pTexture);
}
- oldTexture = This->updateStateBlock->textures[Stage];
TRACE("GL_LIMITS %d\n",GL_LIMITS(sampler_stages));
TRACE("(%p) : oldtexture(%p)\n", This,oldTexture);
@@ -4502,6 +4508,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
return WINED3D_OK;
}
+ if(oldTexture == pTexture) {
+ TRACE("App is setting the same texture again, nothing to do\n");
+ return WINED3D_OK;
+ }
+
/** NOTE: MSDN says that setTexture increases the reference count,
* and the the application nust set the texture back to null (or have a leaky application),
* This means we should pass the refcount up to the parent
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 4dd182c..afc582d 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -756,7 +756,8 @@ should really perform a delta so that on
((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[j][i] = TRUE;
}
}
-
+ /* SetTexture catches nop changes, so the above call does not assure that the sampler is updated */
+ IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_SAMPLER(j));
}
} else if (This->blockType == WINED3DSBT_PIXELSTATE) {