ddraw: Fix filtering of enumerated display modes by bits per pixel

Ričardas Barkauskas miegalius at gmail.com
Sat Apr 30 12:24:01 CDT 2011


Lets have less error mesages on 3dmark99 failure to start

Ričardas Barkauskas
REalm
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20110430/e8ac018b/attachment.htm>
-------------- next part --------------
From c30e802b418cba825335a69446877359c69dd34b Mon Sep 17 00:00:00 2001
From: Ricardas Barkauskas <realm at REalm-debian64.realm.lt>
Date: Sat, 30 Apr 2011 20:07:11 +0300
Subject: ddraw: Fix filtering of enumerated display modes by bits per pixel

---
 dlls/ddraw/ddraw.c            |   19 ++----
 dlls/ddraw/tests/ddrawmodes.c |  136 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+), 13 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 9b87b95..2ade4cd 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2085,11 +2085,11 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
 {
     IDirectDrawImpl *This = impl_from_IDirectDraw7(iface);
     unsigned int modenum, fmt;
-    enum wined3d_format_id pixelformat = WINED3DFMT_UNKNOWN;
     WINED3DDISPLAYMODE mode;
     DDSURFACEDESC2 callback_sd;
     WINED3DDISPLAYMODE *enum_modes = NULL;
     unsigned enum_mode_count = 0, enum_mode_array_size = 0;
+    DDPIXELFORMAT pixelformat;
 
     static const enum wined3d_format_id checkFormatList[] =
     {
@@ -2109,12 +2109,6 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
         return DDERR_INVALIDPARAMS;
     }
 
-    if(DDSD)
-    {
-        if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) )
-            pixelformat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
-    }
-
     if(!(Flags & DDEDM_REFRESHRATES))
     {
         enum_mode_array_size = 16;
@@ -2127,21 +2121,20 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
         }
     }
 
+    pixelformat.dwSize = sizeof(pixelformat);
     for(fmt = 0; fmt < (sizeof(checkFormatList) / sizeof(checkFormatList[0])); fmt++)
     {
-        if(pixelformat != WINED3DFMT_UNKNOWN && checkFormatList[fmt] != pixelformat)
-        {
-            continue;
-        }
-
         modenum = 0;
         while (wined3d_enum_adapter_modes(This->wineD3D, WINED3DADAPTER_DEFAULT,
                 checkFormatList[fmt], modenum++, &mode) == WINED3D_OK)
         {
+            PixelFormat_WineD3DtoDD(&pixelformat, mode.Format);
             if(DDSD)
             {
                 if(DDSD->dwFlags & DDSD_WIDTH && mode.Width != DDSD->dwWidth) continue;
                 if(DDSD->dwFlags & DDSD_HEIGHT && mode.Height != DDSD->dwHeight) continue;
+                if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) )
+                    if(pixelformat.u1.dwRGBBitCount != DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount) continue;
             }
 
             if(!(Flags & DDEDM_REFRESHRATES))
@@ -2180,7 +2173,7 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
             callback_sd.dwWidth = mode.Width;
             callback_sd.dwHeight = mode.Height;
 
-            PixelFormat_WineD3DtoDD(&callback_sd.u4.ddpfPixelFormat, mode.Format);
+            callback_sd.u4.ddpfPixelFormat=pixelformat;
 
             /* Calc pitch and DWORD align like MSDN says */
             callback_sd.u1.lPitch = (callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount / 8) * mode.Width;
diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c
index a103d65..688e46d 100644
--- a/dlls/ddraw/tests/ddrawmodes.c
+++ b/dlls/ddraw/tests/ddrawmodes.c
@@ -26,6 +26,7 @@
  */
 
 #include <assert.h>
+#include <stdio.h>
 #include "wine/test.h"
 #include "ddraw.h"
 
@@ -342,12 +343,113 @@ static void flushdisplaymodes(void)
     modes_cnt = modes_size = 0;
 }
 
+typedef struct
+{
+    DWORD val;
+    const char* name;
+} flag_info;
+
+#define FE(x) { x, #x }
+
+static void dump_pixelformat_flag(DWORD flagmask)
+{
+    static const flag_info flags[] =
+        {
+            FE(DDPF_ALPHAPIXELS),
+            FE(DDPF_ALPHA),
+            FE(DDPF_FOURCC),
+            FE(DDPF_PALETTEINDEXED4),
+            FE(DDPF_PALETTEINDEXEDTO8),
+            FE(DDPF_PALETTEINDEXED8),
+            FE(DDPF_RGB),
+            FE(DDPF_COMPRESSED),
+            FE(DDPF_RGBTOYUV),
+            FE(DDPF_YUV),
+            FE(DDPF_ZBUFFER),
+            FE(DDPF_PALETTEINDEXED1),
+            FE(DDPF_PALETTEINDEXED2),
+            FE(DDPF_ZPIXELS)
+    };
+
+    unsigned int i;
+
+    for (i=0; i < sizeof(flags)/sizeof(flags[0]); i++)
+        if ((flagmask & flags[i].val) ||      /* standard flag value */
+                ((!flagmask) && (!flags[i].val))) /* zero value only */
+            printf("%s ", flags[i].name);
+    printf("(%x) ", flagmask);
+}
+
+static void dump_pixelformat(const DDPIXELFORMAT *pf)
+{
+    printf("( ");
+    dump_pixelformat_flag(pf->dwFlags);
+    if (pf->dwFlags & DDPF_FOURCC)
+    {
+        printf(", dwFourCC code '%c%c%c%c' (0x%08x) - %d bits per pixel",
+                (unsigned char)( pf->dwFourCC     &0xff),
+                (unsigned char)((pf->dwFourCC>> 8)&0xff),
+                (unsigned char)((pf->dwFourCC>>16)&0xff),
+                (unsigned char)((pf->dwFourCC>>24)&0xff),
+                pf->dwFourCC,
+                U1(*pf).dwYUVBitCount
+        );
+    }
+    if (pf->dwFlags & DDPF_RGB)
+    {
+        const char *cmd;
+        printf(", RGB bits: %d, ", U1(*pf).dwRGBBitCount);
+        switch (U1(*pf).dwRGBBitCount)
+        {
+        case 4: cmd = "%1lx"; break;
+        case 8: cmd = "%02lx"; break;
+        case 16: cmd = "%04lx"; break;
+        case 24: cmd = "%06lx"; break;
+        case 32: cmd = "%08lx"; break;
+        default: printf("Unexpected bit depth !\n"); cmd = "%d"; break;
+        }
+        printf(" R "); printf(cmd, U2(*pf).dwRBitMask);
+        printf(" G "); printf(cmd, U3(*pf).dwGBitMask);
+        printf(" B "); printf(cmd, U4(*pf).dwBBitMask);
+        if (pf->dwFlags & DDPF_ALPHAPIXELS)
+        {
+            printf(" A "); printf(cmd, U5(*pf).dwRGBAlphaBitMask);
+        }
+        if (pf->dwFlags & DDPF_ZPIXELS)
+        {
+            printf(" Z "); printf(cmd, U5(*pf).dwRGBZBitMask);
+        }
+    }
+    if (pf->dwFlags & DDPF_ZBUFFER)
+    {
+        printf(", Z bits : %d", U5(*pf).dwZBufferBitDepth);
+    }
+    if (pf->dwFlags & DDPF_ALPHA)
+    {
+        printf(", Alpha bits : %d", U5(*pf).dwAlphaBitDepth);
+    }
+    if (pf->dwFlags & DDPF_BUMPDUDV)
+    {
+        const char *cmd = "%08lx";
+        printf(", Bump bits: %d, ", U1(*pf).dwBumpBitCount);
+        printf(" U "); printf(cmd, U2(*pf).dwBumpDuBitMask);
+        printf(" V "); printf(cmd, U3(*pf).dwBumpDvBitMask);
+        printf(" L "); printf(cmd, U4(*pf).dwBumpLuminanceBitMask);
+    }
+    printf(")\n");
+}
+
 static HRESULT WINAPI enummodescallback(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
 {
     trace("Width = %i, Height = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
         lpddsd->dwWidth, lpddsd->dwHeight,
           U2(*lpddsd).dwRefreshRate, U1(*lpddsd).lPitch, lpddsd->dwFlags);
 
+    if(lpddsd->dwFlags & DDSD_PIXELFORMAT)
+     {
+        dump_pixelformat(&lpddsd->ddpfPixelFormat);
+     }
+
     /* Check that the pitch is valid if applicable */
     if(lpddsd->dwFlags & DDSD_PITCH)
     {
@@ -369,6 +471,28 @@ static HRESULT WINAPI enummodescallback(LPDDSURFACEDESC lpddsd, LPVOID lpContext
     return DDENUMRET_OK;
 }
 
+static HRESULT WINAPI enummodescallback_16bit(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
+{
+    trace("Width = %i, Height = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
+        lpddsd->dwWidth, lpddsd->dwHeight,
+          U2(*lpddsd).dwRefreshRate, U1(*lpddsd).lPitch, lpddsd->dwFlags);
+
+    ok(lpddsd->dwFlags & DDSD_PIXELFORMAT, "Pixel format must be described");
+    ok(lpddsd->ddpfPixelFormat.dwRGBBitCount == 16, "Mode filtering doesn't work\n");
+    if(lpddsd->dwFlags & DDSD_PIXELFORMAT)
+    {
+        dump_pixelformat(&lpddsd->ddpfPixelFormat);
+    }
+
+    /* Check that the pitch is valid if applicable */
+    if(lpddsd->dwFlags & DDSD_PITCH)
+    {
+        ok(U1(*lpddsd).lPitch != 0, "EnumDisplayModes callback with bad pitch\n");
+    }
+
+    return DDENUMRET_OK;
+}
+
 static void enumdisplaymodes(void)
 {
     DDSURFACEDESC ddsd;
@@ -382,6 +506,18 @@ static void enumdisplaymodes(void)
     rc = IDirectDraw_EnumDisplayModes(lpDD,
         DDEDM_STANDARDVGAMODES, &ddsd, 0, enummodescallback);
     ok(rc==DD_OK || rc==E_INVALIDARG,"EnumDisplayModes returned: %x\n",rc);
+
+    ddsd.dwFlags ^= DDSD_PIXELFORMAT;
+    ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+    ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+    ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
+    ddsd.ddpfPixelFormat.dwRBitMask = 0x7C00;
+    ddsd.ddpfPixelFormat.dwGBitMask = 0x03E0;
+    ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
+
+    rc = IDirectDraw_EnumDisplayModes(lpDD,
+            DDEDM_STANDARDVGAMODES, &ddsd, 0, enummodescallback_16bit);
+    ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
 }
 
 static void setdisplaymode(int i)
-- 
1.7.4.4


More information about the wine-patches mailing list