wined3d: Work around a bad crash in fglrx.
This commit is contained in:
parent
4daa3e5320
commit
668328a697
|
@ -895,13 +895,11 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GL_SUPPORT(ARB_POINT_SPRITE)) {
|
for(s = 0; s < GL_LIMITS(point_sprite_units); s++) {
|
||||||
for(s = 0; s < GL_LIMITS(textures); s++) {
|
|
||||||
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
|
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
|
||||||
glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
|
glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
|
||||||
checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
|
checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
||||||
/* Never keep GL_FRAGMENT_SHADER_ATI enabled on a context that we switch away from,
|
/* Never keep GL_FRAGMENT_SHADER_ATI enabled on a context that we switch away from,
|
||||||
|
|
|
@ -1014,7 +1014,11 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
|
||||||
/* GL_ARB_half_float_vertex is a subset of GL_NV_half_float */
|
/* GL_ARB_half_float_vertex is a subset of GL_NV_half_float */
|
||||||
gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
|
gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
|
||||||
}
|
}
|
||||||
|
if(gl_info->supported[ARB_POINT_SPRITE]) {
|
||||||
|
gl_info->max_point_sprite_units = gl_info->max_textures;
|
||||||
|
} else {
|
||||||
|
gl_info->max_point_sprite_units = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
checkGLcall("extension detection\n");
|
checkGLcall("extension detection\n");
|
||||||
|
|
||||||
|
@ -4031,6 +4035,13 @@ static BOOL match_apple_nonr500ati(const WineD3D_GL_Info *gl_info) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL match_fglrx(const WineD3D_GL_Info *gl_info) {
|
||||||
|
if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
|
||||||
|
if(match_apple(gl_info)) return FALSE;
|
||||||
|
if(strstr(gl_info->gl_renderer, "DRI")) return FALSE; /* Filter out Mesa DRI drivers */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void quirk_arb_constants(WineD3D_GL_Info *gl_info) {
|
static void quirk_arb_constants(WineD3D_GL_Info *gl_info) {
|
||||||
TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL\n", gl_info->vs_arb_constantsF);
|
TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL\n", gl_info->vs_arb_constantsF);
|
||||||
gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
|
gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
|
||||||
|
@ -4048,6 +4059,26 @@ static void quirk_apple_glsl_constants(WineD3D_GL_Info *gl_info) {
|
||||||
gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
|
gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
|
||||||
|
* on more than one texture unit. This means that the d3d9 visual point size test will cause a
|
||||||
|
* kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
|
||||||
|
* quirk only enables point sprites on the first texture unit. This keeps point sprites working in
|
||||||
|
* most games, but avoids the crash
|
||||||
|
*
|
||||||
|
* A more sophisticated way would be to find all units that need texture coordinates and enable
|
||||||
|
* point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
|
||||||
|
* if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
|
||||||
|
*
|
||||||
|
* Note that disabling the extension entirely does not gain predictability because there is no point
|
||||||
|
* sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension.
|
||||||
|
*/
|
||||||
|
static void quirk_one_point_sprite(WineD3D_GL_Info *gl_info) {
|
||||||
|
if(gl_info->supported[ARB_POINT_SPRITE]) {
|
||||||
|
TRACE("Limiting point sprites to one texture unit\n");
|
||||||
|
gl_info->max_point_sprite_units = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void quirk_ati_dx9(WineD3D_GL_Info *gl_info) {
|
static void quirk_ati_dx9(WineD3D_GL_Info *gl_info) {
|
||||||
quirk_arb_constants(gl_info);
|
quirk_arb_constants(gl_info);
|
||||||
|
|
||||||
|
@ -4146,6 +4177,11 @@ struct driver_quirk quirk_table[] = {
|
||||||
match_apple_nonr500ati,
|
match_apple_nonr500ati,
|
||||||
quirk_texcoord_w,
|
quirk_texcoord_w,
|
||||||
"Init texcoord .w for Apple ATI >= r600 GPU driver"
|
"Init texcoord .w for Apple ATI >= r600 GPU driver"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match_fglrx,
|
||||||
|
quirk_one_point_sprite,
|
||||||
|
"Fglrx point sprite crash workaround"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1503,14 +1503,25 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
|
||||||
}
|
}
|
||||||
|
|
||||||
static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||||
|
BOOL warned = FALSE;
|
||||||
/* TODO: NV_POINT_SPRITE */
|
/* TODO: NV_POINT_SPRITE */
|
||||||
if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
|
if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
|
||||||
TRACE("Point sprites not supported\n");
|
/* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
|
||||||
|
FIXME("Point sprites not supported\n");
|
||||||
|
warned = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
|
||||||
if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
|
if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
|
||||||
|
BOOL warned = FALSE;
|
||||||
|
if(GL_LIMITS(point_sprite_units) < GL_LIMITS(textures) && !warned) {
|
||||||
|
if(use_ps(stateblock) || stateblock->lowest_disabled_stage > GL_LIMITS(point_sprite_units)) {
|
||||||
|
FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n");
|
||||||
|
warned = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glEnable(GL_POINT_SPRITE_ARB);
|
glEnable(GL_POINT_SPRITE_ARB);
|
||||||
checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
|
checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3933,6 +3933,7 @@ typedef struct _WineD3D_GL_Info {
|
||||||
UINT max_texture_size;
|
UINT max_texture_size;
|
||||||
UINT max_texture3d_size;
|
UINT max_texture3d_size;
|
||||||
float max_pointsize, max_pointsizemin;
|
float max_pointsize, max_pointsizemin;
|
||||||
|
UINT max_point_sprite_units;
|
||||||
UINT max_blends;
|
UINT max_blends;
|
||||||
UINT max_anisotropy;
|
UINT max_anisotropy;
|
||||||
UINT max_glsl_varyings;
|
UINT max_glsl_varyings;
|
||||||
|
|
Loading…
Reference in New Issue