wined3d: Add pixel shaders to the state table.
This commit is contained in:
parent
8365b2819a
commit
22e2a5aca5
@ -3690,37 +3690,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, I
|
|||||||
|
|
||||||
if (NULL != pShader) {
|
if (NULL != pShader) {
|
||||||
IWineD3DPixelShader_AddRef(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) {
|
if (NULL != oldShader) {
|
||||||
IWineD3DPixelShader_Release(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);
|
TRACE("(%p) : setting pShader(%p)\n", This, pShader);
|
||||||
/**
|
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADER);
|
||||||
* TODO: merge HAL shaders context switching from prototype
|
|
||||||
*/
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1781,14 +1781,6 @@ inline static void drawPrimitiveDrawStrided(
|
|||||||
useDrawStridedSlow = TRUE;
|
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 */
|
/* Make any shaders active */
|
||||||
This->shader_backend->shader_select(iface, usePixelShaderFunction, useVertexShaderFunction);
|
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[] =
|
const struct StateEntry StateTable[] =
|
||||||
{
|
{
|
||||||
/* State name representative, apply function */
|
/* State name representative, apply function */
|
||||||
@ -2204,4 +2258,6 @@ const struct StateEntry StateTable[] =
|
|||||||
{ /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
|
{ /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
|
||||||
{ /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
|
{ /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
|
||||||
{ /*15, Sampler 15 */ STATE_SAMPLER(15), 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_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_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
|
struct StateEntry
|
||||||
{
|
{
|
||||||
@ -564,6 +567,7 @@ typedef struct IWineD3DDeviceImpl
|
|||||||
BOOL texture_shader_active; /* TODO: Confirm use is correct */
|
BOOL texture_shader_active; /* TODO: Confirm use is correct */
|
||||||
BOOL last_was_notclipped;
|
BOOL last_was_notclipped;
|
||||||
BOOL untransformed;
|
BOOL untransformed;
|
||||||
|
BOOL last_was_pshader;
|
||||||
|
|
||||||
/* State block related */
|
/* State block related */
|
||||||
BOOL isRecordingState;
|
BOOL isRecordingState;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user