[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