[PATCH 4/5] ddraw: Accept all 3 versions of D3DFINDDEVICERESULT

Andrew D'Addesio andrew at fatbag.net
Sun Oct 4 12:52:07 CDT 2015


Fixes Carmageddon 2 demo launcher
---
 dlls/ddraw/ddraw.c     | 29 +++++++++++++++++++++++----
 dlls/ddraw/tests/d3d.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++----
 include/d3dcaps.h      |  2 ++
 3 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index c94bfee..7b5b593 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -30,6 +30,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
 
 static const struct ddraw *exclusive_ddraw;
 
+/* Size of D3DDEVICEDESC in Direct3D 1-3 */
+enum {
+    D3D1_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth), /* 172 */
+    D3D2_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat), /* 204 */
+    D3D3_DESC_SIZE = sizeof(D3DDEVICEDESC) /* 252 */
+};
+
 /* Device identifier. Don't relay it to WineD3D */
 static const DDDEVICEIDENTIFIER2 deviceidentifier =
 {
@@ -3969,6 +3976,9 @@ static HRESULT WINAPI d3d1_CreateViewport(IDirect3D *iface, IDirect3DViewport **
 static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr)
 {
     struct ddraw *ddraw = impl_from_IDirect3D3(iface);
+    const DWORD hwdesc_offset = FIELD_OFFSET(D3DFINDDEVICERESULT, ddHwDesc);
+    DWORD desc_size;
+    BYTE *desc_ptr;
     D3DDEVICEDESC7 desc7;
     D3DDEVICEDESC desc1;
     HRESULT hr;
@@ -3977,10 +3987,13 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd
 
     if (!fds || !fdr) return DDERR_INVALIDPARAMS;
 
-    if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH)
-            || fdr->dwSize != sizeof(D3DFINDDEVICERESULT))
+    if (fdr->dwSize != hwdesc_offset + 2*D3D1_DESC_SIZE
+        && fdr->dwSize != hwdesc_offset + 2*D3D2_DESC_SIZE
+        && fdr->dwSize != hwdesc_offset + 2*D3D3_DESC_SIZE)
         return DDERR_INVALIDPARAMS;
 
+    desc_size = (fdr->dwSize - hwdesc_offset)/2;
+
     if ((fds->dwFlags & D3DFDS_COLORMODEL)
             && fds->dcmColorModel != D3DCOLOR_RGB)
     {
@@ -4007,8 +4020,16 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd
     /* Now return our own GUID */
     ddraw_d3dcaps1_from_7(&desc1, &desc7);
     fdr->guid = IID_D3DDEVICE_WineD3D;
-    fdr->ddHwDesc = desc1;
-    fdr->ddSwDesc = desc1;
+
+    /* Write ddHwDesc */
+    desc_ptr = (BYTE*)&fdr->ddHwDesc;
+    memcpy(desc_ptr, &desc1, desc_size);
+    ((D3DDEVICEDESC*)desc_ptr)->dwSize = desc_size;
+
+    /* Write ddSwDesc */
+    desc_ptr += desc_size;
+    memcpy(desc_ptr, &desc1, desc_size);
+    ((D3DDEVICEDESC*)desc_ptr)->dwSize = desc_size;
 
     TRACE("Returning Wine's wined3d device with (undumped) capabilities.\n");
 
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c
index df6b3cf..392c13f 100644
--- a/dlls/ddraw/tests/d3d.c
+++ b/dlls/ddraw/tests/d3d.c
@@ -63,6 +63,13 @@ struct d3d2_test_context
     IDirect3DViewport2 *viewport;
 };
 
+/* Size of D3DDEVICEDESC in Direct3D 1-3 */
+enum {
+    D3D1_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth), /* 172 */
+    D3D2_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat), /* 204 */
+    D3D3_DESC_SIZE = sizeof(D3DDEVICEDESC) /* 252 */
+};
+
 typedef struct {
     int total;
     int rgb;
@@ -3223,8 +3230,27 @@ static void VertexBufferLockRest(void)
     IDirect3DVertexBuffer7_Release(buffer);
 }
 
+static void clear_device_result(D3DFINDDEVICERESULT *result, DWORD hwsize, DWORD swsize)
+{
+    BYTE *desc_ptr;
+
+    memset(result, 0, sizeof(*result));
+
+    result->dwSize = FIELD_OFFSET(D3DFINDDEVICERESULT, ddHwDesc) + hwsize + swsize;
+
+    /* Write ddHwDesc.dwSize */
+    desc_ptr = (BYTE*)&result->ddHwDesc;
+    ((D3DDEVICEDESC*)desc_ptr)->dwSize = hwsize;
+
+    /* Write ddSwDesc.dwSize */
+    desc_ptr += hwsize;
+    ((D3DDEVICEDESC*)desc_ptr)->dwSize = swsize;
+}
+
 static void FindDevice(void)
 {
+    static const DWORD desc_sizes[] = {D3D1_DESC_SIZE, D3D2_DESC_SIZE, D3D3_DESC_SIZE};
+
     static const struct
     {
         const GUID *guid;
@@ -3273,14 +3299,33 @@ static void FindDevice(void)
     ok(hr == DDERR_INVALIDPARAMS,
        "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
 
-    /* Specifying no flags is permitted. */
+    /* FindDevice should succeed for the 3 versions of D3DDEVICEDESC (D3D 1-3) */
+    for (i = 0; i < sizeof(desc_sizes)/sizeof(desc_sizes[0]); i++)
+    {
+        /* Specifying no flags is permitted. */
+        search.dwSize = sizeof(search);
+        search.dwFlags = 0;
+        clear_device_result(&result, desc_sizes[i], desc_sizes[i]);
+        hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
+        ok(hr == D3D_OK,
+            "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
+    }
+
+    /* Non-matching D3DDEVICEDESC sizes should fail */
     search.dwSize = sizeof(search);
     search.dwFlags = 0;
-    result.dwSize = sizeof(result);
+    clear_device_result(&result, D3D1_DESC_SIZE, D3D2_DESC_SIZE);
+    hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
+    ok(hr == DDERR_INVALIDPARAMS,
+       "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
 
+    /* Invalid D3DDEVICEDESC sizes should fail */
+    search.dwSize = sizeof(search);
+    search.dwFlags = 0;
+    clear_device_result(&result, (D3D1_DESC_SIZE-4), (D3D1_DESC_SIZE-4));
     hr = IDirect3D_FindDevice(Direct3D1, &search, &result);
-    ok(hr == D3D_OK,
-       "Expected IDirect3D1::FindDevice to return D3D_OK, got 0x%08x\n", hr);
+    ok(hr == DDERR_INVALIDPARAMS,
+       "Expected IDirect3D1::FindDevice to return DDERR_INVALIDPARAMS, got 0x%08x\n", hr);
 
     /* Try an arbitrary non-device GUID. */
     search.dwSize = sizeof(search);
diff --git a/include/d3dcaps.h b/include/d3dcaps.h
index 4fc76ba..392e15c 100644
--- a/include/d3dcaps.h
+++ b/include/d3dcaps.h
@@ -209,11 +209,13 @@ typedef struct _D3DDeviceDesc {
         DWORD           dwMaxBufferSize;
         DWORD           dwMaxVertexCount;
 
+        /* added in D3D2 */
         DWORD           dwMinTextureWidth,dwMinTextureHeight;
         DWORD           dwMaxTextureWidth,dwMaxTextureHeight;
         DWORD           dwMinStippleWidth,dwMaxStippleWidth;
         DWORD           dwMinStippleHeight,dwMaxStippleHeight;
 
+        /* added in D3D3 */
         DWORD       dwMaxTextureRepeat;
         DWORD       dwMaxTextureAspectRatio;
         DWORD       dwMaxAnisotropy;
-- 
2.4.3




More information about the wine-patches mailing list