[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-patches
Subject:    d3dx9_36: Stub ID3DXRenderToSurface, with tests (try 2)
From:       Misha Koshelev <misha680 () gmail ! com>
Date:       2011-02-28 23:13:52
Message-ID: AANLkTinLJxD74JQ3OemDdQyLbMnrQ9mcOkAeaJES-Tb_ () mail ! gmail ! com
[Download RAW message or body]

Makes the The Last Dance proceed further, fixes bug #24899.

Sent per suggestion in
http://www.winehq.org/pipermail/wine-devel/2011-February/088914.html

Corrected per comments in
http://www.winehq.org/pipermail/wine-devel/2011-February/089074.html

Misha
---
 dlls/d3dx9_36/core.c        |  149 +++++++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/d3dx9_36.spec |    2 +-
 dlls/d3dx9_36/tests/core.c  |   87 +++++++++++++++++++++++++
 3 files changed, 237 insertions(+), 1 deletions(-)

["0001-d3dx9_36-Stub-ID3DXRenderToSurface-with-tests.txt" (text/x-patch)]

diff --git a/dlls/d3dx9_36/core.c b/dlls/d3dx9_36/core.c
index 6990fbd..9fadaa7 100644
--- a/dlls/d3dx9_36/core.c
+++ b/dlls/d3dx9_36/core.c
@@ -130,3 +130,152 @@ 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) +{
+    if (IsEqualGUID(riid, &IID_IUnknown)
+        || IsEqualGUID(riid, &IID_ID3DXRenderToSurface))
+    {
+        IUnknown_AddRef(iface);
+        *ppobj = iface;
+        return S_OK;
+    }
+
+    WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj);
+    *ppobj = NULL;
+    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) +{
+    FIXME("(%p)->(%p, %p): stub\n", iface, surface, viewport);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_EndScene(ID3DXRenderToSurface *iface, \
DWORD mipfilter) +{
+    FIXME("(%p)->(%u): stub\n", iface, 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) +{
+    FIXME("(%p): stub\n", iface);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ID3DXRenderToSurfaceImpl_OnResetDevice(ID3DXRenderToSurface \
*iface) +{
+    FIXME("(%p): stub\n", iface);
+
+    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 f91f962..c4f3dc6 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);





[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic