Module: wine Branch: master Commit: 62df35c312d9f65bb775e07d47ebab3ab8495110 URL: http://source.winehq.org/git/wine.git/?a=commit;h=62df35c312d9f65bb775e07d47...
Author: Stefan Dösinger stefan@codeweavers.com Date: Tue Dec 10 14:36:58 2013 +0100
d3d9: Implement user memory for offscreen plain surfaces.
---
dlls/d3d9/device.c | 31 ++++++++++++++++++++++++------- dlls/d3d9/tests/d3d9ex.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 598fff0..57252e7 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -947,7 +947,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; @@ -989,6 +989,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; @@ -1014,7 +1017,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, @@ -1037,7 +1040,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); }
@@ -1222,24 +1225,38 @@ 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_MANAGED) { WARN("Attempting to create a managed offscreen plain surface.\n"); return D3DERR_INVALIDCALL; } + + if (shared_handle) + { + if (pool == D3DPOOL_SYSTEMMEM) + user_mem = *shared_handle; + else + { + if (pool != D3DPOOL_DEFAULT) + { + WARN("Trying to create a shared surface in pool %#x.\n", pool); + return D3DERR_INVALIDCALL; + } + FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); + } + } + /* FIXME: Offscreen surfaces are supposed to be always lockable, * 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 22134c3..7f39d70 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; @@ -605,6 +606,36 @@ 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); + 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); + IDirect3DSurface9_Release(surface); + } + + hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, 128, 128, D3DFMT_A8R8G8B8, + D3DPOOL_SCRATCH, &surface, &mem); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(device, 128, 128, D3DFMT_A8R8G8B8, + D3DPOOL_SCRATCH, &surface, &mem, 0); + todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, mem); refcount = IDirect3DDevice9Ex_Release(device); ok(!refcount, "Device has %u references left.\n", refcount);