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