wined3d: Disable vertex shaders when transformed vertices are used.
This commit is contained in:
parent
ee09e8bfd6
commit
30ee071eb9
|
@ -161,6 +161,17 @@ void primitiveDeclarationConvertToStridedData(
|
|||
|
||||
memset(isPreLoaded, 0, sizeof(isPreLoaded));
|
||||
|
||||
/* Check for transformed vertices, disable vertex shader if present */
|
||||
strided->u.s.position_transformed = FALSE;
|
||||
for (i = 0; i < vertexDeclaration->declarationWNumElements - 1; ++i) {
|
||||
element = vertexDeclaration->pDeclarationWine + i;
|
||||
|
||||
if (element->Usage == WINED3DDECLUSAGE_POSITIONT) {
|
||||
strided->u.s.position_transformed = TRUE;
|
||||
useVertexShaderFunction = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Translate the declaration into strided data */
|
||||
for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) {
|
||||
GLint streamVBO = 0;
|
||||
|
@ -188,7 +199,7 @@ void primitiveDeclarationConvertToStridedData(
|
|||
data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO);
|
||||
if(fixup) {
|
||||
if( streamVBO != 0) *fixup = TRUE;
|
||||
else if(*fixup && This->stateBlock->vertexShader == NULL) {
|
||||
else if(*fixup && !useVertexShaderFunction) {
|
||||
/* This may be bad with the fixed function pipeline */
|
||||
FIXME("Missing fixed and unfixed vertices, expect graphics glitches\n");
|
||||
}
|
||||
|
@ -218,12 +229,6 @@ void primitiveDeclarationConvertToStridedData(
|
|||
strided->u.input[idx].dwStride = stride;
|
||||
strided->u.input[idx].VBO = streamVBO;
|
||||
strided->u.input[idx].streamNo = element->Stream;
|
||||
if (!useVertexShaderFunction) {
|
||||
if (element->Usage == WINED3DDECLUSAGE_POSITION)
|
||||
strided->u.s.position_transformed = FALSE;
|
||||
else if (element->Usage == WINED3DDECLUSAGE_POSITIONT)
|
||||
strided->u.s.position_transformed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Now call PreLoad on all the vertex buffers. In the very rare case
|
||||
|
@ -796,9 +801,7 @@ static void depth_blt(IWineD3DDevice *iface, GLuint texture) {
|
|||
* 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);
|
||||
This->shader_backend->shader_select(iface, use_ps(This), use_vs(This));
|
||||
}
|
||||
|
||||
static void depth_copy(IWineD3DDevice *iface) {
|
||||
|
|
|
@ -2049,7 +2049,7 @@ void delete_glsl_program_entry(IWineD3DDevice *iface, struct glsl_shader_prog_li
|
|||
* the program in the hash table. If it creates a program, it will link the
|
||||
* given objects, too.
|
||||
*/
|
||||
static void set_glsl_shader_program(IWineD3DDevice *iface) {
|
||||
static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(This->wineD3D))->gl_info;
|
||||
IWineD3DPixelShader *pshader = This->stateBlock->pixelShader;
|
||||
|
@ -2059,8 +2059,8 @@ static void set_glsl_shader_program(IWineD3DDevice *iface) {
|
|||
int i;
|
||||
char glsl_name[8];
|
||||
|
||||
GLhandleARB vshader_id = (vshader && This->vs_selected_mode == SHADER_GLSL) ? ((IWineD3DBaseShaderImpl*)vshader)->baseShader.prgId : 0;
|
||||
GLhandleARB pshader_id = (pshader && This->ps_selected_mode == SHADER_GLSL) ? ((IWineD3DBaseShaderImpl*)pshader)->baseShader.prgId : 0;
|
||||
GLhandleARB vshader_id = use_vs ? ((IWineD3DBaseShaderImpl*)vshader)->baseShader.prgId : 0;
|
||||
GLhandleARB pshader_id = use_ps ? ((IWineD3DBaseShaderImpl*)pshader)->baseShader.prgId : 0;
|
||||
entry = get_glsl_program_entry(This, vshader_id, pshader_id);
|
||||
if (entry) {
|
||||
This->stateBlock->glsl_program = entry;
|
||||
|
@ -2179,7 +2179,7 @@ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
|
|||
WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(This->wineD3D))->gl_info;
|
||||
GLhandleARB program_id = 0;
|
||||
|
||||
if (useVS || usePS) set_glsl_shader_program(iface);
|
||||
if (useVS || usePS) set_glsl_shader_program(iface, usePS, useVS);
|
||||
else This->stateBlock->glsl_program = NULL;
|
||||
|
||||
program_id = This->stateBlock->glsl_program ? This->stateBlock->glsl_program->programId : 0;
|
||||
|
|
|
@ -395,7 +395,7 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
|||
DWORD enable = 0xFFFFFFFF;
|
||||
DWORD disable = 0x00000000;
|
||||
|
||||
if(stateblock->vertexShader) {
|
||||
if (use_vs(stateblock->wineD3DDevice)) {
|
||||
/* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
|
||||
* so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
|
||||
* contitions I got sick of tracking down. The shader state handler disables all clip planes because
|
||||
|
@ -709,8 +709,8 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
|
|||
fogend = tmpvalue.f;
|
||||
|
||||
/* Activate when vertex shaders are in the state table */
|
||||
if(stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function &&
|
||||
((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) {
|
||||
if (use_vs(stateblock->wineD3DDevice)
|
||||
&& ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) {
|
||||
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||
checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
|
||||
if (stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
|
||||
|
@ -1977,17 +1977,16 @@ static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
|||
return;
|
||||
}
|
||||
|
||||
device->shader_backend->shader_load_constants((IWineD3DDevice *) device,
|
||||
stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function,
|
||||
stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function);
|
||||
device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
|
||||
}
|
||||
|
||||
static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||
BOOL use_ps = stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function != NULL;
|
||||
BOOL use_vs = stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL;
|
||||
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
|
||||
BOOL use_pshader = use_ps(device);
|
||||
BOOL use_vshader = use_vs(device);
|
||||
int i;
|
||||
|
||||
if (use_ps) {
|
||||
if (use_pshader) {
|
||||
if(!context->last_was_pshader) {
|
||||
/* Former draw without a pixel shader, some samplers
|
||||
* may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
|
||||
|
@ -2018,14 +2017,14 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
|
|||
}
|
||||
|
||||
if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
|
||||
stateblock->wineD3DDevice->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_ps, use_vs);
|
||||
device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
|
||||
|
||||
if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vs || use_ps)) {
|
||||
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
|
||||
shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
|
||||
}
|
||||
}
|
||||
|
||||
context->last_was_pshader = use_ps;
|
||||
context->last_was_pshader = use_pshader;
|
||||
}
|
||||
|
||||
static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||
|
@ -2827,6 +2826,10 @@ static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVer
|
|||
}
|
||||
}
|
||||
|
||||
if (dataLocations->u.s.position_transformed) {
|
||||
useVertexShaderFunction = FALSE;
|
||||
}
|
||||
|
||||
/* Unload the old arrays before loading the new ones to get old junk out */
|
||||
if(context->numberedArraysLoaded) {
|
||||
unloadNumberedArrays(stateblock);
|
||||
|
@ -2906,6 +2909,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
transformed = ((device->strided_streams.u.s.position.lpData != NULL ||
|
||||
device->strided_streams.u.s.position.VBO != 0) &&
|
||||
device->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
|
||||
if (transformed) useVertexShaderFunction = FALSE;
|
||||
|
||||
if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
|
||||
updateFog = TRUE;
|
||||
|
@ -2916,7 +2920,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
|||
state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
|
||||
}
|
||||
|
||||
if (!useVertexShaderFunction && transformed) {
|
||||
if (transformed) {
|
||||
context->last_was_rhw = TRUE;
|
||||
} else {
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ inline BOOL WINAPI IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T
|
|||
* FALSE: otherwise
|
||||
*/
|
||||
|
||||
if(device->stateBlock->vertexShader && ((IWineD3DVertexShaderImpl *) device->stateBlock->vertexShader)->baseShader.function) {
|
||||
if (use_vs(device)) {
|
||||
/* Assume no conversion */
|
||||
memset(&strided, 0, sizeof(strided));
|
||||
} else {
|
||||
|
|
|
@ -1936,4 +1936,18 @@ typedef struct {
|
|||
} PixelFormatDesc;
|
||||
|
||||
const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt);
|
||||
|
||||
inline static BOOL use_vs(IWineD3DDeviceImpl *device) {
|
||||
return (device->vs_selected_mode != SHADER_NONE
|
||||
&& device->stateBlock->vertexShader
|
||||
&& ((IWineD3DVertexShaderImpl *)device->stateBlock->vertexShader)->baseShader.function
|
||||
&& !device->strided_streams.u.s.position_transformed);
|
||||
}
|
||||
|
||||
inline static BOOL use_ps(IWineD3DDeviceImpl *device) {
|
||||
return (device->ps_selected_mode != SHADER_NONE
|
||||
&& device->stateBlock->pixelShader
|
||||
&& ((IWineD3DPixelShaderImpl *)device->stateBlock->pixelShader)->baseShader.function);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue