[PATCH 4/4] d3d9: Implement user memory for offscreen plain surfaces.

Stefan Dösinger stefan at codeweavers.com
Wed Dec 4 07:01:34 CST 2013


---
 dlls/d3d9/device.c       | 19 ++++++++++++++-----
 dlls/d3d9/tests/d3d9ex.c | 26 ++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 25c65f7..c3853e8 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -944,7 +944,7 @@ static HRESULT WINAPI d3d9_device_CreateIndexBuffer(IDirect3DDevice9Ex *iface, U
 
 static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width, UINT height,
         D3DFORMAT format, DWORD flags, IDirect3DSurface9 **surface, UINT usage, D3DPOOL pool,
-        D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
+        D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, void *user_mem)
 {
     struct wined3d_resource *sub_resource;
     struct wined3d_resource_desc desc;
@@ -986,6 +986,9 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
     IDirect3DSurface9_AddRef(*surface);
     wined3d_texture_decref(texture);
 
+    if (user_mem)
+        wined3d_surface_set_mem(surface_impl->wined3d_surface, user_mem, 0);
+
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -1011,7 +1014,7 @@ static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface,
         flags |= WINED3D_SURFACE_MAPPABLE;
 
     return d3d9_device_create_surface(device, width, height, format, flags, surface,
-            D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality);
+            D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL);
 }
 
 static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex *iface, UINT width, UINT height,
@@ -1034,7 +1037,7 @@ static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex *
         flags |= WINED3D_SURFACE_DISCARD;
 
     return d3d9_device_create_surface(device, width, height, format, flags, surface,
-            D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality);
+            D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL);
 }
 
 
@@ -1219,13 +1222,19 @@ static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex
         HANDLE *shared_handle)
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+    void *user_mem = NULL;
 
     TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n",
             iface, width, height, format, pool, surface, shared_handle);
 
     *surface = NULL;
     if (shared_handle)
-        FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+    {
+        if (pool == D3DPOOL_SYSTEMMEM)
+            user_mem = *shared_handle;
+        else
+            FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+    }
 
     if (pool == D3DPOOL_MANAGED)
     {
@@ -1236,7 +1245,7 @@ static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex
      * regardless of the pool they're created in. Should we set dynamic usage
      * here? */
     return d3d9_device_create_surface(device, width, height, format,
-            WINED3D_SURFACE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0);
+            WINED3D_SURFACE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0, user_mem);
 }
 
 static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 *surface)
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
index 9f04832..c2ba72c 100644
--- a/dlls/d3d9/tests/d3d9ex.c
+++ b/dlls/d3d9/tests/d3d9ex.c
@@ -543,6 +543,7 @@ static void test_user_memory(void)
     IDirect3DVolumeTexture9 *volume_texture;
     IDirect3DVertexBuffer9 *vertex_buffer;
     IDirect3DIndexBuffer9 *index_buffer;
+    IDirect3DSurface9 *surface;
     D3DLOCKED_RECT locked_rect;
     UINT refcount;
     HWND window;
@@ -593,6 +594,31 @@ static void test_user_memory(void)
             &vertex_buffer, &mem);
     ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
 
+    hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8,
+            D3DPOOL_SYSTEMMEM, &surface, &mem);
+    ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+    hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
+    ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+    ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
+    ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
+    hr = IDirect3DSurface9_UnlockRect(surface);
+    ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+    IDirect3DSurface9_Release(surface);
+
+    hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8,
+            D3DPOOL_SYSTEMMEM, &surface, &mem, 0);
+    todo_wine ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+    if (SUCCEEDED(hr))
+    {
+        hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
+        ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+        ok(locked_rect.Pitch == 128 * 4, "Got unexpected pitch %d.\n", locked_rect.Pitch);
+        ok(locked_rect.pBits == mem, "Got unexpected pBits %p, expected %p.\n", locked_rect.pBits, mem);
+        hr = IDirect3DSurface9_UnlockRect(surface);
+        ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+        IDirect3DSurface9_Release(surface);
+    }
+
     refcount = IDirect3DDevice9Ex_Release(device);
     ok(!refcount, "Device has %u references left.\n", refcount);
 
-- 
1.8.3.2




More information about the wine-patches mailing list