wined3d: Use less strict pixel format matching if the match fails.
Some drivers(the open source ones most notably) cannot satisfy all possible D3D formats. This doesn't mean we should fall back to the emergency fallback instantly. Instead, try to loosen the requirements step by step.
This commit is contained in:
parent
80fe2faeb6
commit
1219e3d4a7
|
@ -113,10 +113,28 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand
|
|||
/* This function takes care of WineD3D pixel format selection. */
|
||||
static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DFORMAT ColorFormat, WINED3DFORMAT DepthStencilFormat, BOOL auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible)
|
||||
{
|
||||
int iPixelFormat=0;
|
||||
int iPixelFormat=0, matchtry;
|
||||
short redBits, greenBits, blueBits, alphaBits, colorBits;
|
||||
short depthBits=0, stencilBits=0;
|
||||
|
||||
struct match_type {
|
||||
BOOL require_aux;
|
||||
BOOL exact_alpha;
|
||||
BOOL exact_color;
|
||||
} matches[] = {
|
||||
/* First, try without aux buffers - this is the most common cause
|
||||
* for not finding a pixel format. Also some drivers(the open source ones)
|
||||
* only offer 32 bit ARB pixel formats. First try without an exact alpha
|
||||
* match, then try without an exact alpha and color match.
|
||||
*/
|
||||
{ TRUE, TRUE, TRUE },
|
||||
{ FALSE, TRUE, TRUE },
|
||||
{ TRUE, FALSE, TRUE },
|
||||
{ TRUE, FALSE, FALSE },
|
||||
{ FALSE, FALSE, TRUE },
|
||||
{ FALSE, FALSE, FALSE },
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
int nCfgs = This->adapter->nCfgs;
|
||||
WineD3D_PixelFormat *cfgs = This->adapter->cfgs;
|
||||
|
@ -149,7 +167,7 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DF
|
|||
getDepthStencilBits(DepthStencilFormat, &depthBits, &stencilBits);
|
||||
}
|
||||
|
||||
/* Find a pixel format which EXACTLY matches our requirements (except for depth) */
|
||||
for(matchtry = 0; matchtry < (sizeof(matches) / sizeof(matches[0])); matchtry++) {
|
||||
for(i=0; i<nCfgs; i++) {
|
||||
BOOL exactDepthMatch = TRUE;
|
||||
cfgs = &This->adapter->cfgs[i];
|
||||
|
@ -164,21 +182,35 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DF
|
|||
continue;
|
||||
|
||||
/* We like to have aux buffers in backbuffer mode */
|
||||
if(auxBuffers && !cfgs->auxBuffers)
|
||||
if(auxBuffers && !cfgs->auxBuffers && matches[matchtry].require_aux)
|
||||
continue;
|
||||
|
||||
/* In pbuffer-mode we need a pbuffer-capable format but we don't want double buffering */
|
||||
if(pbuffer && (!cfgs->pbufferDrawable || cfgs->doubleBuffer))
|
||||
continue;
|
||||
|
||||
if(matches[matchtry].exact_color) {
|
||||
if(cfgs->redSize != redBits)
|
||||
continue;
|
||||
if(cfgs->greenSize != greenBits)
|
||||
continue;
|
||||
if(cfgs->blueSize != blueBits)
|
||||
continue;
|
||||
} else {
|
||||
if(cfgs->redSize < redBits)
|
||||
continue;
|
||||
if(cfgs->greenSize < greenBits)
|
||||
continue;
|
||||
if(cfgs->blueSize < blueBits)
|
||||
continue;
|
||||
}
|
||||
if(matches[matchtry].exact_alpha) {
|
||||
if(cfgs->alphaSize != alphaBits)
|
||||
continue;
|
||||
} else {
|
||||
if(cfgs->alphaSize < alphaBits)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We try to locate a format which matches our requirements exactly. In case of
|
||||
* depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */
|
||||
|
@ -215,6 +247,7 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DF
|
|||
iPixelFormat = cfgs->iPixelFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* When findCompatible is set and no suitable format was found, let ChoosePixelFormat choose a pixel format in order not to crash. */
|
||||
if(!iPixelFormat && !findCompatible) {
|
||||
|
|
Loading…
Reference in New Issue