[PATCH 5/5] ddraw: Properly support creating compressed user memory surfaces.

Henri Verbeet hverbeet at codeweavers.com
Thu Jun 12 04:52:31 CDT 2014


---
 dlls/ddraw/ddraw_private.h |    7 +++
 dlls/ddraw/surface.c       |  105 ++++++++++++++++++++++++++++++-------------
 dlls/ddraw/tests/ddraw4.c  |  106 ++++++++++++++++++++++++++++++++++++++++----
 dlls/ddraw/tests/ddraw7.c  |  106 ++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 276 insertions(+), 48 deletions(-)

diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 8cc5201..ac232a3 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -575,6 +575,13 @@ void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) DECLSPEC_HIDDEN
 
 void multiply_matrix(D3DMATRIX *dst, const D3DMATRIX *src1, const D3DMATRIX *src2) DECLSPEC_HIDDEN;
 
+static inline BOOL format_is_compressed(const DDPIXELFORMAT *format)
+{
+    return (format->dwFlags & DDPF_FOURCC) && (format->dwFourCC == WINED3DFMT_DXT1
+            || format->dwFourCC == WINED3DFMT_DXT2 || format->dwFourCC == WINED3DFMT_DXT3
+            || format->dwFourCC == WINED3DFMT_DXT4 || format->dwFourCC == WINED3DFMT_DXT5);
+}
+
 static inline BOOL format_is_paletteindexed(const DDPIXELFORMAT *fmt)
 {
     DWORD flags = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 4ffad8f..f2a656c 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -5886,11 +5886,30 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
             return DDERR_INVALIDPARAMS;
         }
 
-        if (!(desc->dwFlags & DDSD_PITCH))
+        if (format_is_compressed(&desc->u4.ddpfPixelFormat))
         {
-            WARN("User memory surfaces should explicitly specify the pitch.\n");
-            HeapFree(GetProcessHeap(), 0, texture);
-            return DDERR_INVALIDPARAMS;
+            if (version != 4 && (desc->dwFlags & DDSD_PITCH))
+            {
+                WARN("Pitch specified on a compressed user memory surface.\n");
+                HeapFree(GetProcessHeap(), 0, texture);
+                return DDERR_INVALIDPARAMS;
+            }
+
+            if (!(desc->dwFlags & (DDSD_LINEARSIZE | DDSD_PITCH)))
+            {
+                WARN("Compressed user memory surfaces should explicitly specify the linear size.\n");
+                HeapFree(GetProcessHeap(), 0, texture);
+                return DDERR_INVALIDPARAMS;
+            }
+        }
+        else
+        {
+            if (!(desc->dwFlags & DDSD_PITCH))
+            {
+                WARN("User memory surfaces should explicitly specify the pitch.\n");
+                HeapFree(GetProcessHeap(), 0, texture);
+                return DDERR_INVALIDPARAMS;
+            }
         }
     }
 
@@ -6112,41 +6131,63 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
     desc->dwHeight = wined3d_desc.height;
     surface->first_attached = surface;
 
-    /* Anno 1602 stores the pitch right after surface creation, so make sure
-     * it's there. TODO: Test other fourcc formats. */
-    if (wined3d_desc.format == WINED3DFMT_DXT1 || wined3d_desc.format == WINED3DFMT_DXT2
-            || wined3d_desc.format == WINED3DFMT_DXT3 || wined3d_desc.format == WINED3DFMT_DXT4
-            || wined3d_desc.format == WINED3DFMT_DXT5)
+    if (format_is_compressed(&desc->u4.ddpfPixelFormat))
     {
-        desc->dwFlags |= DDSD_LINEARSIZE;
-        desc->dwFlags &= ~DDSD_PITCH;
-        desc->u1.dwLinearSize = wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4);
-    }
-    else if (!(desc->dwFlags & DDSD_LPSURFACE))
-    {
-        desc->dwFlags |= DDSD_PITCH;
-        desc->dwFlags &= ~DDSD_LINEARSIZE;
-        desc->u1.lPitch = wined3d_surface_get_pitch(wined3d_surface);
-    }
+        if (desc->dwFlags & DDSD_LPSURFACE)
+        {
+            if ((desc->dwFlags & DDSD_LINEARSIZE)
+                    && desc->u1.dwLinearSize < wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4))
+            {
+                WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
+                return DDERR_INVALIDPARAMS;
+            }
 
-    if (desc->dwFlags & DDSD_LPSURFACE)
-    {
-        if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
-                wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
+            if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
+                    wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
+                    desc->lpSurface, 0)))
+            {
+                ERR("Failed to set surface memory, hr %#x.\n", hr);
+                return hr;
+            }
+
+            desc->dwFlags |= DDSD_LINEARSIZE;
+            desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_PITCH);
+            desc->u1.dwLinearSize = ~0u;
+        }
+        else
         {
-            WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
-            return DDERR_INVALIDPARAMS;
+            desc->dwFlags |= DDSD_LINEARSIZE;
+            desc->dwFlags &= ~DDSD_PITCH;
+            desc->u1.dwLinearSize = wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4);
         }
+    }
+    else
+    {
+        if (desc->dwFlags & DDSD_LPSURFACE)
+        {
+            if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
+                    wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
+            {
+                WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
+                return DDERR_INVALIDPARAMS;
+            }
 
-        if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
-                wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
-                desc->lpSurface, desc->u1.lPitch)))
+            if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
+                    wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
+                    desc->lpSurface, desc->u1.lPitch)))
+            {
+                ERR("Failed to set surface memory, hr %#x.\n", hr);
+                return hr;
+            }
+
+            desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
+        }
+        else
         {
-            ERR("Failed to set surface memory, hr %#x.\n", hr);
-            return hr;
+            desc->dwFlags |= DDSD_PITCH;
+            desc->dwFlags &= ~DDSD_LINEARSIZE;
+            desc->u1.lPitch = wined3d_surface_get_pitch(wined3d_surface);
         }
-
-        desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
     }
 
     wined3d_surface_incref(wined3d_surface);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index b515acc..4cbd9d9 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -4107,6 +4107,7 @@ static void test_block_formats_creation(void)
     DWORD num_fourcc_codes = 0, *fourcc_codes;
     DDSURFACEDESC2 ddsd;
     DDCAPS hal_caps;
+    void *mem;
 
     static const struct
     {
@@ -4115,19 +4116,20 @@ static void test_block_formats_creation(void)
         DWORD support_flag;
         unsigned int block_width;
         unsigned int block_height;
+        unsigned int block_size;
         BOOL create_size_checked, overlay;
     }
     formats[] =
     {
-        {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, FALSE, TRUE },
-        {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, FALSE, TRUE },
+        {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, 8,  TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, 4,  FALSE, TRUE },
+        {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, 4,  FALSE, TRUE },
     };
-    const struct
+    static const struct
     {
         DWORD caps, caps2;
         const char *name;
@@ -4158,6 +4160,36 @@ static void test_block_formats_creation(void)
             "managed texture", FALSE
         }
     };
+    enum size_type
+    {
+        SIZE_TYPE_ZERO,
+        SIZE_TYPE_PITCH,
+        SIZE_TYPE_SIZE,
+    };
+    static const struct
+    {
+        DWORD flags;
+        enum size_type size_type;
+        int rel_size;
+        HRESULT hr;
+    }
+    user_mem_tests[] =
+    {
+        {DDSD_LINEARSIZE,                               SIZE_TYPE_ZERO,   0, DD_OK},
+        {DDSD_LINEARSIZE,                               SIZE_TYPE_SIZE,   0, DD_OK},
+        {DDSD_PITCH,                                    SIZE_TYPE_ZERO,   0, DD_OK},
+        {DDSD_PITCH,                                    SIZE_TYPE_PITCH,  0, DD_OK},
+        {DDSD_LPSURFACE,                                SIZE_TYPE_ZERO,   0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_ZERO,   0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_PITCH,  0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_SIZE,   0, DD_OK},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_SIZE,   1, DD_OK},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_SIZE,  -1, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_PITCH,                   SIZE_TYPE_ZERO,   0, DD_OK},
+        {DDSD_LPSURFACE | DDSD_PITCH,                   SIZE_TYPE_PITCH,  0, DD_OK},
+        {DDSD_LPSURFACE | DDSD_PITCH,                   SIZE_TYPE_SIZE,   0, DD_OK},
+        {DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, SIZE_TYPE_SIZE,   0, DD_OK},
+    };
 
     window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
             0, 0, 640, 480, 0, 0, 0, 0);
@@ -4202,6 +4234,8 @@ static void test_block_formats_creation(void)
     hr = IDirectDraw4_GetCaps(ddraw, &hal_caps, NULL);
     ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
 
+    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2 * 2 * 16 + 1);
+
     for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
     {
         for (j = 0; j < sizeof(types) / sizeof(*types); j++)
@@ -4268,8 +4302,64 @@ static void test_block_formats_creation(void)
                 }
             }
         }
+
+        if (formats[i].overlay)
+            continue;
+
+        for (j = 0; j < sizeof(user_mem_tests) / sizeof(*user_mem_tests); ++j)
+        {
+            memset(&ddsd, 0, sizeof(ddsd));
+            ddsd.dwSize = sizeof(ddsd);
+            ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | user_mem_tests[j].flags;
+            ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE;
+
+            switch (user_mem_tests[j].size_type)
+            {
+                case SIZE_TYPE_ZERO:
+                    U1(ddsd).dwLinearSize = 0;
+                    break;
+
+                case SIZE_TYPE_PITCH:
+                    U1(ddsd).dwLinearSize = 2 * formats[i].block_size;
+                    break;
+
+                case SIZE_TYPE_SIZE:
+                    U1(ddsd).dwLinearSize = 2 * 2 * formats[i].block_size;
+                    break;
+            }
+            U1(ddsd).dwLinearSize += user_mem_tests[j].rel_size;
+
+            ddsd.lpSurface = mem;
+            U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
+            U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+            U4(ddsd).ddpfPixelFormat.dwFourCC = formats[i].fourcc;
+            ddsd.dwWidth = 8;
+            ddsd.dwHeight = 8;
+
+            hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &surface, NULL);
+            ok(hr == user_mem_tests[j].hr, "Test %u: Got unexpected hr %#x, format %s.\n", j, hr, formats[i].name);
+
+            if (FAILED(hr))
+                continue;
+
+            memset(&ddsd, 0, sizeof(ddsd));
+            ddsd.dwSize = sizeof(ddsd);
+            hr = IDirectDrawSurface4_GetSurfaceDesc(surface, &ddsd);
+            ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", j, hr);
+            ok(ddsd.dwFlags == (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LINEARSIZE),
+                    "Test %u: Got unexpected flags %#x.\n", j, ddsd.dwFlags);
+            if (user_mem_tests[j].flags & DDSD_LPSURFACE)
+                ok(U1(ddsd).dwLinearSize == ~0u, "Test %u: Got unexpected linear size %#x.\n",
+                        j, U1(ddsd).dwLinearSize);
+            else
+                ok(U1(ddsd).dwLinearSize == 2 * 2 * formats[i].block_size,
+                        "Test %u: Got unexpected linear size %#x, expected %#x.\n",
+                        j, U1(ddsd).dwLinearSize, 2 * 2 * formats[i].block_size);
+            IDirectDrawSurface4_Release(surface);
+        }
     }
 
+    HeapFree(GetProcessHeap(), 0, mem);
 cleanup:
     IDirectDraw4_Release(ddraw);
     IDirect3DDevice3_Release(device);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 7ed2f00..89f95c7 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -3876,6 +3876,7 @@ static void test_block_formats_creation(void)
     DWORD num_fourcc_codes = 0, *fourcc_codes;
     DDSURFACEDESC2 ddsd;
     DDCAPS hal_caps;
+    void *mem;
 
     static const struct
     {
@@ -3884,19 +3885,20 @@ static void test_block_formats_creation(void)
         DWORD support_flag;
         unsigned int block_width;
         unsigned int block_height;
+        unsigned int block_size;
         BOOL create_size_checked, overlay;
     }
     formats[] =
     {
-        {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, TRUE,  FALSE},
-        {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, FALSE, TRUE },
-        {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, FALSE, TRUE },
+        {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, 8,  TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, 16, TRUE,  FALSE},
+        {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, 4,  FALSE, TRUE },
+        {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, 4,  FALSE, TRUE },
     };
-    const struct
+    static const struct
     {
         DWORD caps, caps2;
         const char *name;
@@ -3927,6 +3929,36 @@ static void test_block_formats_creation(void)
             "managed texture", FALSE
         }
     };
+    enum size_type
+    {
+        SIZE_TYPE_ZERO,
+        SIZE_TYPE_PITCH,
+        SIZE_TYPE_SIZE,
+    };
+    static const struct
+    {
+        DWORD flags;
+        enum size_type size_type;
+        int rel_size;
+        HRESULT hr;
+    }
+    user_mem_tests[] =
+    {
+        {DDSD_LINEARSIZE,                               SIZE_TYPE_ZERO,   0, DD_OK},
+        {DDSD_LINEARSIZE,                               SIZE_TYPE_SIZE,   0, DD_OK},
+        {DDSD_PITCH,                                    SIZE_TYPE_ZERO,   0, DD_OK},
+        {DDSD_PITCH,                                    SIZE_TYPE_PITCH,  0, DD_OK},
+        {DDSD_LPSURFACE,                                SIZE_TYPE_ZERO,   0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_ZERO,   0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_PITCH,  0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_SIZE,   0, DD_OK},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_SIZE,   1, DD_OK},
+        {DDSD_LPSURFACE | DDSD_LINEARSIZE,              SIZE_TYPE_SIZE,  -1, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_PITCH,                   SIZE_TYPE_ZERO,   0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_PITCH,                   SIZE_TYPE_PITCH,  0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_PITCH,                   SIZE_TYPE_SIZE,   0, DDERR_INVALIDPARAMS},
+        {DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, SIZE_TYPE_SIZE,   0, DDERR_INVALIDPARAMS},
+    };
 
     window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
             0, 0, 640, 480, 0, 0, 0, 0);
@@ -3971,6 +4003,8 @@ static void test_block_formats_creation(void)
     hr = IDirectDraw7_GetCaps(ddraw, &hal_caps, NULL);
     ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
 
+    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2 * 2 * 16 + 1);
+
     for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
     {
         for (j = 0; j < sizeof(types) / sizeof(*types); j++)
@@ -4037,8 +4071,64 @@ static void test_block_formats_creation(void)
                 }
             }
         }
+
+        if (formats[i].overlay)
+            continue;
+
+        for (j = 0; j < sizeof(user_mem_tests) / sizeof(*user_mem_tests); ++j)
+        {
+            memset(&ddsd, 0, sizeof(ddsd));
+            ddsd.dwSize = sizeof(ddsd);
+            ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | user_mem_tests[j].flags;
+            ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE;
+
+            switch (user_mem_tests[j].size_type)
+            {
+                case SIZE_TYPE_ZERO:
+                    U1(ddsd).dwLinearSize = 0;
+                    break;
+
+                case SIZE_TYPE_PITCH:
+                    U1(ddsd).dwLinearSize = 2 * formats[i].block_size;
+                    break;
+
+                case SIZE_TYPE_SIZE:
+                    U1(ddsd).dwLinearSize = 2 * 2 * formats[i].block_size;
+                    break;
+            }
+            U1(ddsd).dwLinearSize += user_mem_tests[j].rel_size;
+
+            ddsd.lpSurface = mem;
+            U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
+            U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+            U4(ddsd).ddpfPixelFormat.dwFourCC = formats[i].fourcc;
+            ddsd.dwWidth = 8;
+            ddsd.dwHeight = 8;
+
+            hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &surface, NULL);
+            ok(hr == user_mem_tests[j].hr, "Test %u: Got unexpected hr %#x, format %s.\n", j, hr, formats[i].name);
+
+            if (FAILED(hr))
+                continue;
+
+            memset(&ddsd, 0, sizeof(ddsd));
+            ddsd.dwSize = sizeof(ddsd);
+            hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
+            ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", j, hr);
+            ok(ddsd.dwFlags == (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LINEARSIZE),
+                    "Test %u: Got unexpected flags %#x.\n", j, ddsd.dwFlags);
+            if (user_mem_tests[j].flags & DDSD_LPSURFACE)
+                ok(U1(ddsd).dwLinearSize == ~0u, "Test %u: Got unexpected linear size %#x.\n",
+                        j, U1(ddsd).dwLinearSize);
+            else
+                ok(U1(ddsd).dwLinearSize == 2 * 2 * formats[i].block_size,
+                        "Test %u: Got unexpected linear size %#x, expected %#x.\n",
+                        j, U1(ddsd).dwLinearSize, 2 * 2 * formats[i].block_size);
+            IDirectDrawSurface7_Release(surface);
+        }
     }
 
+    HeapFree(GetProcessHeap(), 0, mem);
 cleanup:
     IDirectDraw7_Release(ddraw);
     IDirect3DDevice7_Release(device);
-- 
1.7.10.4




More information about the wine-patches mailing list