[PATCH 1/5] ddraw/tests: Rewrite yv12_test().

Henri Verbeet hverbeet at codeweavers.com
Fri Feb 5 14:30:59 CST 2016


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/ddraw/tests/ddraw1.c  | 136 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/ddraw/tests/ddraw2.c  | 136 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/ddraw/tests/ddraw4.c  | 136 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/ddraw/tests/ddraw7.c  | 136 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/ddraw/tests/overlay.c | 101 ---------------------------------
 5 files changed, 540 insertions(+), 105 deletions(-)

diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index dcadaf5..fdb9945 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2005 Antoine Chavasse (a.chavasse at gmail.com)
+ * Copyright 2008, 2011, 2012-2013 Stefan Dösinger for CodeWeavers
  * Copyright 2011-2014 Henri Verbeet for CodeWeavers
- * Copyright 2012-2013 Stefan Dösinger for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -45,6 +45,27 @@ static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
     return TRUE;
 }
 
+static IDirectDrawSurface *create_overlay(IDirectDraw *ddraw,
+        unsigned int width, unsigned int height, DWORD format)
+{
+    IDirectDrawSurface *surface;
+    DDSURFACEDESC desc;
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+    desc.dwWidth = width;
+    desc.dwHeight = height;
+    desc.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
+    desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
+    desc.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+    desc.ddpfPixelFormat.dwFourCC = format;
+
+    if (FAILED(IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL)))
+        return NULL;
+    return surface;
+}
+
 static DWORD WINAPI create_window_thread_proc(void *param)
 {
     struct create_window_thread_param *p = param;
@@ -8200,6 +8221,118 @@ done:
     DestroyWindow(window);
 }
 
+static void test_yv12_overlay(void)
+{
+    IDirectDrawSurface *src_surface, *dst_surface;
+    RECT rect = {13, 17, 14, 18};
+    unsigned int offset, y;
+    unsigned char *base;
+    DDSURFACEDESC desc;
+    IDirectDraw *ddraw;
+    HWND window;
+    HRESULT hr;
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    ddraw = create_ddraw();
+    ok(!!ddraw, "Failed to create a ddraw object.\n");
+    hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+    if (!(src_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        skip("Failed to create a YV12 overlay, skipping test.\n");
+        goto done;
+    }
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    hr = IDirectDrawSurface_Lock(src_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+    ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
+            "Got unexpected flags %#x.\n", desc.dwFlags);
+    ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_HWCODEC)
+            || desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
+            "Got unexpected caps %#x.\n", desc.ddsCaps.dwCaps);
+    ok(desc.dwWidth == 256, "Got unexpected width %u.\n", desc.dwWidth);
+    ok(desc.dwHeight == 256, "Got unexpected height %u.\n", desc.dwHeight);
+    /* The overlay pitch seems to have 256 byte alignment. */
+    ok(!(U1(desc).lPitch & 0xff), "Got unexpected pitch %u.\n", U1(desc).lPitch);
+
+    /* Fill the surface with some data for the blit test. */
+    base = desc.lpSurface;
+    /* Luminance */
+    for (y = 0; y < desc.dwHeight; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x10, desc.dwWidth);
+    }
+    /* V */
+    for (; y < desc.dwHeight + desc.dwHeight / 4; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x20, desc.dwWidth);
+    }
+    /* U */
+    for (; y < desc.dwHeight + desc.dwHeight / 2; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x30, desc.dwWidth);
+    }
+
+    hr = IDirectDrawSurface_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
+     * other block-based formats like DXT the entire Y channel is stored in
+     * one big chunk of memory, followed by the chroma channels. So partial
+     * locks do not really make sense. Show that they are allowed nevertheless
+     * and the offset points into the luminance data. */
+    hr = IDirectDrawSurface_Lock(src_surface, &rect, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+    offset = ((const unsigned char *)desc.lpSurface - base);
+    ok(offset == rect.top * U1(desc).lPitch + rect.left, "Got unexpected offset %u, expected %u.\n",
+            offset, rect.top * U1(desc).lPitch + rect.left);
+    hr = IDirectDrawSurface_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    if (!(dst_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        /* Windows XP with a Radeon X1600 GPU refuses to create a second
+         * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
+        skip("Failed to create a second YV12 surface, skipping blit test.\n");
+        IDirectDrawSurface_Release(src_surface);
+        goto done;
+    }
+
+    hr = IDirectDrawSurface_Blt(dst_surface, NULL, src_surface, NULL, DDBLT_WAIT, NULL);
+    /* VMware rejects YV12 blits. This behavior has not been seen on real
+     * hardware yet, so mark it broken. */
+    ok(SUCCEEDED(hr) || broken(hr == E_NOTIMPL), "Failed to blit, hr %#x.\n", hr);
+
+    if (SUCCEEDED(hr))
+    {
+        memset(&desc, 0, sizeof(desc));
+        desc.dwSize = sizeof(desc);
+        hr = IDirectDrawSurface_Lock(dst_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+        ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+        base = desc.lpSurface;
+        ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]);
+        base += desc.dwHeight * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]);
+        base += desc.dwHeight / 4 * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
+
+        hr = IDirectDrawSurface_Unlock(dst_surface, NULL);
+        ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+    }
+
+    IDirectDrawSurface_Release(dst_surface);
+    IDirectDrawSurface_Release(src_surface);
+done:
+    IDirectDraw_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw1)
 {
     IDirectDraw *ddraw;
@@ -8273,4 +8406,5 @@ START_TEST(ddraw1)
     test_range_colorkey();
     test_shademode();
     test_lockrect_invalid();
+    test_yv12_overlay();
 }
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 62f1974..f0ba90c 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2005 Antoine Chavasse (a.chavasse at gmail.com)
+ * Copyright 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
  * Copyright 2011-2014 Henri Verbeet for CodeWeavers
- * Copyright 2012-2014 Stefan Dösinger for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -47,6 +47,27 @@ static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
     return TRUE;
 }
 
+static IDirectDrawSurface *create_overlay(IDirectDraw2 *ddraw,
+        unsigned int width, unsigned int height, DWORD format)
+{
+    IDirectDrawSurface *surface;
+    DDSURFACEDESC desc;
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+    desc.dwWidth = width;
+    desc.dwHeight = height;
+    desc.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
+    desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
+    desc.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+    desc.ddpfPixelFormat.dwFourCC = format;
+
+    if (FAILED(IDirectDraw2_CreateSurface(ddraw, &desc, &surface, NULL)))
+        return NULL;
+    return surface;
+}
+
 static DWORD WINAPI create_window_thread_proc(void *param)
 {
     struct create_window_thread_param *p = param;
@@ -9307,6 +9328,118 @@ done:
     DestroyWindow(window);
 }
 
+static void test_yv12_overlay(void)
+{
+    IDirectDrawSurface *src_surface, *dst_surface;
+    RECT rect = {13, 17, 14, 18};
+    unsigned int offset, y;
+    unsigned char *base;
+    IDirectDraw2 *ddraw;
+    DDSURFACEDESC desc;
+    HWND window;
+    HRESULT hr;
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    ddraw = create_ddraw();
+    ok(!!ddraw, "Failed to create a ddraw object.\n");
+    hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+    if (!(src_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        skip("Failed to create a YV12 overlay, skipping test.\n");
+        goto done;
+    }
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    hr = IDirectDrawSurface_Lock(src_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+    ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
+            "Got unexpected flags %#x.\n", desc.dwFlags);
+    ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_HWCODEC)
+            || desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
+            "Got unexpected caps %#x.\n", desc.ddsCaps.dwCaps);
+    ok(desc.dwWidth == 256, "Got unexpected width %u.\n", desc.dwWidth);
+    ok(desc.dwHeight == 256, "Got unexpected height %u.\n", desc.dwHeight);
+    /* The overlay pitch seems to have 256 byte alignment. */
+    ok(!(U1(desc).lPitch & 0xff), "Got unexpected pitch %u.\n", U1(desc).lPitch);
+
+    /* Fill the surface with some data for the blit test. */
+    base = desc.lpSurface;
+    /* Luminance */
+    for (y = 0; y < desc.dwHeight; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x10, desc.dwWidth);
+    }
+    /* V */
+    for (; y < desc.dwHeight + desc.dwHeight / 4; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x20, desc.dwWidth);
+    }
+    /* U */
+    for (; y < desc.dwHeight + desc.dwHeight / 2; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x30, desc.dwWidth);
+    }
+
+    hr = IDirectDrawSurface_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
+     * other block-based formats like DXT the entire Y channel is stored in
+     * one big chunk of memory, followed by the chroma channels. So partial
+     * locks do not really make sense. Show that they are allowed nevertheless
+     * and the offset points into the luminance data. */
+    hr = IDirectDrawSurface_Lock(src_surface, &rect, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+    offset = ((const unsigned char *)desc.lpSurface - base);
+    ok(offset == rect.top * U1(desc).lPitch + rect.left, "Got unexpected offset %u, expected %u.\n",
+            offset, rect.top * U1(desc).lPitch + rect.left);
+    hr = IDirectDrawSurface_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    if (!(dst_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        /* Windows XP with a Radeon X1600 GPU refuses to create a second
+         * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
+        skip("Failed to create a second YV12 surface, skipping blit test.\n");
+        IDirectDrawSurface_Release(src_surface);
+        goto done;
+    }
+
+    hr = IDirectDrawSurface_Blt(dst_surface, NULL, src_surface, NULL, DDBLT_WAIT, NULL);
+    /* VMware rejects YV12 blits. This behavior has not been seen on real
+     * hardware yet, so mark it broken. */
+    ok(SUCCEEDED(hr) || broken(hr == E_NOTIMPL), "Failed to blit, hr %#x.\n", hr);
+
+    if (SUCCEEDED(hr))
+    {
+        memset(&desc, 0, sizeof(desc));
+        desc.dwSize = sizeof(desc);
+        hr = IDirectDrawSurface_Lock(dst_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+        ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+        base = desc.lpSurface;
+        ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]);
+        base += desc.dwHeight * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]);
+        base += desc.dwHeight / 4 * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
+
+        hr = IDirectDrawSurface_Unlock(dst_surface, NULL);
+        ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+    }
+
+    IDirectDrawSurface_Release(dst_surface);
+    IDirectDrawSurface_Release(src_surface);
+done:
+    IDirectDraw2_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw2)
 {
     IDirectDraw2 *ddraw;
@@ -9387,4 +9520,5 @@ START_TEST(ddraw2)
     test_range_colorkey();
     test_shademode();
     test_lockrect_invalid();
+    test_yv12_overlay();
 }
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 9239930..08a1a4c 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2005 Antoine Chavasse (a.chavasse at gmail.com)
+ * Copyright 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
  * Copyright 2011-2014 Henri Verbeet for CodeWeavers
- * Copyright 2012-2014 Stefan Dösinger for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -86,6 +86,27 @@ static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
     return TRUE;
 }
 
+static IDirectDrawSurface4 *create_overlay(IDirectDraw4 *ddraw,
+        unsigned int width, unsigned int height, DWORD format)
+{
+    IDirectDrawSurface4 *surface;
+    DDSURFACEDESC2 desc;
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+    desc.dwWidth = width;
+    desc.dwHeight = height;
+    desc.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
+    U4(desc).ddpfPixelFormat.dwSize = sizeof(U4(desc).ddpfPixelFormat);
+    U4(desc).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+    U4(desc).ddpfPixelFormat.dwFourCC = format;
+
+    if (FAILED(IDirectDraw4_CreateSurface(ddraw, &desc, &surface, NULL)))
+        return NULL;
+    return surface;
+}
+
 static DWORD WINAPI create_window_thread_proc(void *param)
 {
     struct create_window_thread_param *p = param;
@@ -10482,6 +10503,118 @@ done:
     DestroyWindow(window);
 }
 
+static void test_yv12_overlay(void)
+{
+    IDirectDrawSurface4 *src_surface, *dst_surface;
+    RECT rect = {13, 17, 14, 18};
+    unsigned int offset, y;
+    DDSURFACEDESC2 desc;
+    unsigned char *base;
+    IDirectDraw4 *ddraw;
+    HWND window;
+    HRESULT hr;
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    ddraw = create_ddraw();
+    ok(!!ddraw, "Failed to create a ddraw object.\n");
+    hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+    if (!(src_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        skip("Failed to create a YV12 overlay, skipping test.\n");
+        goto done;
+    }
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    hr = IDirectDrawSurface4_Lock(src_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+    ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
+            "Got unexpected flags %#x.\n", desc.dwFlags);
+    ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_HWCODEC)
+            || desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
+            "Got unexpected caps %#x.\n", desc.ddsCaps.dwCaps);
+    ok(desc.dwWidth == 256, "Got unexpected width %u.\n", desc.dwWidth);
+    ok(desc.dwHeight == 256, "Got unexpected height %u.\n", desc.dwHeight);
+    /* The overlay pitch seems to have 256 byte alignment. */
+    ok(!(U1(desc).lPitch & 0xff), "Got unexpected pitch %u.\n", U1(desc).lPitch);
+
+    /* Fill the surface with some data for the blit test. */
+    base = desc.lpSurface;
+    /* Luminance */
+    for (y = 0; y < desc.dwHeight; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x10, desc.dwWidth);
+    }
+    /* V */
+    for (; y < desc.dwHeight + desc.dwHeight / 4; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x20, desc.dwWidth);
+    }
+    /* U */
+    for (; y < desc.dwHeight + desc.dwHeight / 2; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x30, desc.dwWidth);
+    }
+
+    hr = IDirectDrawSurface4_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
+     * other block-based formats like DXT the entire Y channel is stored in
+     * one big chunk of memory, followed by the chroma channels. So partial
+     * locks do not really make sense. Show that they are allowed nevertheless
+     * and the offset points into the luminance data. */
+    hr = IDirectDrawSurface4_Lock(src_surface, &rect, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+    offset = ((const unsigned char *)desc.lpSurface - base);
+    ok(offset == rect.top * U1(desc).lPitch + rect.left, "Got unexpected offset %u, expected %u.\n",
+            offset, rect.top * U1(desc).lPitch + rect.left);
+    hr = IDirectDrawSurface4_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    if (!(dst_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        /* Windows XP with a Radeon X1600 GPU refuses to create a second
+         * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
+        skip("Failed to create a second YV12 surface, skipping blit test.\n");
+        IDirectDrawSurface4_Release(src_surface);
+        goto done;
+    }
+
+    hr = IDirectDrawSurface4_Blt(dst_surface, NULL, src_surface, NULL, DDBLT_WAIT, NULL);
+    /* VMware rejects YV12 blits. This behavior has not been seen on real
+     * hardware yet, so mark it broken. */
+    ok(SUCCEEDED(hr) || broken(hr == E_NOTIMPL), "Failed to blit, hr %#x.\n", hr);
+
+    if (SUCCEEDED(hr))
+    {
+        memset(&desc, 0, sizeof(desc));
+        desc.dwSize = sizeof(desc);
+        hr = IDirectDrawSurface4_Lock(dst_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+        ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+        base = desc.lpSurface;
+        ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]);
+        base += desc.dwHeight * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]);
+        base += desc.dwHeight / 4 * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
+
+        hr = IDirectDrawSurface4_Unlock(dst_surface, NULL);
+        ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+    }
+
+    IDirectDrawSurface4_Release(dst_surface);
+    IDirectDrawSurface4_Release(src_surface);
+done:
+    IDirectDraw4_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw4)
 {
     IDirectDraw4 *ddraw;
@@ -10569,4 +10702,5 @@ START_TEST(ddraw4)
     test_range_colorkey();
     test_shademode();
     test_lockrect_invalid();
+    test_yv12_overlay();
 }
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 34167c1..9b5c698 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -1,6 +1,6 @@
 /*
  * Copyright 2005 Antoine Chavasse (a.chavasse at gmail.com)
- * Copyright 2006, 2012-2014 Stefan Dösinger for CodeWeavers
+ * Copyright 2006, 2008, 2011, 2012-2014 Stefan Dösinger for CodeWeavers
  * Copyright 2011-2014 Henri Verbeet for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
@@ -100,6 +100,27 @@ static ULONG get_refcount(IUnknown *iface)
     return IUnknown_Release(iface);
 }
 
+static IDirectDrawSurface7 *create_overlay(IDirectDraw7 *ddraw,
+        unsigned int width, unsigned int height, DWORD format)
+{
+    IDirectDrawSurface7 *surface;
+    DDSURFACEDESC2 desc;
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+    desc.dwWidth = width;
+    desc.dwHeight = height;
+    desc.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
+    U4(desc).ddpfPixelFormat.dwSize = sizeof(U4(desc).ddpfPixelFormat);
+    U4(desc).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+    U4(desc).ddpfPixelFormat.dwFourCC = format;
+
+    if (FAILED(IDirectDraw7_CreateSurface(ddraw, &desc, &surface, NULL)))
+        return NULL;
+    return surface;
+}
+
 static DWORD WINAPI create_window_thread_proc(void *param)
 {
     struct create_window_thread_param *p = param;
@@ -10761,6 +10782,118 @@ done:
     DestroyWindow(window);
 }
 
+static void test_yv12_overlay(void)
+{
+    IDirectDrawSurface7 *src_surface, *dst_surface;
+    RECT rect = {13, 17, 14, 18};
+    unsigned int offset, y;
+    DDSURFACEDESC2 desc;
+    unsigned char *base;
+    IDirectDraw7 *ddraw;
+    HWND window;
+    HRESULT hr;
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+    ddraw = create_ddraw();
+    ok(!!ddraw, "Failed to create a ddraw object.\n");
+    hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+    if (!(src_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        skip("Failed to create a YV12 overlay, skipping test.\n");
+        goto done;
+    }
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+    hr = IDirectDrawSurface7_Lock(src_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+    ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
+            "Got unexpected flags %#x.\n", desc.dwFlags);
+    ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_HWCODEC)
+            || desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
+            "Got unexpected caps %#x.\n", desc.ddsCaps.dwCaps);
+    ok(desc.dwWidth == 256, "Got unexpected width %u.\n", desc.dwWidth);
+    ok(desc.dwHeight == 256, "Got unexpected height %u.\n", desc.dwHeight);
+    /* The overlay pitch seems to have 256 byte alignment. */
+    ok(!(U1(desc).lPitch & 0xff), "Got unexpected pitch %u.\n", U1(desc).lPitch);
+
+    /* Fill the surface with some data for the blit test. */
+    base = desc.lpSurface;
+    /* Luminance */
+    for (y = 0; y < desc.dwHeight; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x10, desc.dwWidth);
+    }
+    /* V */
+    for (; y < desc.dwHeight + desc.dwHeight / 4; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x20, desc.dwWidth);
+    }
+    /* U */
+    for (; y < desc.dwHeight + desc.dwHeight / 2; ++y)
+    {
+        memset(base + U1(desc).lPitch * y, 0x30, desc.dwWidth);
+    }
+
+    hr = IDirectDrawSurface7_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    /* YV12 uses 2x2 blocks with 6 bytes per block (4*Y, 1*U, 1*V). Unlike
+     * other block-based formats like DXT the entire Y channel is stored in
+     * one big chunk of memory, followed by the chroma channels. So partial
+     * locks do not really make sense. Show that they are allowed nevertheless
+     * and the offset points into the luminance data. */
+    hr = IDirectDrawSurface7_Lock(src_surface, &rect, &desc, DDLOCK_WAIT, NULL);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+    offset = ((const unsigned char *)desc.lpSurface - base);
+    ok(offset == rect.top * U1(desc).lPitch + rect.left, "Got unexpected offset %u, expected %u.\n",
+            offset, rect.top * U1(desc).lPitch + rect.left);
+    hr = IDirectDrawSurface7_Unlock(src_surface, NULL);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+    if (!(dst_surface = create_overlay(ddraw, 256, 256, MAKEFOURCC('Y','V','1','2'))))
+    {
+        /* Windows XP with a Radeon X1600 GPU refuses to create a second
+         * overlay surface, DDERR_NOOVERLAYHW, making the blit tests moot. */
+        skip("Failed to create a second YV12 surface, skipping blit test.\n");
+        IDirectDrawSurface7_Release(src_surface);
+        goto done;
+    }
+
+    hr = IDirectDrawSurface7_Blt(dst_surface, NULL, src_surface, NULL, DDBLT_WAIT, NULL);
+    /* VMware rejects YV12 blits. This behavior has not been seen on real
+     * hardware yet, so mark it broken. */
+    ok(SUCCEEDED(hr) || broken(hr == E_NOTIMPL), "Failed to blit, hr %#x.\n", hr);
+
+    if (SUCCEEDED(hr))
+    {
+        memset(&desc, 0, sizeof(desc));
+        desc.dwSize = sizeof(desc);
+        hr = IDirectDrawSurface7_Lock(dst_surface, NULL, &desc, DDLOCK_WAIT, NULL);
+        ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+
+        base = desc.lpSurface;
+        ok(base[0] == 0x10, "Got unexpected Y data 0x%02x.\n", base[0]);
+        base += desc.dwHeight * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x20, "Got unexpected V data 0x%02x.\n", base[0]);
+        base += desc.dwHeight / 4 * U1(desc).lPitch;
+        todo_wine ok(base[0] == 0x30, "Got unexpected U data 0x%02x.\n", base[0]);
+
+        hr = IDirectDrawSurface7_Unlock(dst_surface, NULL);
+        ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+    }
+
+    IDirectDrawSurface7_Release(dst_surface);
+    IDirectDrawSurface7_Release(src_surface);
+done:
+    IDirectDraw7_Release(ddraw);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw7)
 {
     HMODULE module = GetModuleHandleA("ddraw.dll");
@@ -10859,4 +10992,5 @@ START_TEST(ddraw7)
     test_range_colorkey();
     test_shademode();
     test_lockrect_invalid();
+    test_yv12_overlay();
 }
diff --git a/dlls/ddraw/tests/overlay.c b/dlls/ddraw/tests/overlay.c
index 7e22cca..ecea63e 100644
--- a/dlls/ddraw/tests/overlay.c
+++ b/dlls/ddraw/tests/overlay.c
@@ -191,106 +191,6 @@ static void offscreen_test(void) {
     IDirectDrawSurface7_Release(overlay);
 }
 
-static void yv12_test(void)
-{
-    HRESULT hr;
-    DDSURFACEDESC2 desc;
-    IDirectDrawSurface7 *surface, *dst;
-    char *base;
-    RECT rect = {13, 17, 14, 18};
-    unsigned int offset, y;
-
-    surface = create_overlay(256, 256, MAKEFOURCC('Y','V','1','2'));
-    if(!surface) {
-        skip("YV12 surfaces not available\n");
-        return;
-    }
-
-    memset(&desc, 0, sizeof(desc));
-    desc.dwSize = sizeof(desc);
-    hr = IDirectDrawSurface7_Lock(surface, NULL, &desc, 0, NULL);
-    ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned 0x%08x, expected DD_OK\n", hr);
-
-    ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
-       "Unexpected desc.dwFlags 0x%08x\n", desc.dwFlags);
-    ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM) ||
-       desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_HWCODEC),
-       "Unexpected desc.ddsCaps.dwCaps 0x%08x\n", desc.ddsCaps.dwCaps);
-    ok(desc.dwWidth == 256 && desc.dwHeight == 256, "Expected size 256x256, got %ux%u\n",
-       desc.dwWidth, desc.dwHeight);
-    /* The overlay pitch seems to have 256 byte alignment */
-    ok((U1(desc).lPitch & 0xff) == 0, "Expected 256 byte aligned pitch, got %u\n", U1(desc).lPitch);
-
-    /* Fill the surface with some data for the blit test */
-    base = desc.lpSurface;
-    /* Luminance */
-    for (y = 0; y < desc.dwHeight; y++)
-    {
-        memset(base + U1(desc).lPitch * y, 0x10, desc.dwWidth);
-    }
-    /* V */
-    for (; y < desc.dwHeight + desc.dwHeight / 4; y++)
-    {
-        memset(base + U1(desc).lPitch * y, 0x20, desc.dwWidth);
-    }
-    /* U */
-    for (; y < desc.dwHeight + desc.dwHeight / 2; y++)
-    {
-        memset(base + U1(desc).lPitch * y, 0x30, desc.dwWidth);
-    }
-
-    hr = IDirectDrawSurface7_Unlock(surface, NULL);
-    ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);
-
-    /* YV12 uses 2x2 blocks with 6 bytes per block(4*Y, 1*U, 1*V). Unlike other block-based formats like DXT
-     * the entire Y channel is stored in one big chunk of memory, followed by the chroma channels. So
-     * partial locks do not really make sense. Show that they are allowed nevertheless and the offset points
-     * into the luminance data */
-    hr = IDirectDrawSurface7_Lock(surface, &rect, &desc, 0, NULL);
-    ok(hr == DD_OK, "Partial lock of a YV12 surface returned 0x%08x, expected DD_OK\n", hr);
-    offset = ((const char *) desc.lpSurface - base);
-    ok(offset == rect.top * U1(desc).lPitch + rect.left, "Expected %u byte offset from partial lock, got %u\n",
-            rect.top * U1(desc).lPitch + rect.left, offset);
-    hr = IDirectDrawSurface7_Unlock(surface, NULL);
-    ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);
-
-    dst = create_overlay(256, 256, MAKEFOURCC('Y','V','1','2'));
-    if (!dst)
-    {
-        /* Windows XP with a Radeon X1600 GPU refuses to create a second overlay surface,
-         * DDERR_NOOVERLAYHW, making the blit tests moot */
-        skip("Could not create a second YV12 surface, skipping blit test\n");
-        goto cleanup;
-    }
-
-    hr = IDirectDrawSurface7_Blt(dst, NULL, surface, NULL, 0, NULL);
-    /* VMware rejects YV12 blits. This behavior has not been seen on real hardware yet, so mark it broken */
-    ok(hr == DD_OK || broken(hr == E_NOTIMPL),
-            "IDirectDrawSurface7_Blt returned 0x%08x, expected DD_OK\n", hr);
-
-    if (SUCCEEDED(hr))
-    {
-        memset(&desc, 0, sizeof(desc));
-        desc.dwSize = sizeof(desc);
-        hr = IDirectDrawSurface7_Lock(dst, NULL, &desc, 0, NULL);
-        ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned 0x%08x, expected DD_OK\n", hr);
-
-        base = desc.lpSurface;
-        ok(base[0] == 0x10, "Y data is 0x%02x, expected 0x10\n", base[0]);
-        base += desc.dwHeight * U1(desc).lPitch;
-        todo_wine ok(base[0] == 0x20, "V data is 0x%02x, expected 0x20\n", base[0]);
-        base += desc.dwHeight / 4 * U1(desc).lPitch;
-        todo_wine ok(base[0] == 0x30, "U data is 0x%02x, expected 0x30\n", base[0]);
-
-        hr = IDirectDrawSurface7_Unlock(dst, NULL);
-        ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);
-    }
-
-    IDirectDrawSurface7_Release(dst);
-cleanup:
-    IDirectDrawSurface7_Release(surface);
-}
-
 START_TEST(overlay)
 {
     if(CreateDirectDraw() == FALSE) {
@@ -300,7 +200,6 @@ START_TEST(overlay)
 
     rectangle_settings();
     offscreen_test();
-    yv12_test();
 
     if(primary) IDirectDrawSurface7_Release(primary);
     if(ddraw) IDirectDraw7_Release(ddraw);
-- 
2.1.4




More information about the wine-patches mailing list