Commit 22e2a5ac authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Add pixel shaders to the state table.

parent 8365b281
......@@ -3690,37 +3690,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, I
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;
}
......
......@@ -1781,14 +1781,6 @@ inline static void drawPrimitiveDrawStrided(
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);
......
......@@ -1707,6 +1707,60 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock) {
}
}
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 },
};
......@@ -420,7 +420,10 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock);
#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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment