d3drm: Implement CreateTextureFromSurface() and related methods.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2017-06-05 02:07:30 +03:00 committed by Alexandre Julliard
parent 824c46207d
commit d3e47919bc
4 changed files with 111 additions and 39 deletions

View File

@ -407,9 +407,25 @@ static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface, static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
IDirectDrawSurface *surface, IDirect3DRMTexture **texture) 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, 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, static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture) 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, 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, static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture) 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, static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,

View File

@ -51,6 +51,7 @@ struct d3drm_texture
IDirect3DRMTexture3 IDirect3DRMTexture3_iface; IDirect3DRMTexture3 IDirect3DRMTexture3_iface;
IDirect3DRM *d3drm; IDirect3DRM *d3drm;
D3DRMIMAGE *image; D3DRMIMAGE *image;
IDirectDrawSurface *surface;
}; };
struct d3drm_frame struct d3drm_frame

View File

@ -2342,8 +2342,10 @@ static void test_Texture(void)
ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4); ok(ref4 == ref1, "expected ref4 == ref1, got ref1 = %u , ref4 = %u.\n", ref1, ref4);
/* Created from image, GetSurface() does not work. */ /* 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); hr = IDirect3DRMTexture3_GetSurface(texture3, 0, &surface);
todo_wine
ok(hr == D3DRMERR_NOTCREATEDFROMDDS, "GetSurface() expected to fail, %#x\n", hr); ok(hr == D3DRMERR_NOTCREATEDFROMDDS, "GetSurface() expected to fail, %#x\n", hr);
/* Test all failures together */ /* Test all failures together */
@ -6599,66 +6601,52 @@ static void test_create_texture_from_surface(void)
/* Test NULL params */ /* Test NULL params */
texture1 = (IDirect3DRMTexture *)0xdeadbeef; texture1 = (IDirect3DRMTexture *)0xdeadbeef;
hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, &texture1); hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, &texture1);
todo_wine {
ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1); ok(!texture1, "Expected texture returned == NULL, got %p.\n", texture1);
}
hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, NULL); hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, NULL, NULL);
todo_wine
ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
texture2 = (IDirect3DRMTexture2 *)0xdeadbeef; texture2 = (IDirect3DRMTexture2 *)0xdeadbeef;
hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, &texture2); hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, &texture2);
todo_wine {
ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2); ok(!texture2, "Expected texture returned == NULL, got %p.\n", texture2);
}
hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, NULL); hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, NULL, NULL);
todo_wine
ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
texture3 = (IDirect3DRMTexture3 *)0xdeadbeef; texture3 = (IDirect3DRMTexture3 *)0xdeadbeef;
hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, &texture3); hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, &texture3);
todo_wine {
ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3); ok(!texture3, "Expected texture returned == NULL, got %p.\n", texture3);
}
hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, NULL); hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, NULL, NULL);
todo_wine
ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr);
ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n"); ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, surface, &texture1); hr = IDirect3DRM_CreateTextureFromSurface(d3drm1, surface, &texture1);
todo_wine
ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
if (SUCCEEDED(hr))
{
ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n"); ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
image = IDirect3DRMTexture_GetImage(texture1); image = IDirect3DRMTexture_GetImage(texture1);
ok(image == NULL, "Unexpected image, %p.\n", image); ok(image == NULL, "Unexpected image, %p.\n", image);
hr = IDirect3DRMTexture_InitFromSurface(texture1, NULL); hr = IDirect3DRMTexture_InitFromSurface(texture1, NULL);
ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
IDirect3DRMTexture_Release(texture1); IDirect3DRMTexture_Release(texture1);
}
ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n"); ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, surface, &texture2); hr = IDirect3DRM2_CreateTextureFromSurface(d3drm2, surface, &texture2);
todo_wine
ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
if (SUCCEEDED(hr))
{
ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n"); ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
image = IDirect3DRMTexture2_GetImage(texture2); image = IDirect3DRMTexture2_GetImage(texture2);
ok(image == NULL, "Unexpected image, %p.\n", image); ok(image == NULL, "Unexpected image, %p.\n", image);
hr = IDirect3DRMTexture2_InitFromSurface(texture2, NULL); hr = IDirect3DRMTexture2_InitFromSurface(texture2, NULL);
ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr);
IDirect3DRMTexture_Release(texture2); IDirect3DRMTexture_Release(texture2);
}
ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n"); ok(get_refcount((IUnknown *)surface) == 1, "Unexpected surface refcount.\n");
hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, surface, &texture3); hr = IDirect3DRM3_CreateTextureFromSurface(d3drm3, surface, &texture3);
todo_wine
ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
if (SUCCEEDED(hr))
{
ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n"); ok(get_refcount((IUnknown *)surface) == 2, "Unexpected surface refcount.\n");
image = IDirect3DRMTexture3_GetImage(texture3); image = IDirect3DRMTexture3_GetImage(texture3);
ok(image == NULL, "Unexpected image, %p.\n", image); 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"); ok(ref3 == get_refcount((IUnknown *)d3drm3), "Expected d3drm3 reference unchanged.\n");
/* Release leaked reference to d3drm1 */ /* Release leaked reference to d3drm1 */
IDirect3DRM_Release(d3drm1); IDirect3DRM_Release(d3drm1);
IDirect3DRMTexture3_Release(texture3); IDirect3DRMTexture3_Release(texture3);
}
IDirectDrawSurface_Release(surface2); IDirectDrawSurface_Release(surface2);
IDirectDrawSurface_Release(surface); IDirectDrawSurface_Release(surface);
IDirect3DRM3_Release(d3drm3); IDirect3DRM3_Release(d3drm3);

View File

@ -45,8 +45,10 @@ static void d3drm_texture_destroy(struct d3drm_texture *texture)
TRACE("texture %p is being destroyed.\n", texture); TRACE("texture %p is being destroyed.\n", texture);
d3drm_object_cleanup((IDirect3DRMObject*)&texture->IDirect3DRMTexture_iface, &texture->obj); d3drm_object_cleanup((IDirect3DRMObject*)&texture->IDirect3DRMTexture_iface, &texture->obj);
if (texture->image) if (texture->image || texture->surface)
IDirect3DRM_Release(texture->d3drm); IDirect3DRM_Release(texture->d3drm);
if (texture->surface)
IDirectDrawSurface_Release(texture->surface);
HeapFree(GetProcessHeap(), 0, texture); 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, static HRESULT WINAPI d3drm_texture1_InitFromSurface(IDirect3DRMTexture *iface,
IDirectDrawSurface *surface) 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) 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, static HRESULT WINAPI d3drm_texture2_InitFromSurface(IDirect3DRMTexture2 *iface,
IDirectDrawSurface *surface) 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) 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, static HRESULT WINAPI d3drm_texture3_InitFromSurface(IDirect3DRMTexture3 *iface,
IDirectDrawSurface *surface) 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) 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. */ /* d3drm intentionally leaks a reference to IDirect3DRM here if texture has already been initialized. */
IDirect3DRM_AddRef(texture->d3drm); IDirect3DRM_AddRef(texture->d3drm);
if (texture->image) if (texture->image || texture->surface)
return D3DRMERR_BADOBJECT; return D3DRMERR_BADOBJECT;
texture->image = image; texture->image = image;
@ -1001,9 +1020,23 @@ static HRESULT WINAPI d3drm_texture3_GenerateMIPMap(IDirect3DRMTexture3 *iface,
static HRESULT WINAPI d3drm_texture3_GetSurface(IDirect3DRMTexture3 *iface, static HRESULT WINAPI d3drm_texture3_GetSurface(IDirect3DRMTexture3 *iface,
DWORD flags, IDirectDrawSurface **surface) 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) static HRESULT WINAPI d3drm_texture3_SetCacheOptions(IDirect3DRMTexture3 *iface, LONG importance, DWORD flags)