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

wined3d: Use the shader backend to enable / disable atifs and nvts.

The previous logic assumed that if NVTS or ATIFS are available they will be used. This happens to be true for NVTS, but ATIFS is only used if neither ARBFP nor GLSL are supported. This breaks fixed function fragment processing on ATI r300 and newer cards
parent 9bbbebc2
...@@ -2081,6 +2081,10 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info ...@@ -2081,6 +2081,10 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info
static void shader_arb_load_init(void) { static void shader_arb_load_init(void) {
} }
static void shader_arb_fragment_enable(IWineD3DDevice *iface, BOOL enable) {
none_shader_backend.shader_fragment_enable(iface, enable);
}
const shader_backend_t arb_program_shader_backend = { const shader_backend_t arb_program_shader_backend = {
&shader_arb_select, &shader_arb_select,
&shader_arb_select_depth_blt, &shader_arb_select_depth_blt,
...@@ -2096,5 +2100,6 @@ const shader_backend_t arb_program_shader_backend = { ...@@ -2096,5 +2100,6 @@ const shader_backend_t arb_program_shader_backend = {
&shader_arb_generate_vshader, &shader_arb_generate_vshader,
&shader_arb_get_caps, &shader_arb_get_caps,
&shader_arb_load_init, &shader_arb_load_init,
&shader_arb_fragment_enable,
FFPStateTable FFPStateTable
}; };
...@@ -1026,6 +1026,16 @@ static void shader_atifs_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU ...@@ -1026,6 +1026,16 @@ static void shader_atifs_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
arb_program_shader_backend.shader_generate_vshader(iface, buffer); arb_program_shader_backend.shader_generate_vshader(iface, buffer);
} }
static void shader_atifs_fragment_enable(IWineD3DDevice *iface, BOOL enable) {
if(enable) {
glEnable(GL_FRAGMENT_SHADER_ATI);
checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
} else {
glDisable(GL_FRAGMENT_SHADER_ATI);
checkGLcall("glDisable(GL_FRAGMENT_SHADER_ATI)");
}
}
const shader_backend_t atifs_shader_backend = { const shader_backend_t atifs_shader_backend = {
shader_atifs_select, shader_atifs_select,
shader_atifs_select_depth_blt, shader_atifs_select_depth_blt,
...@@ -1041,5 +1051,6 @@ const shader_backend_t atifs_shader_backend = { ...@@ -1041,5 +1051,6 @@ const shader_backend_t atifs_shader_backend = {
shader_atifs_generate_vshader, shader_atifs_generate_vshader,
shader_atifs_get_caps, shader_atifs_get_caps,
shader_atifs_load_init, shader_atifs_load_init,
shader_atifs_fragment_enable,
ATIFSStateTable ATIFSStateTable
}; };
...@@ -1182,6 +1182,22 @@ static void shader_none_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_inf ...@@ -1182,6 +1182,22 @@ static void shader_none_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_inf
#endif #endif
} }
static void shader_none_fragment_enable(IWineD3DDevice *iface, BOOL enable) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
if(enable) {
glEnable(GL_TEXTURE_SHADER_NV);
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
} else {
glDisable(GL_TEXTURE_SHADER_NV);
checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
}
}
}
#undef GLINFO_LOCATION #undef GLINFO_LOCATION
const shader_backend_t none_shader_backend = { const shader_backend_t none_shader_backend = {
...@@ -1199,6 +1215,7 @@ const shader_backend_t none_shader_backend = { ...@@ -1199,6 +1215,7 @@ const shader_backend_t none_shader_backend = {
&shader_none_generate_vshader, &shader_none_generate_vshader,
&shader_none_get_caps, &shader_none_get_caps,
&shader_none_load_init, &shader_none_load_init,
&shader_none_fragment_enable,
FFPStateTable FFPStateTable
}; };
......
...@@ -351,10 +351,9 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar ...@@ -351,10 +351,9 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
/* Set up the context defaults */ /* Set up the context defaults */
oldCtx = pwglGetCurrentContext(); oldCtx = pwglGetCurrentContext();
oldDrawable = pwglGetCurrentDC(); oldDrawable = pwglGetCurrentDC();
if(oldCtx && oldDrawable && GL_SUPPORT(ATI_FRAGMENT_SHADER)) { if(oldCtx && oldDrawable) {
/* See comment in ActivateContext context switching */ /* See comment in ActivateContext context switching */
glDisable(GL_FRAGMENT_SHADER_ATI); This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, FALSE);
checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
} }
if(pwglMakeCurrent(hdc, ctx) == FALSE) { if(pwglMakeCurrent(hdc, ctx) == FALSE) {
ERR("Cannot activate context to set up defaults\n"); ERR("Cannot activate context to set up defaults\n");
...@@ -439,10 +438,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar ...@@ -439,10 +438,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
if(oldDrawable && oldCtx) { if(oldDrawable && oldCtx) {
pwglMakeCurrent(oldDrawable, oldCtx); pwglMakeCurrent(oldDrawable, oldCtx);
} }
if(GL_SUPPORT(ATI_FRAGMENT_SHADER)) { This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
glEnable(GL_FRAGMENT_SHADER_ATI);
checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
}
out: out:
return ret; return ret;
...@@ -687,13 +683,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex ...@@ -687,13 +683,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
checkGLcall("glViewport"); checkGLcall("glViewport");
Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, FALSE);
glDisable(GL_TEXTURE_SHADER_NV);
checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
} else if(GL_SUPPORT(ATI_FRAGMENT_SHADER)) {
glDisable(GL_FRAGMENT_SHADER_ATI);
checkGLcall("glDisable(GL_FRAGMENT_SHADER_ATI)");
}
} }
/***************************************************************************** /*****************************************************************************
...@@ -941,22 +931,12 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU ...@@ -941,22 +931,12 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
else { else {
TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx); TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx);
if(GL_SUPPORT(ATI_FRAGMENT_SHADER)) { This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, FALSE);
/* Mesa crashes when enabling a context with GL_FRAGMENT_SHADER_ATI enabled.
* Thus we disable it before deactivating any context, and re-enable it afterwards.
*
* This bug is filed as bug #15269 on bugs.freedesktop.org
*/
glDisable(GL_FRAGMENT_SHADER_ATI);
checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
}
ret = pwglMakeCurrent(context->hdc, context->glCtx); ret = pwglMakeCurrent(context->hdc, context->glCtx);
if(ret == FALSE) { if(ret == FALSE) {
ERR("Failed to activate the new context\n"); ERR("Failed to activate the new context\n");
} else if(GL_SUPPORT(ATI_FRAGMENT_SHADER) && !context->last_was_blit) { } else if(!context->last_was_blit) {
glEnable(GL_FRAGMENT_SHADER_ATI); This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
} }
} }
if(This->activeContext->vshader_const_dirty) { if(This->activeContext->vshader_const_dirty) {
...@@ -988,13 +968,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU ...@@ -988,13 +968,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
case CTXUSAGE_CLEAR: case CTXUSAGE_CLEAR:
if(context->last_was_blit) { if(context->last_was_blit) {
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
glEnable(GL_TEXTURE_SHADER_NV);
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
} else if(GL_SUPPORT(ATI_FRAGMENT_SHADER)) {
glEnable(GL_FRAGMENT_SHADER_ATI);
checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
}
} }
/* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling /* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling
...@@ -1013,13 +987,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU ...@@ -1013,13 +987,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
case CTXUSAGE_DRAWPRIM: case CTXUSAGE_DRAWPRIM:
/* This needs all dirty states applied */ /* This needs all dirty states applied */
if(context->last_was_blit) { if(context->last_was_blit) {
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
glEnable(GL_TEXTURE_SHADER_NV);
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
} else if(GL_SUPPORT(ATI_FRAGMENT_SHADER)) {
glEnable(GL_FRAGMENT_SHADER_ATI);
checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
}
} }
IWineD3DDeviceImpl_FindTexUnitMap(This); IWineD3DDeviceImpl_FindTexUnitMap(This);
......
...@@ -3583,6 +3583,10 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_inf ...@@ -3583,6 +3583,10 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_inf
static void shader_glsl_load_init(void) {} static void shader_glsl_load_init(void) {}
static void shader_glsl_fragment_enable(IWineD3DDevice *iface, BOOL enable) {
none_shader_backend.shader_fragment_enable(iface, enable);
}
const shader_backend_t glsl_shader_backend = { const shader_backend_t glsl_shader_backend = {
&shader_glsl_select, &shader_glsl_select,
&shader_glsl_select_depth_blt, &shader_glsl_select_depth_blt,
...@@ -3598,5 +3602,6 @@ const shader_backend_t glsl_shader_backend = { ...@@ -3598,5 +3602,6 @@ const shader_backend_t glsl_shader_backend = {
&shader_glsl_generate_vshader, &shader_glsl_generate_vshader,
&shader_glsl_get_caps, &shader_glsl_get_caps,
&shader_glsl_load_init, &shader_glsl_load_init,
&shader_glsl_fragment_enable,
FFPStateTable FFPStateTable
}; };
...@@ -300,6 +300,7 @@ typedef struct { ...@@ -300,6 +300,7 @@ typedef struct {
void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer); void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer);
void (*shader_get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *caps); void (*shader_get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *caps);
void (*shader_dll_load_init)(void); void (*shader_dll_load_init)(void);
void (*shader_fragment_enable)(IWineD3DDevice *iface, BOOL enable);
const struct StateEntry *StateTable; const struct StateEntry *StateTable;
} shader_backend_t; } shader_backend_t;
......
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