[PATCH 3/6] d3d9/tests: Add helpers to avoid multiple readbacks of the render target surface.

Matteo Bruni mbruni at codeweavers.com
Wed Oct 7 18:26:43 CDT 2015


Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
And use them in pointsize_test(). It reduces the run time of that test
for me on Linux + Radeon HD 5650 with Mesa from 3.8 to 1.6 seconds.

My feeling is that we could improve the readback performance further in
wined3d, regardless of this patch.
---
 dlls/d3d9/tests/visual.c | 94 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 82 insertions(+), 12 deletions(-)

diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 04ee92f..4a4456f 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -173,6 +173,71 @@ out:
     return ret;
 }
 
+static D3DLOCKED_RECT get_rt(IDirect3DDevice9 *device, IDirect3DSurface9 **surf)
+{
+    IDirect3DSurface9 *target = NULL;
+    HRESULT hr;
+    D3DLOCKED_RECT locked_rect = {0};
+
+    *surf = NULL;
+    hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
+            D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, surf, NULL);
+    if (FAILED(hr) || !*surf)
+    {
+        trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
+        return locked_rect;
+    }
+
+    hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
+    if (FAILED(hr))
+    {
+        trace("Can't get the render target, hr %#x.\n", hr);
+        goto error;
+    }
+
+    hr = IDirect3DDevice9_GetRenderTargetData(device, target, *surf);
+    if (FAILED(hr))
+    {
+        trace("Can't read the render target data, hr %#x.\n", hr);
+        goto error;
+    }
+    IDirect3DSurface9_Release(target);
+    target = NULL;
+
+    hr = IDirect3DSurface9_LockRect(*surf, &locked_rect, NULL, D3DLOCK_READONLY);
+    if (FAILED(hr))
+    {
+        trace("Can't lock the offscreen surface, hr %#x.\n", hr);
+        goto error;
+    }
+
+    return locked_rect;
+
+error:
+    if (target)
+        IDirect3DSurface9_Release(target);
+    if (*surf)
+        IDirect3DSurface9_Release(*surf);
+    return locked_rect;
+}
+
+static DWORD get_rt_color(D3DLOCKED_RECT *locked_rect, unsigned int x, unsigned int y)
+{
+    return locked_rect->pBits
+            ? ((DWORD *)locked_rect->pBits)[y * locked_rect->Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
+}
+
+static void release_rt(IDirect3DSurface9 *surf)
+{
+    HRESULT hr;
+
+    if (!surf)
+        return;
+    if (FAILED(hr = IDirect3DSurface9_UnlockRect(surf)))
+        trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
+    IDirect3DSurface9_Release(surf);
+}
+
 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
 {
     D3DPRESENT_PARAMETERS present_parameters = {0};
@@ -10680,35 +10745,40 @@ static void pointsize_test(void)
             }
             else
             {
+                IDirect3DSurface9 *readback;
+                D3DLOCKED_RECT locked_rect = get_rt(device, &readback);
+
                 /* On AMD apparently only the first texcoord is modified by the point coordinates
                  * when using SM2/3 pixel shaders. */
-                color = getPixelColor(device, 64 - size / 2 + 1, 64 - size / 2 + 1);
+                color = get_rt_color(&locked_rect, 64 - size / 2 + 1, 64 - size / 2 + 1);
                 ok(color_match(color, 0x00ff0000, 0),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
-                color = getPixelColor(device, 64 + size / 2 - 1, 64 - size / 2 + 1);
+                color = get_rt_color(&locked_rect, 64 + size / 2 - 1, 64 - size / 2 + 1);
                 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
                         || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
-                color = getPixelColor(device, 64 - size / 2 + 1, 64 + size / 2 - 1);
+                color = get_rt_color(&locked_rect, 64 - size / 2 + 1, 64 + size / 2 - 1);
                 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
-                color = getPixelColor(device, 64 + size / 2 - 1, 64 + size / 2 - 1);
+                color = get_rt_color(&locked_rect, 64 + size / 2 - 1, 64 + size / 2 - 1);
                 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
                         || (allow_broken && broken(color_match(color, 0x00000000, 0))),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
 
-                color = getPixelColor(device, 64 - size / 2 - 1, 64 - size / 2 - 1);
-                ok(color_match(color, 0x0000ffff, 0),
+                color = get_rt_color(&locked_rect, 64 - size / 2 - 1, 64 - size / 2 - 1);
+                ok(color_match(color, 0xff00ffff, 0),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
-                color = getPixelColor(device, 64 + size / 2 + 1, 64 - size / 2 - 1);
-                ok(color_match(color, 0x0000ffff, 0),
+                color = get_rt_color(&locked_rect, 64 + size / 2 + 1, 64 - size / 2 - 1);
+                ok(color_match(color, 0xff00ffff, 0),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
-                color = getPixelColor(device, 64 - size / 2 - 1, 64 + size / 2 + 1);
-                ok(color_match(color, 0x0000ffff, 0),
+                color = get_rt_color(&locked_rect, 64 - size / 2 - 1, 64 + size / 2 + 1);
+                ok(color_match(color, 0xff00ffff, 0),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
-                color = getPixelColor(device, 64 + size / 2 + 1, 64 + size / 2 + 1);
-                ok(color_match(color, 0x0000ffff, 0),
+                color = get_rt_color(&locked_rect, 64 + size / 2 + 1, 64 + size / 2 + 1);
+                ok(color_match(color, 0xff00ffff, 0),
                         "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
+
+                release_rt(readback);
             }
         }
         IDirect3DDevice9_SetVertexShader(device, NULL);
-- 
2.4.9




More information about the wine-patches mailing list