Somewhat barebones patch to implement D3DXCreateRenderToSurface for bug 24899, how much more needs to be implemented?
Misha Koshelev
misha680 at gmail.com
Thu Feb 17 19:10:37 CST 2011
On Thu, Feb 17, 2011 at 6:37 PM, Matteo Bruni <matteo.mystral at gmail.com> wrote:
> 2011/2/16 Misha Koshelev <misha680 at gmail.com>:
> The patch stubs all methods of ID3DXRenderToSurface, right? I think
> you can already send it, even if it lacks the actual implementation.
> Does it make any game go further?
Yes, it does stub those methods. Yes, it makes The Last Dance go
farther (marginally, but farther).
>
> I didn't look carefully at the code, one nitpick is to change the name
> of the test function called from inside START_TEST(core) to
> test_ID3DXRenderToSurface for consistency.
Thank you. I have attached the updated patch.
In the spirit of one thing at a time, if it is time to submit patches,
I will first send the single <-> half precision float conversion patch
that Stefan Dosinger has so graciously vetted quite a bit.
If there are any more comments on this patch (or on D3DXCreateTorus),
much appreciated.
Thank you
Misha
-------------- next part --------------
From cbec51efa076f52a4e1968fc235df77946e82c3e Mon Sep 17 00:00:00 2001
From: Misha Koshelev <misha680 at gmail.com>
Date: Thu, 17 Feb 2011 20:09:31 -0500
Subject: d3dx9: Implement barebones D3DXCreateRenderToSurface for bug 24899
To: wine-patches <wine-patches at winehq.org>
Reply-To: wine-devel <wine-devel at winehq.org>
---
dlls/d3dx9_36/core.c | 158 +++++++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/d3dx9_36.spec | 2 +-
dlls/d3dx9_36/tests/core.c | 87 ++++++++++++++++++++++++
3 files changed, 246 insertions(+), 1 deletions(-)
diff --git a/dlls/d3dx9_36/core.c b/dlls/d3dx9_36/core.c
index 6990fbd..7ef28b1 100644
--- a/dlls/d3dx9_36/core.c
+++ b/dlls/d3dx9_36/core.c
@@ -130,3 +130,161 @@ HRESULT WINAPI D3DXCreateBuffer(DWORD NumBytes, LPD3DXBUFFER* ppBuffer)
*ppBuffer = &object->ID3DXBuffer_iface;
return D3D_OK;
}
+
+typedef struct ID3DXRenderToSurfaceImpl
+{
+ ID3DXRenderToSurface ID3DXRenderToSurface_iface;
+ LONG ref;
+
+ D3DXRTS_DESC desc;
+ LPDIRECT3DDEVICE9 device;
+} ID3DXRenderToSurfaceImpl;
+
+static inline ID3DXRenderToSurfaceImpl *impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface *iface)
+{
+ return CONTAINING_RECORD(iface, ID3DXRenderToSurfaceImpl, ID3DXRenderToSurface_iface);
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_QueryInterface(ID3DXRenderToSurface *iface, REFIID riid, void **ppobj)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+
+ if (IsEqualGUID(riid, &IID_IUnknown)
+ || IsEqualGUID(riid, &IID_ID3DXRenderToSurface))
+ {
+ IUnknown_AddRef(iface);
+ *ppobj = This;
+ return D3D_OK;
+ }
+
+ WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ID3DXRenderToSurfaceImpl_AddRef(ID3DXRenderToSurface *iface)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p): AddRef from %d\n", This, ref - 1);
+
+ return ref;
+}
+
+static ULONG WINAPI ID3DXRenderToSurfaceImpl_Release(ID3DXRenderToSurface *iface)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p): ReleaseRef to %d\n", This, ref);
+
+ if (ref == 0)
+ {
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_BeginScene(ID3DXRenderToSurface *iface, LPDIRECT3DSURFACE9 surface, const D3DVIEWPORT9 *viewport)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+
+ FIXME("(%p)->(%p, %p): stub\n", This, surface, viewport);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_EndScene(ID3DXRenderToSurface *iface, DWORD mipfilter)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+
+ FIXME("(%p)->(%u): stub\n", This, mipfilter);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_GetDesc(ID3DXRenderToSurface *iface, D3DXRTS_DESC *parameters)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+
+ TRACE("(%p)->(%p)\n", This, parameters);
+
+ if (parameters == NULL) return D3DERR_INVALIDCALL;
+ *parameters = This->desc;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_GetDevice(ID3DXRenderToSurface *iface, LPDIRECT3DDEVICE9 *device)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+
+ TRACE("(%p)->(%p)\n", This, device);
+
+ if (device == NULL) return D3DERR_INVALIDCALL;
+ *device = This->device;
+ IDirect3DDevice9_AddRef(This->device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_OnLostDevice(ID3DXRenderToSurface *iface)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+
+ FIXME("(%p): stub\n", This);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_OnResetDevice(ID3DXRenderToSurface *iface)
+{
+ ID3DXRenderToSurfaceImpl *This = impl_from_ID3DXRenderToSurface(iface);
+
+ FIXME("(%p): stub\n", This);
+
+ return E_NOTIMPL;
+}
+
+const ID3DXRenderToSurfaceVtbl D3DXRenderToSurface_Vtbl =
+{
+ ID3DXRenderToSurfaceImpl_QueryInterface,
+ ID3DXRenderToSurfaceImpl_AddRef,
+ ID3DXRenderToSurfaceImpl_Release,
+ ID3DXRenderToSurfaceImpl_GetDevice,
+ ID3DXRenderToSurfaceImpl_GetDesc,
+ ID3DXRenderToSurfaceImpl_BeginScene,
+ ID3DXRenderToSurfaceImpl_EndScene,
+ ID3DXRenderToSurfaceImpl_OnLostDevice,
+ ID3DXRenderToSurfaceImpl_OnResetDevice
+};
+
+HRESULT WINAPI D3DXCreateRenderToSurface(LPDIRECT3DDEVICE9 device, UINT width, UINT height, D3DFORMAT format,
+ BOOL stencil, D3DFORMAT stencil_format, LPD3DXRENDERTOSURFACE *rts)
+{
+ ID3DXRenderToSurfaceImpl *object;
+
+ TRACE("(%p, %u, %u, %u, %u, %u, %p)\n", device, width, height, format, stencil, stencil_format, rts);
+
+ if (device == NULL || rts == NULL)
+ {
+ return D3DERR_INVALIDCALL;
+ }
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXRenderToSurfaceImpl));
+ if (object == NULL)
+ {
+ return E_OUTOFMEMORY;
+ }
+ object->ID3DXRenderToSurface_iface.lpVtbl = &D3DXRenderToSurface_Vtbl;
+ object->ref = 1;
+ object->device = device;
+ object->desc.Width = width;
+ object->desc.Height = height;
+ object->desc.Format = format;
+ object->desc.DepthStencil = stencil;
+ object->desc.DepthStencilFormat = stencil_format;
+
+ *rts = &object->ID3DXRenderToSurface_iface;
+ return D3D_OK;
+}
diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index cbb6d20..dc44e8d 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -82,7 +82,7 @@
@ stub D3DXCreatePRTCompBuffer
@ stub D3DXCreatePRTEngine
@ stub D3DXCreateRenderToEnvMap
-@ stub D3DXCreateRenderToSurface
+@ stdcall D3DXCreateRenderToSurface(ptr long long long long long ptr)
@ stub D3DXCreateSPMesh
@ stub D3DXCreateSkinInfo
@ stub D3DXCreateSkinInfoFromBlendedMesh
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c
index b1379ef..69087a2 100644
--- a/dlls/d3dx9_36/tests/core.c
+++ b/dlls/d3dx9_36/tests/core.c
@@ -417,6 +417,92 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
} else skip("Failed to create a ID3DXFont object\n");
}
+static inline BOOL test_create_render_to_surface(LPDIRECT3DDEVICE9 device, UINT width, UINT height, D3DFORMAT format,
+ BOOL stencil, D3DFORMAT stencil_format, LPD3DXRENDERTOSURFACE *rts,
+ HRESULT expected, BOOL release_on_success, unsigned int line)
+{
+ HRESULT hr;
+
+ hr = D3DXCreateRenderToSurface(device, width, height, format, stencil, stencil_format, rts);
+ ok(hr == expected, "Line %u, got result %x, expected %x\n", line, hr, expected);
+
+ if (SUCCEEDED(hr) && *rts && release_on_success)
+ {
+ ID3DXRenderToSurface_Release(*rts);
+ }
+
+ return SUCCEEDED(hr);
+}
+
+static void test_D3DXCreateRenderToSurface(IDirect3DDevice9 *device)
+{
+ D3DXRTS_DESC desc = { 200, 200, D3DFMT_UNKNOWN, FALSE, D3DFMT_UNKNOWN };
+ ID3DXRenderToSurface *rts;
+ HRESULT hr;
+ IDirect3DDevice9 *test_device;
+ D3DXRTS_DESC test_desc;
+
+ test_create_render_to_surface(NULL, desc.Width, desc.Height, desc.Format, desc.DepthStencil,
+ desc.DepthStencilFormat, &rts, D3DERR_INVALIDCALL, TRUE, __LINE__);
+ test_create_render_to_surface(device, -1, desc.Height, desc.Format, desc.DepthStencil,
+ desc.DepthStencilFormat, &rts, D3D_OK, TRUE, __LINE__);
+ test_create_render_to_surface(device, 0, desc.Height, desc.Format, desc.DepthStencil,
+ desc.DepthStencilFormat, &rts, D3D_OK, TRUE, __LINE__);
+ test_create_render_to_surface(device, desc.Width, -1, desc.Format, desc.DepthStencil,
+ desc.DepthStencilFormat, &rts, D3D_OK, TRUE, __LINE__);
+ test_create_render_to_surface(device, desc.Width, 0, desc.Format, desc.DepthStencil,
+ desc.DepthStencilFormat, &rts, D3D_OK, TRUE, __LINE__);
+ test_create_render_to_surface(device, desc.Width, desc.Height, -1, desc.DepthStencil,
+ desc.DepthStencilFormat, &rts, D3D_OK, TRUE, __LINE__);
+ test_create_render_to_surface(device, desc.Width, desc.Height, desc.Format, -1, desc.DepthStencilFormat,
+ &rts, D3D_OK, TRUE, __LINE__);
+ test_create_render_to_surface(device, desc.Width, desc.Height, desc.Format, desc.DepthStencil, -1, &rts,
+ D3D_OK, TRUE, __LINE__);
+ test_create_render_to_surface(device, desc.Width, desc.Height, desc.Format, desc.DepthStencil,
+ desc.DepthStencilFormat, NULL, D3DERR_INVALIDCALL, TRUE, __LINE__);
+
+ if (!test_create_render_to_surface(device, desc.Width, desc.Height, desc.Format, desc.DepthStencil,
+ desc.DepthStencilFormat, &rts, D3D_OK, FALSE, __LINE__))
+ {
+ skip("D3DXCreateRenderToSurface failed, skipping\n");
+ }
+ else
+ {
+ /* device */
+ hr = ID3DXRenderToSurface_GetDevice(rts, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToSurface_GetDevice(rts, &test_device);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(test_device == device, "Got result %p, expected %p\n", test_device, device);
+
+ if (hr == D3D_OK)
+ {
+ IDirect3DDevice9_Release(device);
+ }
+
+ /* description */
+ hr = ID3DXRenderToSurface_GetDesc(rts, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToSurface_GetDesc(rts, &test_desc);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ ok(test_desc.Width == desc.Width, "Returned width %d, expected %d\n", test_desc.Width, desc.Width);
+ ok(test_desc.Height == desc.Height, "Returned height %d, expected %d\n", test_desc.Height, desc.Height);
+ ok(test_desc.Format == desc.Format, "Returned format %d, expected %d\n", test_desc.Format, desc.Format);
+ ok(test_desc.DepthStencil == desc.DepthStencil, "Returned depth stencil %d, expected %d\n",
+ test_desc.DepthStencil, desc.DepthStencil);
+ ok(test_desc.DepthStencilFormat == desc.DepthStencilFormat, "Returned depth stencil format %d, expected %d\n",
+ test_desc.DepthStencilFormat, desc.DepthStencilFormat);
+ }
+
+ ID3DXRenderToSurface_Release(rts);
+ }
+}
+
START_TEST(core)
{
HWND wnd;
@@ -450,6 +536,7 @@ START_TEST(core)
test_ID3DXSprite(device);
test_ID3DXFont(device);
+ test_D3DXCreateRenderToSurface(device);
check_release((IUnknown*)device, 0);
check_release((IUnknown*)d3d, 0);
--
1.7.4
More information about the wine-devel
mailing list