[PATCH 2/5] d3drm: Implement CreateTextureFromSurface() and related methods

Nikolay Sivov nsivov at codeweavers.com
Sun Jun 4 18:07:30 CDT 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3drm/d3drm.c         | 63 +++++++++++++++++++++++++++++++++++++++++-----
 dlls/d3drm/d3drm_private.h |  1 +
 dlls/d3drm/tests/d3drm.c   | 33 ++++++++----------------
 dlls/d3drm/texture.c       | 53 ++++++++++++++++++++++++++++++--------
 4 files changed, 111 insertions(+), 39 deletions(-)

diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c
index 260cc7d217..31564364a5 100644
--- a/dlls/d3drm/d3drm.c
+++ b/dlls/d3drm/d3drm.c
@@ -407,9 +407,25 @@ static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
 static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
         IDirectDrawSurface *surface, IDirect3DRMTexture **texture)
 {
-    FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);
+    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
+    IDirect3DRMTexture3 *texture3;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
+
+    if (!texture)
+        return D3DRMERR_BADVALUE;
+
+    if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
+    {
+        *texture = NULL;
+        return hr;
+    }
+
+    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
+    IDirect3DRMTexture3_Release(texture3);
+
+    return hr;
 }
 
 static HRESULT WINAPI d3drm1_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
@@ -882,9 +898,25 @@ static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
 static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
         IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture)
 {
-    FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);
+    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
+    IDirect3DRMTexture3 *texture3;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
+
+    if (!texture)
+        return D3DRMERR_BADVALUE;
+
+    if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
+    {
+        *texture = NULL;
+        return hr;
+    }
+
+    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
+    IDirect3DRMTexture3_Release(texture3);
+
+    return hr;
 }
 
 static HRESULT WINAPI d3drm2_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
@@ -1484,9 +1516,28 @@ static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object,
 static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
         IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
 {
-    FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);
+    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
+    struct d3drm_texture *object;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
+
+    if (!texture)
+        return D3DRMERR_BADVALUE;
+
+    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
+        return hr;
+
+    *texture = &object->IDirect3DRMTexture3_iface;
+
+    if (FAILED(IDirect3DRMTexture3_InitFromSurface(*texture, surface)))
+    {
+        IDirect3DRMTexture3_Release(*texture);
+        *texture = NULL;
+        return D3DRMERR_BADVALUE;
+    }
+
+    return D3DRM_OK;
 }
 
 static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h
index 033fcffe98..cfef7885f4 100644
--- a/dlls/d3drm/d3drm_private.h
+++ b/dlls/d3drm/d3drm_private.h
@@ -51,6 +51,7 @@ struct d3drm_texture
     IDirect3DRMTexture3 IDirect3DRMTexture3_iface;
     IDirect3DRM *d3drm;
     D3DRMIMAGE *image;
+    IDirectDrawSurface *surface;
 };
 
 struct d3drm_frame
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index 90820a2499..411cd835f6 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -2342,8 +2342,10 @@ static void test_Texture(void)
     ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
 
     /* Created from image, GetSurface() does not work. */
+    hr = IDirect3DRMTexture3_GetSurface(texture3, 0, NULL);
+    ok(hr == D3DRMERR_BADVALUE, "GetSurface() expected to fail, %#x\n", hr);
+
     hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &surface);
-todo_wine
     ok(hr == D3DRMERR_NOTCREATEDFROMDDS, "GetSurface() expected to fail, %#x\n", hr);
 
     /* Test all failures together */
@@ -6599,66 +6601,52 @@ static void test_create_texture_from_surface(void)
     /* Test NULL params */
     texture1 = (IDirect3DRMTexture *)0xdeadbeef;
     hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, &texture1);
-todo_wine {
     ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
     ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1);
-}
+
     hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, NULL);
-todo_wine
     ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
 
     texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
     hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, &texture2);
-todo_wine {
     ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
     ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2);
-}
+
     hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, NULL);
-todo_wine
     ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
 
     texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
     hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, &texture3);
-todo_wine {
     ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
     ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3);
-}
+
     hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, NULL);
-todo_wine
     ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
 
     ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
     hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, surface, &texture1);
-todo_wine
     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
-if (SUCCEEDED(hr))
-{
+
     ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
     image = IDirect3DRMTexture_GetImage(texture1);
     ok(image == NULL, "Unexpected image, %p.\n", image);
     hr = IDirect3DRMTexture_InitFromSurface(texture1, NULL);
     ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
     IDirect3DRMTexture_Release(texture1);
-}
+
     ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
     hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, surface, &texture2);
-todo_wine
     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
-if (SUCCEEDED(hr))
-{
     ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
     image = IDirect3DRMTexture2_GetImage(texture2);
     ok(image == NULL, "Unexpected image, %p.\n", image);
     hr = IDirect3DRMTexture2_InitFromSurface(texture2, NULL);
     ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
     IDirect3DRMTexture_Release(texture2);
-}
+
     ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
     hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, surface, &texture3);
-todo_wine
     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
-if (SUCCEEDED(hr))
-{
     ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
     image = IDirect3DRMTexture3_GetImage(texture3);
     ok(image == NULL, "Unexpected image, %p.\n", image);
@@ -6711,9 +6699,8 @@ if (SUCCEEDED(hr))
     ok(ref3 == get_refcount((IUnknown *)d3drm3), "Expected d3drm3 reference unchanged.\n");
     /* Release leaked reference to d3drm1 */
     IDirect3DRM_Release(d3drm1);
-
     IDirect3DRMTexture3_Release(texture3);
-}
+
     IDirectDrawSurface_Release(surface2);
     IDirectDrawSurface_Release(surface);
     IDirect3DRM3_Release(d3drm3);
diff --git a/dlls/d3drm/texture.c b/dlls/d3drm/texture.c
index 5d621a05f8..3de22c6423 100644
--- a/dlls/d3drm/texture.c
+++ b/dlls/d3drm/texture.c
@@ -45,8 +45,10 @@ static void d3drm_texture_destroy(struct d3drm_texture *texture)
     TRACE("texture %p is being destroyed.\n", texture);
 
     d3drm_object_cleanup((IDirect3DRMObject*)&texture->IDirect3DRMTexture_iface, &texture->obj);
-    if (texture->image)
+    if (texture->image || texture->surface)
         IDirect3DRM_Release(texture->d3drm);
+    if (texture->surface)
+        IDirectDrawSurface_Release(texture->surface);
     HeapFree(GetProcessHeap(), 0, texture);
 }
 
@@ -177,9 +179,11 @@ static HRESULT WINAPI d3drm_texture1_InitFromFile(IDirect3DRMTexture *iface, con
 static HRESULT WINAPI d3drm_texture1_InitFromSurface(IDirect3DRMTexture *iface,
         IDirectDrawSurface *surface)
 {
-    FIXME("iface %p, surface %p stub!\n", iface, surface);
+    struct d3drm_texture *texture = impl_from_IDirect3DRMTexture(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, surface %p.\n", iface, surface);
+
+    return IDirect3DRMTexture3_InitFromSurface(&texture->IDirect3DRMTexture3_iface, surface);
 }
 
 static HRESULT WINAPI d3drm_texture1_InitFromResource(IDirect3DRMTexture *iface, HRSRC resource)
@@ -477,9 +481,11 @@ static HRESULT WINAPI d3drm_texture2_InitFromFile(IDirect3DRMTexture2 *iface, co
 static HRESULT WINAPI d3drm_texture2_InitFromSurface(IDirect3DRMTexture2 *iface,
         IDirectDrawSurface *surface)
 {
-    FIXME("iface %p, surface %p stub!\n", iface, surface);
+    struct d3drm_texture *texture = impl_from_IDirect3DRMTexture2(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, surface %p.\n", iface, surface);
+
+    return IDirect3DRMTexture3_InitFromSurface(&texture->IDirect3DRMTexture3_iface, surface);
 }
 
 static HRESULT WINAPI d3drm_texture2_InitFromResource(IDirect3DRMTexture2 *iface, HRSRC resource)
@@ -835,9 +841,22 @@ static HRESULT WINAPI d3drm_texture3_InitFromFile(IDirect3DRMTexture3 *iface, co
 static HRESULT WINAPI d3drm_texture3_InitFromSurface(IDirect3DRMTexture3 *iface,
         IDirectDrawSurface *surface)
 {
-    FIXME("iface %p, surface %p stub!\n", iface, surface);
+    struct d3drm_texture *texture = impl_from_IDirect3DRMTexture3(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, surface %p.\n", iface, surface);
+
+    if (!surface)
+        return D3DRMERR_BADOBJECT;
+
+    /* d3drm intentionally leaks a reference to IDirect3DRM here if texture has already been initialized. */
+    IDirect3DRM_AddRef(texture->d3drm);
+
+    if (texture->image || texture->surface)
+        return D3DRMERR_BADOBJECT;
+
+    texture->surface = surface;
+    IDirectDrawSurface_AddRef(texture->surface);
+    return D3DRM_OK;
 }
 
 static HRESULT WINAPI d3drm_texture3_InitFromResource(IDirect3DRMTexture3 *iface, HRSRC resource)
@@ -974,7 +993,7 @@ static HRESULT WINAPI d3drm_texture3_InitFromImage(IDirect3DRMTexture3 *iface, D
     /* d3drm intentionally leaks a reference to IDirect3DRM here if texture has already been initialized. */
     IDirect3DRM_AddRef(texture->d3drm);
 
-    if (texture->image)
+    if (texture->image || texture->surface)
         return D3DRMERR_BADOBJECT;
 
     texture->image = image;
@@ -1001,9 +1020,23 @@ static HRESULT WINAPI d3drm_texture3_GenerateMIPMap(IDirect3DRMTexture3 *iface,
 static HRESULT WINAPI d3drm_texture3_GetSurface(IDirect3DRMTexture3 *iface,
         DWORD flags, IDirectDrawSurface **surface)
 {
-    FIXME("iface %p, flags %#x, surface %p stub!\n", iface, flags, surface);
+    struct d3drm_texture *texture = impl_from_IDirect3DRMTexture3(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, flags %#x, surface %p.\n", iface, flags, surface);
+
+    if (flags)
+        FIXME("unexpected flags %#x.\n", flags);
+
+    if (!surface)
+        return D3DRMERR_BADVALUE;
+
+    if (texture->image)
+        return D3DRMERR_NOTCREATEDFROMDDS;
+
+    *surface = texture->surface;
+    IDirectDrawSurface_AddRef(*surface);
+
+    return D3DRM_OK;
 }
 
 static HRESULT WINAPI d3drm_texture3_SetCacheOptions(IDirect3DRMTexture3 *iface, LONG importance, DWORD flags)
-- 
2.11.0




More information about the wine-patches mailing list