[PATCH] WineD3D: Use less strict pixel format matching if the =
Stefan Doesinger
stefan at codeweavers.com
Mon Jul 21 09:22:22 CDT 2008
match fails=0A=
=0A=
Some drivers(the open source ones most notably) cannot satisfy=0A=
all possible D3D formats. This doesn't mean we should fall back=0A=
to the emergency fallback instantly. Instead, try to loosen the=0A=
requirements step by step.=0A=
=0A=
E.g. fglrx doesn't support aux buffers, like the open source=0A=
drivers, and the open source drivers only support 32 bit ARB=0A=
colors.=0A=
---=0A=
dlls/wined3d/context.c | 163 =
+++++++++++++++++++++++++++++-------------------=0A=
1 files changed, 98 insertions(+), 65 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c=0A=
index efa1006..ca81f3a 100644=0A=
--- a/dlls/wined3d/context.c=0A=
+++ b/dlls/wined3d/context.c=0A=
@@ -113,10 +113,28 @@ static WineD3DContext =
*AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand=0A=
/* This function takes care of WineD3D pixel format selection. */=0A=
static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, =
WINED3DFORMAT ColorFormat, WINED3DFORMAT DepthStencilFormat, BOOL =
auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible)=0A=
{=0A=
- int iPixelFormat=3D0;=0A=
+ int iPixelFormat=3D0, matchtry;=0A=
short redBits, greenBits, blueBits, alphaBits, colorBits;=0A=
short depthBits=3D0, stencilBits=3D0;=0A=
=0A=
+ struct match_type {=0A=
+ BOOL require_aux;=0A=
+ BOOL exact_alpha;=0A=
+ BOOL exact_color;=0A=
+ } matches[] =3D {=0A=
+ /* First, try without aux buffers - this is the most common =
cause=0A=
+ * for not finding a pixel format. Also some drivers(the open =
source ones)=0A=
+ * only offer 32 bit ARB pixel formats. First try without an =
exact alpha=0A=
+ * match, then try without an exact alpha and color match.=0A=
+ */=0A=
+ { TRUE, TRUE, TRUE },=0A=
+ { FALSE, TRUE, TRUE },=0A=
+ { TRUE, FALSE, TRUE },=0A=
+ { TRUE, FALSE, FALSE },=0A=
+ { FALSE, FALSE, TRUE },=0A=
+ { FALSE, FALSE, FALSE },=0A=
+ };=0A=
+=0A=
int i =3D 0;=0A=
int nCfgs =3D This->adapter->nCfgs;=0A=
WineD3D_PixelFormat *cfgs =3D This->adapter->cfgs;=0A=
@@ -149,70 +167,85 @@ static int =
WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DF=0A=
getDepthStencilBits(DepthStencilFormat, &depthBits, =
&stencilBits);=0A=
}=0A=
=0A=
- /* Find a pixel format which EXACTLY matches our requirements =
(except for depth) */=0A=
- for(i=3D0; i<nCfgs; i++) {=0A=
- BOOL exactDepthMatch =3D TRUE;=0A=
- cfgs =3D &This->adapter->cfgs[i];=0A=
-=0A=
- /* For now only accept RGBA formats. Perhaps some day we will=0A=
- * allow floating point formats for pbuffers. */=0A=
- if(cfgs->iPixelType !=3D WGL_TYPE_RGBA_ARB)=0A=
- continue;=0A=
-=0A=
- /* In window mode (!pbuffer) we need a window drawable format =
and double buffering. */=0A=
- if(!pbuffer && !(cfgs->windowDrawable && cfgs->doubleBuffer))=0A=
- continue;=0A=
-=0A=
- /* We like to have aux buffers in backbuffer mode */=0A=
- if(auxBuffers && !cfgs->auxBuffers)=0A=
- continue;=0A=
-=0A=
- /* In pbuffer-mode we need a pbuffer-capable format but we =
don't want double buffering */=0A=
- if(pbuffer && (!cfgs->pbufferDrawable || cfgs->doubleBuffer))=0A=
- continue;=0A=
-=0A=
- if(cfgs->redSize !=3D redBits)=0A=
- continue;=0A=
- if(cfgs->greenSize !=3D greenBits)=0A=
- continue;=0A=
- if(cfgs->blueSize !=3D blueBits)=0A=
- continue;=0A=
- if(cfgs->alphaSize !=3D alphaBits)=0A=
- continue;=0A=
-=0A=
- /* We try to locate a format which matches our requirements =
exactly. In case of=0A=
- * depth it is no problem to emulate 16-bit using e.g. 24-bit, =
so accept that. */=0A=
- if(cfgs->depthSize < depthBits)=0A=
- continue;=0A=
- else if(cfgs->depthSize > depthBits)=0A=
- exactDepthMatch =3D FALSE;=0A=
-=0A=
- /* In all cases make sure the number of stencil bits matches =
our requirements=0A=
- * even when we don't need stencil because it could affect =
performance EXCEPT=0A=
- * on cards which don't offer depth formats without stencil =
like the i915 drivers=0A=
- * on Linux. */=0A=
- if(stencilBits !=3D cfgs->stencilSize && =
!(This->adapter->brokenStencil && stencilBits <=3D cfgs->stencilSize))=0A=
- continue;=0A=
-=0A=
- /* Check multisampling support */=0A=
- if(cfgs->numSamples !=3D numSamples)=0A=
- continue;=0A=
-=0A=
- /* When we have passed all the checks then we have found a =
format which matches our=0A=
- * requirements. Note that we only check for a limit number of =
capabilities right now,=0A=
- * so there can easily be a dozen of pixel formats which appear =
to be the 'same' but=0A=
- * can still differ in things like multisampling, stereo, SRGB =
and other flags.=0A=
- */=0A=
+ for(matchtry =3D 0; matchtry < (sizeof(matches) / =
sizeof(matches[0])); matchtry++) {=0A=
+ for(i=3D0; i<nCfgs; i++) {=0A=
+ BOOL exactDepthMatch =3D TRUE;=0A=
+ cfgs =3D &This->adapter->cfgs[i];=0A=
+=0A=
+ /* For now only accept RGBA formats. Perhaps some day we =
will=0A=
+ * allow floating point formats for pbuffers. */=0A=
+ if(cfgs->iPixelType !=3D WGL_TYPE_RGBA_ARB)=0A=
+ continue;=0A=
+=0A=
+ /* In window mode (!pbuffer) we need a window drawable =
format and double buffering. */=0A=
+ if(!pbuffer && !(cfgs->windowDrawable && =
cfgs->doubleBuffer))=0A=
+ continue;=0A=
+=0A=
+ /* We like to have aux buffers in backbuffer mode */=0A=
+ if(auxBuffers && !cfgs->auxBuffers && =
matches[matchtry].require_aux)=0A=
+ continue;=0A=
+=0A=
+ /* In pbuffer-mode we need a pbuffer-capable format but we =
don't want double buffering */=0A=
+ if(pbuffer && (!cfgs->pbufferDrawable || =
cfgs->doubleBuffer))=0A=
+ continue;=0A=
+=0A=
+ if(matches[matchtry].exact_color) {=0A=
+ if(cfgs->redSize !=3D redBits)=0A=
+ continue;=0A=
+ if(cfgs->greenSize !=3D greenBits)=0A=
+ continue;=0A=
+ if(cfgs->blueSize !=3D blueBits)=0A=
+ continue;=0A=
+ } else {=0A=
+ if(cfgs->redSize < redBits)=0A=
+ continue;=0A=
+ if(cfgs->greenSize < greenBits)=0A=
+ continue;=0A=
+ if(cfgs->blueSize < blueBits)=0A=
+ continue;=0A=
+ }=0A=
+ if(matches[matchtry].exact_alpha) {=0A=
+ if(cfgs->alphaSize !=3D alphaBits)=0A=
+ continue;=0A=
+ } else {=0A=
+ if(cfgs->alphaSize < alphaBits)=0A=
+ continue;=0A=
+ }=0A=
=0A=
- /* Exit the loop as we have found a format :) */=0A=
- if(exactDepthMatch) {=0A=
- iPixelFormat =3D cfgs->iPixelFormat;=0A=
- break;=0A=
- } else if(!iPixelFormat) {=0A=
- /* In the end we might end up with a format which doesn't =
exactly match our depth=0A=
- * requirements. Accept the first format we found because =
formats with higher iPixelFormat=0A=
- * values tend to have more extended capabilities (e.g. =
multisampling) which we don't need. */=0A=
- iPixelFormat =3D cfgs->iPixelFormat;=0A=
+ /* We try to locate a format which matches our requirements =
exactly. In case of=0A=
+ * depth it is no problem to emulate 16-bit using e.g. =
24-bit, so accept that. */=0A=
+ if(cfgs->depthSize < depthBits)=0A=
+ continue;=0A=
+ else if(cfgs->depthSize > depthBits)=0A=
+ exactDepthMatch =3D FALSE;=0A=
+=0A=
+ /* In all cases make sure the number of stencil bits =
matches our requirements=0A=
+ * even when we don't need stencil because it could affect =
performance EXCEPT=0A=
+ * on cards which don't offer depth formats without stencil =
like the i915 drivers=0A=
+ * on Linux. */=0A=
+ if(stencilBits !=3D cfgs->stencilSize && =
!(This->adapter->brokenStencil && stencilBits <=3D cfgs->stencilSize))=0A=
+ continue;=0A=
+=0A=
+ /* Check multisampling support */=0A=
+ if(cfgs->numSamples !=3D numSamples)=0A=
+ continue;=0A=
+=0A=
+ /* When we have passed all the checks then we have found a =
format which matches our=0A=
+ * requirements. Note that we only check for a limit number =
of capabilities right now,=0A=
+ * so there can easily be a dozen of pixel formats which =
appear to be the 'same' but=0A=
+ * can still differ in things like multisampling, stereo, =
SRGB and other flags.=0A=
+ */=0A=
+=0A=
+ /* Exit the loop as we have found a format :) */=0A=
+ if(exactDepthMatch) {=0A=
+ iPixelFormat =3D cfgs->iPixelFormat;=0A=
+ break;=0A=
+ } else if(!iPixelFormat) {=0A=
+ /* In the end we might end up with a format which =
doesn't exactly match our depth=0A=
+ * requirements. Accept the first format we found =
because formats with higher iPixelFormat=0A=
+ * values tend to have more extended capabilities (e.g. =
multisampling) which we don't need. */=0A=
+ iPixelFormat =3D cfgs->iPixelFormat;=0A=
+ }=0A=
}=0A=
}=0A=
=0A=
-- =0A=
1.5.4.5=0A=
=0A=
------=_NextPart_000_0015_01C8EB1E.F61337E0--
More information about the wine-patches
mailing list