Roderick Colenbrander : wined3d: Let WineD3D_ChoosePixelFormat operate on the pixel format database we store at WineD3D startup .

Alexandre Julliard julliard at winehq.org
Mon Apr 28 08:01:00 CDT 2008


Module: wine
Branch: master
Commit: a38e5a95efb28757de812b68359c23a9125d1310
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a38e5a95efb28757de812b68359c23a9125d1310

Author: Roderick Colenbrander <thunderbird2k at gmx.net>
Date:   Sun Apr 27 17:42:48 2008 +0000

wined3d: Let WineD3D_ChoosePixelFormat operate on the pixel format database we store at WineD3D startup.

---

 dlls/wined3d/context.c |  111 ++++++++++++++++++++++++++++++------------------
 1 files changed, 69 insertions(+), 42 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 79ea74c..901a36c 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -113,65 +113,91 @@ 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, BOOL pbuffer, BOOL findCompatible)
 {
-    int iPixelFormat = 0;
-    int attribs[256];
-    int nAttribs = 0;
-    unsigned int nFormats;
+    int iPixelFormat=0;
     short redBits, greenBits, blueBits, alphaBits, colorBits;
     short depthBits=0, stencilBits=0;
-    BOOL result = FALSE;
 
-#define PUSH1(att)        attribs[nAttribs++] = (att);
-#define PUSH2(att,value)  attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
+    int i = 0;
+    int nCfgs = This->adapter->nCfgs;
+    WineD3D_PixelFormat *cfgs = This->adapter->cfgs;
 
-    if(getColorBits(ColorFormat, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits)) {
-        PUSH2(WGL_COLOR_BITS_ARB, colorBits);
-        PUSH2(WGL_RED_BITS_ARB, redBits);
-        PUSH2(WGL_GREEN_BITS_ARB, greenBits);
-        PUSH2(WGL_BLUE_BITS_ARB, blueBits);
-        PUSH2(WGL_ALPHA_BITS_ARB, alphaBits);
-    } else {
+    if(!getColorBits(ColorFormat, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits)) {
         ERR("Unable to get color bits for format %s (%#x)!\n", debug_d3dformat(ColorFormat), ColorFormat);
         return 0;
     }
 
-    /* Request depth/stencil when we need it */
-    if(DepthStencilFormat && getDepthStencilBits(DepthStencilFormat, &depthBits, &stencilBits)) {
-        PUSH2(WGL_DEPTH_BITS_ARB, depthBits);
-        PUSH2(WGL_STENCIL_BITS_ARB, stencilBits);
+    if(DepthStencilFormat) {
+        getDepthStencilBits(DepthStencilFormat, &depthBits, &stencilBits);
     }
 
-    PUSH2(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); /* Make sure we don't get a float or color index format */
-    PUSH2(WGL_SUPPORT_OPENGL_ARB, GL_TRUE);
-    PUSH2(WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB); /* Make sure we receive an accelerated format. On windows (at least on ATI) this is not always the case */
-
-    if(auxBuffers) {
-        TRACE("Requesting 2 aux buffers\n");
-        /* We like to have two aux buffers in backbuffer mode */
-        PUSH2(WGL_AUX_BUFFERS_ARB, 2);
+    /* Find a pixel format which EXACTLY matches our requirements (except for depth) */
+    for(i=0; i<nCfgs; i++) {
+        BOOL exactDepthMatch = TRUE;
+
+        /* For now only accept RGBA formats. Perhaps some day we will
+         * allow floating point formats for pbuffers. */
+        if(cfgs->iPixelType != WGL_TYPE_RGBA_ARB)
+            continue;
+
+        /* In all cases except when we are in pbuffer-mode we need a window drawable format with double buffering. */
+        if(!pbuffer && !cfgs->windowDrawable && !cfgs->doubleBuffer)
+            continue;
+
+        /* We like to have aux buffers in backbuffer mode */
+        if(auxBuffers && !cfgs->auxBuffers)
+            continue;
+
+        /* In pbuffer-mode we need a pbuffer-capable format */
+        if(pbuffer && !cfgs->pbufferDrawable)
+            continue;
+
+        if(cfgs->redSize != redBits)
+            continue;
+        if(cfgs->greenSize != greenBits)
+            continue;
+        if(cfgs->blueSize != blueBits)
+            continue;
+        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. */
+        if(cfgs->depthSize < depthBits)
+            continue;
+        else if(cfgs->depthSize > depthBits)
+            exactDepthMatch = FALSE;
+
+        /* In all cases make sure the number of stencil bits matches our requirements
+         * even when we don't need stencil because it could affect performance */
+        if(!(cfgs->stencilSize == stencilBits))
+            continue;
+
+        /* When we have passed all the checks then we have found a format which matches our
+         * requirements. Note that we only check for a limit number of capabilities right now,
+         * so there can easily be a dozen of pixel formats which appear to be the 'same' but
+         * can still differ in things like multisampling, stereo, SRGB and other flags.
+         */
 
-        PUSH2(WGL_DRAW_TO_WINDOW_ARB, GL_TRUE); /* We want to draw to a window */
-        PUSH2(WGL_DOUBLE_BUFFER_ARB, GL_TRUE);
-    } else if(pbuffer) {
-        PUSH2(WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE); /* We need pbuffer support; doublebuffering isn't needed */
-    } else {
-        PUSH2(WGL_DRAW_TO_WINDOW_ARB, GL_TRUE); /* We want to draw to a window */
-        PUSH2(WGL_DOUBLE_BUFFER_ARB, GL_TRUE);
+        /* Exit the loop as we have found a format :) */
+        if(exactDepthMatch) {
+            iPixelFormat = cfgs->iPixelFormat;
+            break;
+        } else if(!iPixelFormat) {
+            /* In the end we might end up with a format which doesn't exactly match our depth
+             * requirements. Accept the first format we found because formats with higher iPixelFormat
+             * values tend to have more extended capabilities (e.g. multisampling) which we don't need. */
+            iPixelFormat = cfgs->iPixelFormat;
+        }
     }
 
-    PUSH1(0); /* end the list */
-
-#undef PUSH1
-#undef PUSH2
-
-    result = GL_EXTCALL(wglChoosePixelFormatARB(hdc, (const int*)&attribs, NULL, 1, &iPixelFormat, &nFormats));
-    if(!result && !findCompatible) {
+    /* When findCompatible is set and no suitable format was found, let ChoosePixelFormat choose a pixel format in order not to crash. */
+    if(!iPixelFormat && !findCompatible) {
         ERR("Can't find a suitable iPixelFormat\n");
         return FALSE;
     } else {
         PIXELFORMATDESCRIPTOR pfd;
 
-        TRACE("Falling back to ChoosePixelFormat as wglChoosePixelFormatARB failed\n");
+        TRACE("Falling back to ChoosePixelFormat as we weren't able to find an exactly matching pixel format\n");
         /* PixelFormat selection */
         ZeroMemory(&pfd, sizeof(pfd));
         pfd.nSize      = sizeof(pfd);
@@ -192,6 +218,7 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DF
         }
     }
 
+    TRACE("Found iPixelFormat=%d for ColorFormat=%s, DepthStencilFormat=%s\n", cfgs->iPixelFormat, debug_d3dformat(ColorFormat), debug_d3dformat(DepthStencilFormat));
     return iPixelFormat;
 }
 




More information about the wine-cvs mailing list