Surface interface is only supported for 1D and 2D texture, but all objects are represented as resources.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d11/tests/d3d11.c | 93 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index a43e2bb0cc5..9c72de054c4 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -2499,6 +2499,63 @@ static void test_create_texture1d(void) ok(!refcount, "Device has %lu references left.\n", refcount); }
+#define test_dxgi_resource(a) test_dxgi_resource_(__LINE__, a) +static void test_dxgi_resource_(unsigned int line, void *iface) +{ + IDXGIResource *resource, *resource2; + IDXGISurface *surface, *surface2; + IUnknown *object = iface, *unk; + DWORD data; + HRESULT hr; + UINT size; + + hr = IUnknown_QueryInterface(object, &IID_IDXGIResource, (void **)&resource); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + if (SUCCEEDED(IUnknown_QueryInterface(object, &IID_IDXGISurface, (void **)&surface))) + { + hr = IDXGISurface_QueryInterface(surface, &IID_IDXGIDeviceSubObject, (void **)&unk); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)((IUnknown *)resource == unk, "Unexpected interface pointer.\n"); + IUnknown_Release(unk); + + hr = IDXGISurface_QueryInterface(surface, &IID_IDXGIObject, (void **)&unk); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)((IUnknown *)resource == unk, "Unexpected interface pointer.\n"); + IUnknown_Release(unk); + + hr = IDXGISurface_QueryInterface(surface, &IID_IDXGIResource, (void **)&resource2); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(resource2 == resource, "Unexpected resource pointer.\n"); + IDXGIResource_Release(resource2); + + hr = IDXGIResource_QueryInterface(resource, &IID_IDXGISurface, (void **)&surface2); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(surface2 == surface, "Unexpected surface pointer.\n"); + IDXGISurface_Release(surface2); + + hr = IDXGISurface_GetParent(surface, &IID_IDXGIResource, (void **)&resource2); + ok_(__FILE__, line)(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + hr = IDXGIResource_GetParent(resource, &IID_IDXGISurface, (void **)&surface2); + ok_(__FILE__, line)(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + + data = 123; + hr = IDXGIResource_SetPrivateData(resource, &IID_IUnknown, sizeof(data), &data); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + size = sizeof(data); + data = 0; + hr = IDXGISurface_GetPrivateData(surface, &IID_IUnknown, &size, &data); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(data == 123, "Unexpected data %#lx.\n", data); + + IDXGISurface_Release(surface); + } + + IDXGIResource_Release(resource); +} + static void test_texture1d_interfaces(void) { ID3D10Texture1D *d3d10_texture; @@ -2548,7 +2605,7 @@ static void test_texture1d_interfaces(void) }
desc.Width = 512; - desc.MipLevels = 0; + desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.Usage = D3D11_USAGE_DEFAULT; @@ -2558,7 +2615,18 @@ static void test_texture1d_interfaces(void)
hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine + test_dxgi_resource(texture); + ID3D11Texture1D_Release(texture); + + desc.MipLevels = 0; + hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine + test_dxgi_resource(texture); check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); + todo_wine + check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); hr = check_interface(texture, &IID_ID3D10Texture1D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture1D_Release(texture); if (FAILED(hr)) @@ -2934,7 +3002,7 @@ static void test_texture2d_interfaces(void)
desc.Width = 512; desc.Height = 512; - desc.MipLevels = 0; + desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.SampleDesc.Count = 1; @@ -2944,9 +3012,23 @@ static void test_texture2d_interfaces(void) desc.CPUAccessFlags = 0; desc.MiscFlags = 0;
+ hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + check_interface(texture, &IID_IDXGISurface, TRUE, FALSE); + todo_wine + check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); + todo_wine + test_dxgi_resource(texture); + ID3D11Texture2D_Release(texture); + + desc.MipLevels = 0; hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); + todo_wine + check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); + todo_wine + test_dxgi_resource(texture); hr = check_interface(texture, &IID_ID3D10Texture2D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture2D_Release(texture); if (FAILED(hr)) @@ -3211,6 +3293,10 @@ static void test_texture3d_interfaces(void) hr = ID3D11Device_CreateTexture3D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); + todo_wine + check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); + todo_wine + test_dxgi_resource(texture); hr = check_interface(texture, &IID_ID3D10Texture3D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture3D_Release(texture); if (FAILED(hr)) @@ -3526,6 +3612,9 @@ static void test_create_buffer(void) continue; }
+ todo_wine + check_interface(buffer, &IID_IDXGIResource, TRUE, FALSE); + if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)) desc.StructureByteStride = 0;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116523
Your paranoid android.
=== build (build log) ===
WineRunBuild.pl:error: The build timed out
=== debian11 (64 bit WoW report) ===
d3d11: d3d11.c:16840: Test failed: Dim 1, Test 15: At layer 0, (0,0,0), expected 0x00c01001, got 0x00000000.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 33e9ead31ad..5fd0ba89054 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -1265,6 +1265,8 @@ static void test_create_surface(void) hr = IDXGIDevice_CreateSurface(device, &desc, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT, NULL, &surface); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ todo_wine + check_interface(surface, &IID_IDXGIResource, TRUE, FALSE); check_interface(surface, &IID_ID3D10Texture2D, TRUE, FALSE); /* Not available on all Windows versions. */ check_interface(surface, &IID_ID3D11Texture2D, TRUE, TRUE);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116524
Your paranoid android.
=== debian11 (32 bit report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit Arabic:Morocco report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit German report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit French report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit Hebrew:Israel report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit Hindi:India report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit Japanese:Japan report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit Chinese:China report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (32 bit WoW report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 00000000.
=== debian11 (64 bit WoW report) ===
dxgi: dxgi.c:1269: Test succeeded inside todo block: Got unexpected pointer 0000000000000000.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d11/d3d11_private.h | 4 +- dlls/d3d11/tests/d3d11.c | 7 - dlls/d3d11/texture.c | 130 ++++++------ dlls/dxgi/Makefile.in | 2 +- dlls/dxgi/device.c | 24 +-- dlls/dxgi/dxgi_private.h | 11 +- dlls/dxgi/resource.c | 423 +++++++++++++++++++++++++++++++++++++ dlls/dxgi/surface.c | 296 -------------------------- dlls/dxgi/tests/dxgi.c | 32 ++- include/wine/winedxgi.idl | 7 +- 10 files changed, 525 insertions(+), 411 deletions(-) create mode 100644 dlls/dxgi/resource.c delete mode 100644 dlls/dxgi/surface.c
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 29a01dd91ad..4e4efcae098 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -130,7 +130,7 @@ struct d3d_texture1d LONG refcount;
struct wined3d_private_store private_store; - IUnknown *dxgi_surface; + IUnknown *dxgi_resource; struct wined3d_texture *wined3d_texture; D3D11_TEXTURE1D_DESC desc; ID3D11Device2 *device; @@ -149,7 +149,7 @@ struct d3d_texture2d LONG refcount;
struct wined3d_private_store private_store; - IUnknown *dxgi_surface; + IUnknown *dxgi_resource; struct wined3d_texture *wined3d_texture; D3D11_TEXTURE2D_DESC desc; ID3D11Device2 *device; diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 9c72de054c4..0c741283da5 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -2615,17 +2615,14 @@ static void test_texture1d_interfaces(void)
hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine test_dxgi_resource(texture); ID3D11Texture1D_Release(texture);
desc.MipLevels = 0; hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine test_dxgi_resource(texture); check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); - todo_wine check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); hr = check_interface(texture, &IID_ID3D10Texture1D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture1D_Release(texture); @@ -3015,9 +3012,7 @@ static void test_texture2d_interfaces(void) hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check_interface(texture, &IID_IDXGISurface, TRUE, FALSE); - todo_wine check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); - todo_wine test_dxgi_resource(texture); ID3D11Texture2D_Release(texture);
@@ -3025,9 +3020,7 @@ static void test_texture2d_interfaces(void) hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); - todo_wine check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); - todo_wine test_dxgi_resource(texture); hr = check_interface(texture, &IID_ID3D10Texture2D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture2D_Release(texture); diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index 09ba1136f97..b3f4d7132be 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -54,10 +54,10 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_QueryInterface(ID3D11Texture1D return S_OK; }
- if (texture->dxgi_surface) + if (texture->dxgi_resource) { - TRACE("Forwarding to dxgi surface.\n"); - return IUnknown_QueryInterface(texture->dxgi_surface, iid, out); + TRACE("Forwarding to dxgi resource.\n"); + return IUnknown_QueryInterface(texture->dxgi_resource, iid, out); }
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); @@ -120,8 +120,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_GetPrivateData(ID3D11Texture1D
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_surface - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (texture->dxgi_resource + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) { hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data); IDXGISurface_Release(dxgi_surface); @@ -140,8 +140,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateData(ID3D11Texture1D
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_surface - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (texture->dxgi_resource + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) { hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data); IDXGISurface_Release(dxgi_surface); @@ -160,8 +160,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateDataInterface(ID3D11T
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- if (texture->dxgi_surface - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (texture->dxgi_resource + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) { hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data); IDXGISurface_Release(dxgi_surface); @@ -256,8 +256,8 @@ static void STDMETHODCALLTYPE d3d_texture1d_wined3d_object_released(void *parent { struct d3d_texture1d *texture = parent;
- if (texture->dxgi_surface) - IUnknown_Release(texture->dxgi_surface); + if (texture->dxgi_resource) + IUnknown_Release(texture->dxgi_resource); wined3d_private_store_cleanup(&texture->private_store); heap_free(texture); } @@ -425,7 +425,9 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE { struct wined3d_resource_desc wined3d_desc; struct d3d_texture1d *texture; + IWineDXGIDevice *wine_device; unsigned int levels; + BOOL needs_surface; DWORD flags = 0; HRESULT hr;
@@ -472,30 +474,26 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE return hr; }
- if (desc->MipLevels == 1 && desc->ArraySize == 1) + if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, + (void **)&wine_device))) { - IWineDXGIDevice *wine_device; - - if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, - (void **)&wine_device))) - { - ERR("Device should implement IWineDXGIDevice.\n"); - wined3d_texture_decref(texture->wined3d_texture); - wined3d_mutex_unlock(); - return E_FAIL; - } - - hr = IWineDXGIDevice_create_surface(wine_device, texture->wined3d_texture, 0, NULL, - (IUnknown *)&texture->ID3D10Texture1D_iface, (void **)&texture->dxgi_surface); - IWineDXGIDevice_Release(wine_device); - if (FAILED(hr)) - { - ERR("Failed to create DXGI surface, returning %#.lx\n", hr); - texture->dxgi_surface = NULL; - wined3d_texture_decref(texture->wined3d_texture); - wined3d_mutex_unlock(); - return hr; - } + ERR("Device should implement IWineDXGIDevice.\n"); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return E_FAIL; + } + + needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1; + hr = IWineDXGIDevice_create_resource(wine_device, wined3d_texture_get_resource(texture->wined3d_texture), + 0, NULL, (IUnknown *)&texture->ID3D10Texture1D_iface, needs_surface, (void **)&texture->dxgi_resource); + IWineDXGIDevice_Release(wine_device); + if (FAILED(hr)) + { + ERR("Failed to create DXGI resource, returning %#.lx\n", hr); + texture->dxgi_resource = NULL; + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return hr; } wined3d_mutex_unlock();
@@ -533,10 +531,10 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(ID3D11Texture2D return S_OK; }
- if (texture->dxgi_surface) + if (texture->dxgi_resource) { - TRACE("Forwarding to dxgi surface.\n"); - return IUnknown_QueryInterface(texture->dxgi_surface, riid, object); + TRACE("Forwarding to dxgi resource.\n"); + return IUnknown_QueryInterface(texture->dxgi_resource, riid, object); }
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); @@ -599,8 +597,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(ID3D11Texture2D
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_surface - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (texture->dxgi_resource + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) { hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data); IDXGISurface_Release(dxgi_surface); @@ -619,8 +617,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(ID3D11Texture2D
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_surface - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (texture->dxgi_resource + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) { hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data); IDXGISurface_Release(dxgi_surface); @@ -639,8 +637,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(ID3D11T
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- if (texture->dxgi_surface - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (texture->dxgi_resource + && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) { hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data); IDXGISurface_Release(dxgi_surface); @@ -750,7 +748,7 @@ static void STDMETHODCALLTYPE d3d_texture2d_wined3d_object_released(void *parent { struct d3d_texture2d *texture = parent;
- if (texture->dxgi_surface) IUnknown_Release(texture->dxgi_surface); + if (texture->dxgi_resource) IUnknown_Release(texture->dxgi_resource); wined3d_private_store_cleanup(&texture->private_store); heap_free(texture); } @@ -965,7 +963,9 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE { struct wined3d_resource_desc wined3d_desc; struct d3d_texture2d *texture; + IWineDXGIDevice *wine_device; unsigned int levels; + BOOL needs_surface; DWORD flags = 0; HRESULT hr;
@@ -1019,30 +1019,26 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE } texture->desc.MipLevels = levels;
- if (desc->MipLevels == 1 && desc->ArraySize == 1) + if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, + (void **)&wine_device))) { - IWineDXGIDevice *wine_device; - - if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, - (void **)&wine_device))) - { - ERR("Device should implement IWineDXGIDevice.\n"); - wined3d_texture_decref(texture->wined3d_texture); - wined3d_mutex_unlock(); - return E_FAIL; - } - - hr = IWineDXGIDevice_create_surface(wine_device, texture->wined3d_texture, 0, NULL, - (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface); - IWineDXGIDevice_Release(wine_device); - if (FAILED(hr)) - { - ERR("Failed to create DXGI surface, returning %#.lx\n", hr); - texture->dxgi_surface = NULL; - wined3d_texture_decref(texture->wined3d_texture); - wined3d_mutex_unlock(); - return hr; - } + ERR("Device should implement IWineDXGIDevice.\n"); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return E_FAIL; + } + + needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1; + hr = IWineDXGIDevice_create_resource(wine_device, wined3d_texture_get_resource(texture->wined3d_texture), + 0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, needs_surface, (void **)&texture->dxgi_resource); + IWineDXGIDevice_Release(wine_device); + if (FAILED(hr)) + { + ERR("Failed to create DXGI resource, returning %#.lx\n", hr); + texture->dxgi_resource = NULL; + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return hr; } wined3d_mutex_unlock();
diff --git a/dlls/dxgi/Makefile.in b/dlls/dxgi/Makefile.in index db52f49a68a..dea2e4b58f7 100644 --- a/dlls/dxgi/Makefile.in +++ b/dlls/dxgi/Makefile.in @@ -9,7 +9,7 @@ C_SRCS = \ dxgi_main.c \ factory.c \ output.c \ - surface.c \ + resource.c \ swapchain.c \ utils.c
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index b9c5ff177c9..efa04e0f495 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -326,31 +326,31 @@ static void STDMETHODCALLTYPE dxgi_device_Trim(IWineDXGIDevice *iface)
/* IWineDXGIDevice methods */
-static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *iface, - struct wined3d_texture *wined3d_texture, DXGI_USAGE usage, - const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, void **surface) +static HRESULT STDMETHODCALLTYPE dxgi_device_create_resource(IWineDXGIDevice *iface, + struct wined3d_resource *wined3d_resource, DXGI_USAGE usage, + const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, BOOL needs_surface, void **resource) { - struct dxgi_surface *object; + struct dxgi_resource *object; HRESULT hr;
- TRACE("iface %p, wined3d_texture %p, usage %#x, shared_resource %p, outer %p, surface %p.\n", - iface, wined3d_texture, usage, shared_resource, outer, surface); + TRACE("iface %p, wined3d_resource %p, usage %#x, shared_resource %p, outer %p, surface %p.\n", + iface, wined3d_resource, usage, shared_resource, outer, resource);
if (!(object = heap_alloc_zero(sizeof(*object)))) { - ERR("Failed to allocate DXGI surface object memory.\n"); + ERR("Failed to allocate DXGI resource object memory.\n"); return E_OUTOFMEMORY; }
- if (FAILED(hr = dxgi_surface_init(object, (IDXGIDevice *)iface, outer, wined3d_texture))) + if (FAILED(hr = dxgi_resource_init(object, (IDXGIDevice *)iface, outer, needs_surface, wined3d_resource))) { - WARN("Failed to initialize surface, hr %#lx.\n", hr); + WARN("Failed to initialize resource, hr %#lx.\n", hr); heap_free(object); return hr; }
- TRACE("Created IDXGISurface %p.\n", object); - *surface = outer ? &object->IUnknown_iface : (IUnknown *)&object->IDXGISurface1_iface; + TRACE("Created resource %p.\n", object); + *resource = outer ? &object->IUnknown_iface : (IUnknown *)&object->IDXGIResource_iface;
return S_OK; } @@ -382,7 +382,7 @@ static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl = /* IDXGIDevice3 methods */ dxgi_device_Trim, /* IWineDXGIDevice methods */ - dxgi_device_create_surface, + dxgi_device_create_resource, };
static inline struct dxgi_device *impl_from_IWineDXGISwapChainFactory(IWineDXGISwapChainFactory *iface) diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index b3cd1164b90..dd17e39eca6 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -194,20 +194,21 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu
BOOL dxgi_validate_swapchain_desc(const DXGI_SWAP_CHAIN_DESC1 *desc) DECLSPEC_HIDDEN;
-/* IDXGISurface */ -struct dxgi_surface +/* IDXGISurface/IDXGIResource */ +struct dxgi_resource { IDXGISurface1 IDXGISurface1_iface; + IDXGIResource IDXGIResource_iface; IUnknown IUnknown_iface; IUnknown *outer_unknown; LONG refcount; struct wined3d_private_store private_store; IDXGIDevice *device; - struct wined3d_texture *wined3d_texture; + struct wined3d_resource *wined3d_resource; HDC dc; };
-HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, - IUnknown *outer, struct wined3d_texture *wined3d_texture) DECLSPEC_HIDDEN; +HRESULT dxgi_resource_init(struct dxgi_resource *resource, IDXGIDevice *device, + IUnknown *outer, BOOL needs_surface, struct wined3d_resource *wined3d_resource) DECLSPEC_HIDDEN;
#endif /* __WINE_DXGI_PRIVATE_H */ diff --git a/dlls/dxgi/resource.c b/dlls/dxgi/resource.c new file mode 100644 index 00000000000..86ad4ec3f09 --- /dev/null +++ b/dlls/dxgi/resource.c @@ -0,0 +1,423 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +/* Inner IUnknown methods */ + +static inline struct dxgi_resource *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_resource, IUnknown_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_resource_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out) +{ + struct dxgi_resource *resource = impl_from_IUnknown(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if ((IsEqualGUID(riid, &IID_IDXGISurface1) + || IsEqualGUID(riid, &IID_IDXGISurface)) && resource->IDXGISurface1_iface.lpVtbl != NULL) + { + IDXGISurface1_AddRef(&resource->IDXGISurface1_iface); + *out = &resource->IDXGISurface1_iface; + return S_OK; + } + else if (IsEqualGUID(riid, &IID_IDXGIResource) + || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IDXGIResource_AddRef(&resource->IDXGIResource_iface); + *out = &resource->IDXGIResource_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_resource_inner_AddRef(IUnknown *iface) +{ + struct dxgi_resource *resource = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&resource->refcount); + + TRACE("%p increasing refcount to %lu.\n", resource, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_resource_inner_Release(IUnknown *iface) +{ + struct dxgi_resource *resource = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&resource->refcount); + + TRACE("%p decreasing refcount to %lu.\n", resource, refcount); + + if (!refcount) + { + wined3d_private_store_cleanup(&resource->private_store); + heap_free(resource); + } + + return refcount; +} + +static inline struct dxgi_resource *impl_from_IDXGISurface1(IDXGISurface1 *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_resource, IDXGISurface1_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface1 *iface, REFIID riid, + void **object) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_QueryInterface(&resource->IDXGIResource_iface, riid, object); +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface1 *iface) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_AddRef(&resource->IDXGIResource_iface); +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface1 *iface) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_Release(&resource->IDXGIResource_iface); +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface1 *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_SetPrivateData(&resource->IDXGIResource_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateDataInterface(IDXGISurface1 *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_SetPrivateDataInterface(&resource->IDXGIResource_iface, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetPrivateData(IDXGISurface1 *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_GetPrivateData(&resource->IDXGIResource_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetParent(IDXGISurface1 *iface, REFIID riid, void **parent) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_GetParent(&resource->IDXGIResource_iface, riid, parent); +} + +/* IDXGIDeviceSubObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDevice(IDXGISurface1 *iface, REFIID riid, void **device) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + return IDXGIResource_GetDevice(&resource->IDXGIResource_iface, riid, device); +} + +/* IDXGISurface methods */ +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDesc(IDXGISurface1 *iface, DXGI_SURFACE_DESC *desc) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + struct wined3d_resource_desc wined3d_desc; + + TRACE("iface %p, desc %p.\n", iface, desc); + + wined3d_mutex_lock(); + wined3d_resource_get_desc(resource->wined3d_resource, &wined3d_desc); + wined3d_mutex_unlock(); + desc->Width = wined3d_desc.width; + desc->Height = wined3d_desc.height; + desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.format); + dxgi_sample_desc_from_wined3d(&desc->SampleDesc, wined3d_desc.multisample_type, wined3d_desc.multisample_quality); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_Map(IDXGISurface1 *iface, DXGI_MAPPED_RECT *mapped_rect, UINT flags) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + struct wined3d_map_desc wined3d_map_desc; + DWORD wined3d_map_flags = 0; + HRESULT hr; + + TRACE("iface %p, mapped_rect %p, flags %#x.\n", iface, mapped_rect, flags); + + if (flags & DXGI_MAP_READ) + wined3d_map_flags |= WINED3D_MAP_READ; + if (flags & DXGI_MAP_WRITE) + wined3d_map_flags |= WINED3D_MAP_WRITE; + if (flags & DXGI_MAP_DISCARD) + wined3d_map_flags |= WINED3D_MAP_DISCARD; + + if (SUCCEEDED(hr = wined3d_resource_map(resource->wined3d_resource, 0, &wined3d_map_desc, NULL, wined3d_map_flags))) + { + mapped_rect->Pitch = wined3d_map_desc.row_pitch; + mapped_rect->pBits = wined3d_map_desc.data; + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_Unmap(IDXGISurface1 *iface) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + + TRACE("iface %p.\n", iface); + wined3d_resource_unmap(resource->wined3d_resource, 0); + return S_OK; +} + +/* IDXGISurface1 methods */ +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDC(IDXGISurface1 *iface, BOOL discard, HDC *hdc) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + HRESULT hr; + + FIXME("iface %p, discard %d, hdc %p semi-stub!\n", iface, discard, hdc); + + if (!hdc) + return E_INVALIDARG; + + wined3d_mutex_lock(); + hr = wined3d_texture_get_dc(wined3d_texture_from_resource(resource->wined3d_resource), 0, hdc); + wined3d_mutex_unlock(); + + if (SUCCEEDED(hr)) + resource->dc = *hdc; + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_ReleaseDC(IDXGISurface1 *iface, RECT *dirty_rect) +{ + struct dxgi_resource *resource = impl_from_IDXGISurface1(iface); + HRESULT hr; + + TRACE("iface %p, rect %s\n", iface, wine_dbgstr_rect(dirty_rect)); + + if (!IsRectEmpty(dirty_rect)) + FIXME("dirty rectangle is ignored.\n"); + + wined3d_mutex_lock(); + hr = wined3d_texture_release_dc(wined3d_texture_from_resource(resource->wined3d_resource), 0, resource->dc); + wined3d_mutex_unlock(); + + return hr; +} + +static const struct IDXGISurface1Vtbl dxgi_surface_vtbl = +{ + /* IUnknown methods */ + dxgi_surface_QueryInterface, + dxgi_surface_AddRef, + dxgi_surface_Release, + /* IDXGIObject methods */ + dxgi_surface_SetPrivateData, + dxgi_surface_SetPrivateDataInterface, + dxgi_surface_GetPrivateData, + dxgi_surface_GetParent, + /* IDXGIDeviceSubObject methods */ + dxgi_surface_GetDevice, + /* IDXGISurface methods */ + dxgi_surface_GetDesc, + dxgi_surface_Map, + dxgi_surface_Unmap, + /* IDXGISurface1 methods */ + dxgi_surface_GetDC, + dxgi_surface_ReleaseDC, +}; + +static inline struct dxgi_resource *impl_from_IDXGIResource(IDXGIResource *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_resource, IDXGIResource_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_resource_QueryInterface(IDXGIResource *iface, REFIID riid, + void **object) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_QueryInterface(resource->outer_unknown, riid, object); +} + +static ULONG STDMETHODCALLTYPE dxgi_resource_AddRef(IDXGIResource *iface) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_AddRef(resource->outer_unknown); +} + +static ULONG STDMETHODCALLTYPE dxgi_resource_Release(IDXGIResource *iface) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_Release(resource->outer_unknown); +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_resource_SetPrivateData(IDXGIResource *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_set_private_data(&resource->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_resource_SetPrivateDataInterface(IDXGIResource *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + + TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); + + return dxgi_set_private_data_interface(&resource->private_store, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_resource_GetPrivateData(IDXGIResource *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return dxgi_get_private_data(&resource->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_resource_GetParent(IDXGIResource *iface, REFIID riid, void **parent) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + return IDXGIDevice_QueryInterface(resource->device, riid, parent); +} + +/* IDXGIDeviceSubObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_resource_GetDevice(IDXGIResource *iface, REFIID riid, void **device) +{ + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + + TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device); + + return IDXGIDevice_QueryInterface(resource->device, riid, device); +} + +/* IDXGIResource methods */ +static HRESULT STDMETHODCALLTYPE dxgi_resource_GetSharedHandle(IDXGIResource *iface, HANDLE *shared_handle) +{ + FIXME("iface %p, shared_handle %p stub!\n", iface, shared_handle); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_resource_GetUsage(IDXGIResource *iface, DXGI_USAGE *usage) +{ + FIXME("iface %p, usage %p stub!\n", iface, usage); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_resource_SetEvictionPriority(IDXGIResource *iface, UINT eviction_priority) +{ + FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_resource_GetEvictionPriority(IDXGIResource *iface, UINT *eviction_priority) +{ + FIXME("iface %p, eviction_priority %p stub!\n", iface, eviction_priority); + + return E_NOTIMPL; +} + +static const struct IDXGIResourceVtbl dxgi_resource_vtbl = +{ + /* IUnknown methods */ + dxgi_resource_QueryInterface, + dxgi_resource_AddRef, + dxgi_resource_Release, + /* IDXGIObject methods */ + dxgi_resource_SetPrivateData, + dxgi_resource_SetPrivateDataInterface, + dxgi_resource_GetPrivateData, + dxgi_resource_GetParent, + /* IDXGIDeviceSubObject methods */ + dxgi_resource_GetDevice, + /* IDXGIResource methods */ + dxgi_resource_GetSharedHandle, + dxgi_resource_GetUsage, + dxgi_resource_SetEvictionPriority, + dxgi_resource_GetEvictionPriority, +}; + +static const struct IUnknownVtbl dxgi_resource_inner_unknown_vtbl = +{ + /* IUnknown methods */ + dxgi_resource_inner_QueryInterface, + dxgi_resource_inner_AddRef, + dxgi_resource_inner_Release, +}; + +HRESULT dxgi_resource_init(struct dxgi_resource *resource, IDXGIDevice *device, + IUnknown *outer, BOOL needs_surface, struct wined3d_resource *wined3d_resource) +{ + struct wined3d_resource_desc desc; + + wined3d_resource_get_desc(wined3d_resource, &desc); + if ((desc.resource_type == WINED3D_RTYPE_TEXTURE_1D || desc.resource_type == WINED3D_RTYPE_TEXTURE_2D) + && needs_surface) + { + resource->IDXGISurface1_iface.lpVtbl = &dxgi_surface_vtbl; + } + else + resource->IDXGISurface1_iface.lpVtbl = NULL; + resource->IDXGIResource_iface.lpVtbl = &dxgi_resource_vtbl; + resource->IUnknown_iface.lpVtbl = &dxgi_resource_inner_unknown_vtbl; + resource->refcount = 1; + wined3d_private_store_init(&resource->private_store); + resource->outer_unknown = outer ? outer : &resource->IUnknown_iface; + resource->device = device; + resource->wined3d_resource = wined3d_resource; + resource->dc = NULL; + + return S_OK; +} diff --git a/dlls/dxgi/surface.c b/dlls/dxgi/surface.c deleted file mode 100644 index 628e335ee0d..00000000000 --- a/dlls/dxgi/surface.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright 2009 Henri Verbeet for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#include "dxgi_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(dxgi); - -/* Inner IUnknown methods */ - -static inline struct dxgi_surface *impl_from_IUnknown(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, struct dxgi_surface, IUnknown_iface); -} - -static HRESULT STDMETHODCALLTYPE dxgi_surface_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out) -{ - struct dxgi_surface *surface = impl_from_IUnknown(iface); - - TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); - - if (IsEqualGUID(riid, &IID_IDXGISurface1) - || IsEqualGUID(riid, &IID_IDXGISurface) - || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject) - || IsEqualGUID(riid, &IID_IDXGIObject) - || IsEqualGUID(riid, &IID_IUnknown)) - { - IDXGISurface1_AddRef(&surface->IDXGISurface1_iface); - *out = &surface->IDXGISurface1_iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); - - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE dxgi_surface_inner_AddRef(IUnknown *iface) -{ - struct dxgi_surface *surface = impl_from_IUnknown(iface); - ULONG refcount = InterlockedIncrement(&surface->refcount); - - TRACE("%p increasing refcount to %lu.\n", surface, refcount); - - return refcount; -} - -static ULONG STDMETHODCALLTYPE dxgi_surface_inner_Release(IUnknown *iface) -{ - struct dxgi_surface *surface = impl_from_IUnknown(iface); - ULONG refcount = InterlockedDecrement(&surface->refcount); - - TRACE("%p decreasing refcount to %lu.\n", surface, refcount); - - if (!refcount) - { - wined3d_private_store_cleanup(&surface->private_store); - heap_free(surface); - } - - return refcount; -} - -static inline struct dxgi_surface *impl_from_IDXGISurface1(IDXGISurface1 *iface) -{ - return CONTAINING_RECORD(iface, struct dxgi_surface, IDXGISurface1_iface); -} - -/* IUnknown methods */ - -static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface1 *iface, REFIID riid, - void **object) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - TRACE("Forwarding to outer IUnknown\n"); - return IUnknown_QueryInterface(surface->outer_unknown, riid, object); -} - -static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface1 *iface) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - TRACE("Forwarding to outer IUnknown\n"); - return IUnknown_AddRef(surface->outer_unknown); -} - -static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface1 *iface) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - TRACE("Forwarding to outer IUnknown\n"); - return IUnknown_Release(surface->outer_unknown); -} - -/* IDXGIObject methods */ - -static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface1 *iface, - REFGUID guid, UINT data_size, const void *data) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - - TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); - - return dxgi_set_private_data(&surface->private_store, guid, data_size, data); -} - -static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateDataInterface(IDXGISurface1 *iface, - REFGUID guid, const IUnknown *object) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - - TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object); - - return dxgi_set_private_data_interface(&surface->private_store, guid, object); -} - -static HRESULT STDMETHODCALLTYPE dxgi_surface_GetPrivateData(IDXGISurface1 *iface, - REFGUID guid, UINT *data_size, void *data) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - - TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); - - return dxgi_get_private_data(&surface->private_store, guid, data_size, data); -} - -static HRESULT STDMETHODCALLTYPE dxgi_surface_GetParent(IDXGISurface1 *iface, REFIID riid, void **parent) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - - TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); - - return IDXGIDevice_QueryInterface(surface->device, riid, parent); -} - -/* IDXGIDeviceSubObject methods */ - -static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDevice(IDXGISurface1 *iface, REFIID riid, void **device) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - - TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device); - - return IDXGIDevice_QueryInterface(surface->device, riid, device); -} - -/* IDXGISurface methods */ -static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDesc(IDXGISurface1 *iface, DXGI_SURFACE_DESC *desc) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - struct wined3d_resource_desc wined3d_desc; - - TRACE("iface %p, desc %p.\n", iface, desc); - - wined3d_mutex_lock(); - wined3d_resource_get_desc(wined3d_texture_get_resource(surface->wined3d_texture), &wined3d_desc); - wined3d_mutex_unlock(); - desc->Width = wined3d_desc.width; - desc->Height = wined3d_desc.height; - desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.format); - dxgi_sample_desc_from_wined3d(&desc->SampleDesc, wined3d_desc.multisample_type, wined3d_desc.multisample_quality); - - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE dxgi_surface_Map(IDXGISurface1 *iface, DXGI_MAPPED_RECT *mapped_rect, UINT flags) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - struct wined3d_map_desc wined3d_map_desc; - DWORD wined3d_map_flags = 0; - HRESULT hr; - - TRACE("iface %p, mapped_rect %p, flags %#x.\n", iface, mapped_rect, flags); - - if (flags & DXGI_MAP_READ) - wined3d_map_flags |= WINED3D_MAP_READ; - if (flags & DXGI_MAP_WRITE) - wined3d_map_flags |= WINED3D_MAP_WRITE; - if (flags & DXGI_MAP_DISCARD) - wined3d_map_flags |= WINED3D_MAP_DISCARD; - - if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), 0, - &wined3d_map_desc, NULL, wined3d_map_flags))) - { - mapped_rect->Pitch = wined3d_map_desc.row_pitch; - mapped_rect->pBits = wined3d_map_desc.data; - } - - return hr; -} - -static HRESULT STDMETHODCALLTYPE dxgi_surface_Unmap(IDXGISurface1 *iface) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - - TRACE("iface %p.\n", iface); - wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), 0); - return S_OK; -} - -/* IDXGISurface1 methods */ -static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDC(IDXGISurface1 *iface, BOOL discard, HDC *hdc) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - HRESULT hr; - - FIXME("iface %p, discard %d, hdc %p semi-stub!\n", iface, discard, hdc); - - if (!hdc) - return E_INVALIDARG; - - wined3d_mutex_lock(); - hr = wined3d_texture_get_dc(surface->wined3d_texture, 0, hdc); - wined3d_mutex_unlock(); - - if (SUCCEEDED(hr)) - surface->dc = *hdc; - - return hr; -} - -static HRESULT STDMETHODCALLTYPE dxgi_surface_ReleaseDC(IDXGISurface1 *iface, RECT *dirty_rect) -{ - struct dxgi_surface *surface = impl_from_IDXGISurface1(iface); - HRESULT hr; - - TRACE("iface %p, rect %s\n", iface, wine_dbgstr_rect(dirty_rect)); - - if (!IsRectEmpty(dirty_rect)) - FIXME("dirty rectangle is ignored.\n"); - - wined3d_mutex_lock(); - hr = wined3d_texture_release_dc(surface->wined3d_texture, 0, surface->dc); - wined3d_mutex_unlock(); - - return hr; -} - -static const struct IDXGISurface1Vtbl dxgi_surface_vtbl = -{ - /* IUnknown methods */ - dxgi_surface_QueryInterface, - dxgi_surface_AddRef, - dxgi_surface_Release, - /* IDXGIObject methods */ - dxgi_surface_SetPrivateData, - dxgi_surface_SetPrivateDataInterface, - dxgi_surface_GetPrivateData, - dxgi_surface_GetParent, - /* IDXGIDeviceSubObject methods */ - dxgi_surface_GetDevice, - /* IDXGISurface methods */ - dxgi_surface_GetDesc, - dxgi_surface_Map, - dxgi_surface_Unmap, - /* IDXGISurface1 methods */ - dxgi_surface_GetDC, - dxgi_surface_ReleaseDC, -}; - -static const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl = -{ - /* IUnknown methods */ - dxgi_surface_inner_QueryInterface, - dxgi_surface_inner_AddRef, - dxgi_surface_inner_Release, -}; - -HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, - IUnknown *outer, struct wined3d_texture *wined3d_texture) -{ - surface->IDXGISurface1_iface.lpVtbl = &dxgi_surface_vtbl; - surface->IUnknown_iface.lpVtbl = &dxgi_surface_inner_unknown_vtbl; - surface->refcount = 1; - wined3d_private_store_init(&surface->private_store); - surface->outer_unknown = outer ? outer : &surface->IUnknown_iface; - surface->device = device; - surface->wined3d_texture = wined3d_texture; - surface->dc = NULL; - - return S_OK; -} diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 5fd0ba89054..1874bcc0834 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -1265,7 +1265,6 @@ static void test_create_surface(void) hr = IDXGIDevice_CreateSurface(device, &desc, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT, NULL, &surface); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- todo_wine check_interface(surface, &IID_IDXGIResource, TRUE, FALSE); check_interface(surface, &IID_ID3D10Texture2D, TRUE, FALSE); /* Not available on all Windows versions. */ @@ -4492,19 +4491,13 @@ static void test_swapchain_parameters(void) continue;
hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i); - if (FAILED(hr)) - { - hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - - IDXGISwapChain_Release(swapchain); - continue; - } + ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; hr = IDXGIResource_GetUsage(resource, &usage); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i); + todo_wine ok((usage & expected_usage) == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i);
@@ -4541,15 +4534,21 @@ static void test_swapchain_parameters(void) broken_usage |= DXGI_USAGE_READ_ONLY;
hr = IDXGIResource_GetUsage(resource, &usage); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx, test %u, buffer %u.\n", hr, i, j); + todo_wine ok(usage == expected_usage || broken(usage == broken_usage), "Got usage %x, expected %x, test %u, buffer %u.\n", usage, expected_usage, i, j);
IDXGIResource_Release(resource); } - hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource); - ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx, test %u.\n", hr, i); + + if (strcmp(winetest_platform, "wine")) + { + hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx, test %u.\n", hr, i); + }
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i); @@ -4605,15 +4604,12 @@ static void test_swapchain_parameters(void) }
hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i); - if (FAILED(hr)) - { - IDXGISwapChain_Release(swapchain); - continue; - } + ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i); expected_usage = usage | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_DISCARD_ON_PRESENT; hr = IDXGIResource_GetUsage(resource, &usage); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i); + todo_wine_if(i != 7) ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i); IDXGIResource_Release(resource);
diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index 83012047ea7..64e4218204b 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -44,12 +44,13 @@ interface IWineDXGISwapChainFactory : IUnknown ] interface IWineDXGIDevice : IDXGIDevice3 { - HRESULT create_surface( - [in] struct wined3d_texture *wined3d_texture, + HRESULT create_resource( + [in] struct wined3d_resource *wined3d_resource, [in] DXGI_USAGE usage, [in] const DXGI_SHARED_RESOURCE *shared_resource, [in] IUnknown *outer, - [out] void **surface + [in] BOOL needs_surface, + [out] void **resource ); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116526
Your paranoid android.
=== w10pro64 (32 bit report) ===
d3d11: d3d11.c:5911: Test failed: Got unexpected query result 0x0000000000000000.
=== debian11 (32 bit report) ===
Report validation errors: dxgi:dxgi prints too much data (34265 bytes)
=== debian11 (32 bit Arabic:Morocco report) ===
Report validation errors: dxgi:dxgi prints too much data (34265 bytes)
=== debian11 (32 bit German report) ===
Report validation errors: dxgi:dxgi prints too much data (34265 bytes)
=== debian11 (32 bit French report) ===
Report validation errors: dxgi:dxgi prints too much data (34265 bytes)
=== debian11 (32 bit Hebrew:Israel report) ===
Report validation errors: dxgi:dxgi prints too much data (34265 bytes)
=== debian11 (32 bit Hindi:India report) ===
Report validation errors: dxgi:dxgi prints too much data (34265 bytes)
=== debian11 (32 bit Japanese:Japan report) ===
Report validation errors: dxgi:dxgi prints too much data (34590 bytes)
=== debian11 (32 bit Chinese:China report) ===
Report validation errors: dxgi:dxgi prints too much data (34590 bytes)
=== debian11 (32 bit WoW report) ===
Report validation errors: dxgi:dxgi prints too much data (34265 bytes)
=== debian11 (64 bit WoW report) ===
d3d11: d3d11.c:28398: Test failed: Got texcoord {7.51953065e-001, 2.48046920e-001}, expected {7.51953125e-001, 2.48046875e-001} at (3, 3), offset 4.92187500e-001.
Report validation errors: dxgi:dxgi prints too much data (34606 bytes)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d11/texture.c | 58 +++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 28 deletions(-)
diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index b3f4d7132be..513a656aebe 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -420,12 +420,35 @@ static const struct wined3d_parent_ops d3d_texture1d_wined3d_parent_ops = d3d_texture1d_wined3d_object_released, };
+static HRESULT d3d_device_create_dxgi_resource(IUnknown *device, struct wined3d_resource *wined3d_resource, + IUnknown *outer, BOOL needs_surface, IUnknown **dxgi_resource) +{ + IWineDXGIDevice *wine_device; + HRESULT hr; + + if (FAILED(hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&wine_device))) + { + ERR("Device should implement IWineDXGIDevice.\n"); + return E_FAIL; + } + + hr = IWineDXGIDevice_create_resource(wine_device, wined3d_resource, 0, NULL, outer, + needs_surface, (void **)dxgi_resource); + IWineDXGIDevice_Release(wine_device); + if (FAILED(hr)) + { + ERR("Failed to create DXGI resource, returning %#.lx\n", hr); + *dxgi_resource = NULL; + } + + return hr; +} + HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture1d **out) { struct wined3d_resource_desc wined3d_desc; struct d3d_texture1d *texture; - IWineDXGIDevice *wine_device; unsigned int levels; BOOL needs_surface; DWORD flags = 0; @@ -474,23 +497,13 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE return hr; }
- if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, - (void **)&wine_device))) - { - ERR("Device should implement IWineDXGIDevice.\n"); - wined3d_texture_decref(texture->wined3d_texture); - wined3d_mutex_unlock(); - return E_FAIL; - } - needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1; - hr = IWineDXGIDevice_create_resource(wine_device, wined3d_texture_get_resource(texture->wined3d_texture), - 0, NULL, (IUnknown *)&texture->ID3D10Texture1D_iface, needs_surface, (void **)&texture->dxgi_resource); - IWineDXGIDevice_Release(wine_device); + hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface, + wined3d_texture_get_resource(texture->wined3d_texture), (IUnknown *)&texture->ID3D10Texture1D_iface, + needs_surface, &texture->dxgi_resource); if (FAILED(hr)) { ERR("Failed to create DXGI resource, returning %#.lx\n", hr); - texture->dxgi_resource = NULL; wined3d_texture_decref(texture->wined3d_texture); wined3d_mutex_unlock(); return hr; @@ -963,7 +976,6 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE { struct wined3d_resource_desc wined3d_desc; struct d3d_texture2d *texture; - IWineDXGIDevice *wine_device; unsigned int levels; BOOL needs_surface; DWORD flags = 0; @@ -1019,23 +1031,13 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE } texture->desc.MipLevels = levels;
- if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, - (void **)&wine_device))) - { - ERR("Device should implement IWineDXGIDevice.\n"); - wined3d_texture_decref(texture->wined3d_texture); - wined3d_mutex_unlock(); - return E_FAIL; - } - needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1; - hr = IWineDXGIDevice_create_resource(wine_device, wined3d_texture_get_resource(texture->wined3d_texture), - 0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, needs_surface, (void **)&texture->dxgi_resource); - IWineDXGIDevice_Release(wine_device); + hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface, + wined3d_texture_get_resource(texture->wined3d_texture), (IUnknown *)&texture->ID3D10Texture2D_iface, + needs_surface, &texture->dxgi_resource); if (FAILED(hr)) { ERR("Failed to create DXGI resource, returning %#.lx\n", hr); - texture->dxgi_resource = NULL; wined3d_texture_decref(texture->wined3d_texture); wined3d_mutex_unlock(); return hr;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d11/d3d11_private.h | 2 - dlls/d3d11/texture.c | 78 +++++++++++++++----------------------- 2 files changed, 30 insertions(+), 50 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 4e4efcae098..cc236699871 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -129,7 +129,6 @@ struct d3d_texture1d ID3D10Texture1D ID3D10Texture1D_iface; LONG refcount;
- struct wined3d_private_store private_store; IUnknown *dxgi_resource; struct wined3d_texture *wined3d_texture; D3D11_TEXTURE1D_DESC desc; @@ -148,7 +147,6 @@ struct d3d_texture2d ID3D10Texture2D ID3D10Texture2D_iface; LONG refcount;
- struct wined3d_private_store private_store; IUnknown *dxgi_resource; struct wined3d_texture *wined3d_texture; D3D11_TEXTURE2D_DESC desc; diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index 513a656aebe..775b7df43f1 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -115,60 +115,54 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_GetPrivateData(ID3D11Texture1D REFGUID guid, UINT *data_size, void *data) { struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); - IDXGISurface *dxgi_surface; + IDXGIResource *dxgi_resource; HRESULT hr;
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_resource - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) { - hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data); - IDXGISurface_Release(dxgi_surface); - return hr; + hr = IDXGIResource_GetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); }
- return d3d_get_private_data(&texture->private_store, guid, data_size, data); + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateData(ID3D11Texture1D *iface, REFGUID guid, UINT data_size, const void *data) { struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); - IDXGISurface *dxgi_surface; + IDXGIResource *dxgi_resource; HRESULT hr;
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_resource - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) { - hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data); - IDXGISurface_Release(dxgi_surface); - return hr; + hr = IDXGIResource_SetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); }
- return d3d_set_private_data(&texture->private_store, guid, data_size, data); + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateDataInterface(ID3D11Texture1D *iface, REFGUID guid, const IUnknown *data) { struct d3d_texture1d *texture = impl_from_ID3D11Texture1D(iface); - IDXGISurface *dxgi_surface; + IDXGIResource *dxgi_resource; HRESULT hr;
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- if (texture->dxgi_resource - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) { - hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data); - IDXGISurface_Release(dxgi_surface); - return hr; + hr = IDXGIResource_SetPrivateDataInterface(dxgi_resource, guid, data); + IDXGIResource_Release(dxgi_resource); }
- return d3d_set_private_data_interface(&texture->private_store, guid, data); + return hr; }
static void STDMETHODCALLTYPE d3d11_texture1d_GetType(ID3D11Texture1D *iface, @@ -258,7 +252,6 @@ static void STDMETHODCALLTYPE d3d_texture1d_wined3d_object_released(void *parent
if (texture->dxgi_resource) IUnknown_Release(texture->dxgi_resource); - wined3d_private_store_cleanup(&texture->private_store); heap_free(texture); }
@@ -460,7 +453,6 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE texture->ID3D11Texture1D_iface.lpVtbl = &d3d11_texture1d_vtbl; texture->ID3D10Texture1D_iface.lpVtbl = &d3d10_texture1d_vtbl; texture->refcount = 1; - wined3d_private_store_init(&texture->private_store); texture->desc = *desc; levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(desc->Width) + 1; texture->desc.MipLevels = levels; @@ -489,7 +481,6 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE texture, &d3d_texture1d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#lx.\n", hr); - wined3d_private_store_cleanup(&texture->private_store); heap_free(texture); wined3d_mutex_unlock(); if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL) @@ -605,60 +596,54 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(ID3D11Texture2D REFGUID guid, UINT *data_size, void *data) { struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); - IDXGISurface *dxgi_surface; + IDXGIResource *dxgi_resource; HRESULT hr;
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_resource - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) { - hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data); - IDXGISurface_Release(dxgi_surface); - return hr; + hr = IDXGIResource_GetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); }
- return d3d_get_private_data(&texture->private_store, guid, data_size, data); + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(ID3D11Texture2D *iface, REFGUID guid, UINT data_size, const void *data) { struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); - IDXGISurface *dxgi_surface; + IDXGIResource *dxgi_resource; HRESULT hr;
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- if (texture->dxgi_resource - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) { - hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data); - IDXGISurface_Release(dxgi_surface); - return hr; + hr = IDXGIResource_SetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); }
- return d3d_set_private_data(&texture->private_store, guid, data_size, data); + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(ID3D11Texture2D *iface, REFGUID guid, const IUnknown *data) { struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface); - IDXGISurface *dxgi_surface; + IDXGIResource *dxgi_resource; HRESULT hr;
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- if (texture->dxgi_resource - && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface))) + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) { - hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data); - IDXGISurface_Release(dxgi_surface); - return hr; + hr = IDXGIResource_SetPrivateDataInterface(dxgi_resource, guid, data); + IDXGIResource_Release(dxgi_resource); }
- return d3d_set_private_data_interface(&texture->private_store, guid, data); + return hr; }
static void STDMETHODCALLTYPE d3d11_texture2d_GetType(ID3D11Texture2D *iface, @@ -762,7 +747,6 @@ static void STDMETHODCALLTYPE d3d_texture2d_wined3d_object_released(void *parent struct d3d_texture2d *texture = parent;
if (texture->dxgi_resource) IUnknown_Release(texture->dxgi_resource); - wined3d_private_store_cleanup(&texture->private_store); heap_free(texture); }
@@ -994,7 +978,6 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; texture->refcount = 1; wined3d_mutex_lock(); - wined3d_private_store_init(&texture->private_store); texture->desc = *desc;
wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; @@ -1022,7 +1005,6 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#lx.\n", hr); - wined3d_private_store_cleanup(&texture->private_store); heap_free(texture); wined3d_mutex_unlock(); if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d11/d3d11_private.h | 2 +- dlls/d3d11/tests/d3d11.c | 2 -- dlls/d3d11/texture.c | 70 +++++++++++++++++++++++++++++--------- 3 files changed, 55 insertions(+), 19 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index cc236699871..8b3f1ab5717 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -170,7 +170,7 @@ struct d3d_texture3d ID3D10Texture3D ID3D10Texture3D_iface; LONG refcount;
- struct wined3d_private_store private_store; + IUnknown *dxgi_resource; struct wined3d_texture *wined3d_texture; D3D11_TEXTURE3D_DESC desc; ID3D11Device2 *device; diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 0c741283da5..3628a0bd573 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -3286,9 +3286,7 @@ static void test_texture3d_interfaces(void) hr = ID3D11Device_CreateTexture3D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); - todo_wine check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); - todo_wine test_dxgi_resource(texture); hr = check_interface(texture, &IID_ID3D10Texture3D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture3D_Release(texture); diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index 775b7df43f1..fb4c1cdc597 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -1044,6 +1044,7 @@ static inline struct d3d_texture3d *impl_from_ID3D11Texture3D(ID3D11Texture3D *i static HRESULT STDMETHODCALLTYPE d3d11_texture3d_QueryInterface(ID3D11Texture3D *iface, REFIID riid, void **object) { struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + HRESULT hr;
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
@@ -1065,10 +1066,15 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture3d_QueryInterface(ID3D11Texture3D return S_OK; }
- WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + TRACE("Forwarding to dxgi resource.\n");
- *object = NULL; - return E_NOINTERFACE; + if (FAILED(hr = IUnknown_QueryInterface(texture->dxgi_resource, riid, object))) + { + WARN("%s not implemented, returning %#lx.\n", debugstr_guid(riid), hr); + *object = NULL; + } + + return hr; }
static ULONG STDMETHODCALLTYPE d3d11_texture3d_AddRef(ID3D11Texture3D *iface) @@ -1091,7 +1097,8 @@ static void STDMETHODCALLTYPE d3d_texture3d_wined3d_object_released(void *parent { struct d3d_texture3d *texture = parent;
- wined3d_private_store_cleanup(&texture->private_store); + if (texture->dxgi_resource) + IUnknown_Release(texture->dxgi_resource); heap_free(parent); }
@@ -1129,30 +1136,54 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture3d_GetPrivateData(ID3D11Texture3D REFGUID guid, UINT *data_size, void *data) { struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + IDXGIResource *dxgi_resource; + HRESULT hr;
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_get_private_data(&texture->private_store, guid, data_size, data); + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) + { + hr = IDXGIResource_GetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); + } + + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_texture3d_SetPrivateData(ID3D11Texture3D *iface, REFGUID guid, UINT data_size, const void *data) { struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + IDXGIResource *dxgi_resource; + HRESULT hr;
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_set_private_data(&texture->private_store, guid, data_size, data); + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) + { + hr = IDXGIResource_SetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); + } + + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_texture3d_SetPrivateDataInterface(ID3D11Texture3D *iface, REFGUID guid, const IUnknown *data) { struct d3d_texture3d *texture = impl_from_ID3D11Texture3D(iface); + IDXGIResource *dxgi_resource; + HRESULT hr;
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- return d3d_set_private_data_interface(&texture->private_store, guid, data); + if (SUCCEEDED(hr = IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) + { + hr = IDXGIResource_SetPrivateDataInterface(dxgi_resource, guid, data); + IDXGIResource_Release(dxgi_resource); + } + + return hr; }
static void STDMETHODCALLTYPE d3d11_texture3d_GetType(ID3D11Texture3D *iface, @@ -1251,10 +1282,9 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture3d_GetPrivateData(ID3D10Texture3D { struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
- TRACE("iface %p, guid %s, data_size %p, data %p.\n", - iface, debugstr_guid(guid), data_size, data); + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_get_private_data(&texture->private_store, guid, data_size, data); + return d3d11_texture3d_GetPrivateData(&texture->ID3D11Texture3D_iface, guid, data_size, data); }
static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateData(ID3D10Texture3D *iface, @@ -1262,10 +1292,9 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateData(ID3D10Texture3D { struct d3d_texture3d *texture = impl_from_ID3D10Texture3D(iface);
- TRACE("iface %p, guid %s, data_size %u, data %p.\n", - iface, debugstr_guid(guid), data_size, data); + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_set_private_data(&texture->private_store, guid, data_size, data); + return d3d11_texture3d_SetPrivateData(&texture->ID3D11Texture3D_iface, guid, data_size, data); }
static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateDataInterface(ID3D10Texture3D *iface, @@ -1275,7 +1304,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture3d_SetPrivateDataInterface(ID3D10T
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- return d3d_set_private_data_interface(&texture->private_store, guid, data); + return d3d11_texture3d_SetPrivateDataInterface(&texture->ID3D11Texture3D_iface, guid, data); }
static void STDMETHODCALLTYPE d3d10_texture3d_GetType(ID3D10Texture3D *iface, @@ -1413,7 +1442,6 @@ static HRESULT d3d_texture3d_init(struct d3d_texture3d *texture, struct d3d_devi texture->ID3D10Texture3D_iface.lpVtbl = &d3d10_texture3d_vtbl; texture->refcount = 1; wined3d_mutex_lock(); - wined3d_private_store_init(&texture->private_store); texture->desc = *desc;
wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; @@ -1439,12 +1467,22 @@ static HRESULT d3d_texture3d_init(struct d3d_texture3d *texture, struct d3d_devi &d3d_texture3d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#lx.\n", hr); - wined3d_private_store_cleanup(&texture->private_store); wined3d_mutex_unlock(); if (hr == WINED3DERR_INVALIDCALL) hr = E_INVALIDARG; return hr; } + + hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface, + wined3d_texture_get_resource(texture->wined3d_texture), (IUnknown *)&texture->ID3D10Texture3D_iface, + FALSE, &texture->dxgi_resource); + if (FAILED(hr)) + { + ERR("Failed to create DXGI resource, returning %#.lx\n", hr); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + return hr; + } wined3d_mutex_unlock(); texture->desc.MipLevels = levels;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116529
Your paranoid android.
=== w1064_tsign (32 bit report) ===
d3d11: d3d11.c:5909: Test failed: Got unexpected query result 0x0000000000000000.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3d11/buffer.c | 61 ++++++++++++++++++++++++++++++-------- dlls/d3d11/d3d11_private.h | 4 ++- dlls/d3d11/tests/d3d11.c | 1 - dlls/d3d11/texture.c | 2 +- 4 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/dlls/d3d11/buffer.c b/dlls/d3d11/buffer.c index 352559322d7..6447c3c7a53 100644 --- a/dlls/d3d11/buffer.c +++ b/dlls/d3d11/buffer.c @@ -31,6 +31,7 @@ static inline struct d3d_buffer *impl_from_ID3D11Buffer(ID3D11Buffer *iface) static HRESULT STDMETHODCALLTYPE d3d11_buffer_QueryInterface(ID3D11Buffer *iface, REFIID riid, void **out) { struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + HRESULT hr;
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
@@ -53,10 +54,13 @@ static HRESULT STDMETHODCALLTYPE d3d11_buffer_QueryInterface(ID3D11Buffer *iface return S_OK; }
- WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + if (FAILED(hr = IUnknown_QueryInterface(buffer->dxgi_resource, riid, out))) + { + WARN("%s not implemented, returning %#lx.\n", debugstr_guid(riid), hr); + *out = NULL; + }
- *out = NULL; - return E_NOINTERFACE; + return hr; }
static ULONG STDMETHODCALLTYPE d3d11_buffer_AddRef(ID3D11Buffer *iface) @@ -109,30 +113,54 @@ static HRESULT STDMETHODCALLTYPE d3d11_buffer_GetPrivateData(ID3D11Buffer *iface REFGUID guid, UINT *data_size, void *data) { struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + IDXGIResource *dxgi_resource; + HRESULT hr;
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_get_private_data(&buffer->private_store, guid, data_size, data); + if (SUCCEEDED(hr = IUnknown_QueryInterface(buffer->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) + { + hr = IDXGIResource_GetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); + } + + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_buffer_SetPrivateData(ID3D11Buffer *iface, REFGUID guid, UINT data_size, const void *data) { struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + IDXGIResource *dxgi_resource; + HRESULT hr;
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_set_private_data(&buffer->private_store, guid, data_size, data); + if (SUCCEEDED(hr = IUnknown_QueryInterface(buffer->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) + { + hr = IDXGIResource_SetPrivateData(dxgi_resource, guid, data_size, data); + IDXGIResource_Release(dxgi_resource); + } + + return hr; }
static HRESULT STDMETHODCALLTYPE d3d11_buffer_SetPrivateDataInterface(ID3D11Buffer *iface, REFGUID guid, const IUnknown *data) { struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface); + IDXGIResource *dxgi_resource; + HRESULT hr;
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- return d3d_set_private_data_interface(&buffer->private_store, guid, data); + if (SUCCEEDED(hr = IUnknown_QueryInterface(buffer->dxgi_resource, &IID_IDXGIResource, (void **)&dxgi_resource))) + { + hr = IDXGIResource_SetPrivateDataInterface(dxgi_resource, guid, data); + IDXGIResource_Release(dxgi_resource); + } + + return hr; }
static void STDMETHODCALLTYPE d3d11_buffer_GetType(ID3D11Buffer *iface, @@ -246,7 +274,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_buffer_GetPrivateData(ID3D10Buffer *iface TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_get_private_data(&buffer->private_store, guid, data_size, data); + return d3d11_buffer_GetPrivateData(&buffer->ID3D11Buffer_iface, guid, data_size, data); }
static HRESULT STDMETHODCALLTYPE d3d10_buffer_SetPrivateData(ID3D10Buffer *iface, @@ -257,7 +285,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_buffer_SetPrivateData(ID3D10Buffer *iface TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
- return d3d_set_private_data(&buffer->private_store, guid, data_size, data); + return d3d11_buffer_SetPrivateData(&buffer->ID3D11Buffer_iface, guid, data_size, data); }
static HRESULT STDMETHODCALLTYPE d3d10_buffer_SetPrivateDataInterface(ID3D10Buffer *iface, @@ -267,7 +295,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_buffer_SetPrivateDataInterface(ID3D10Buff
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
- return d3d_set_private_data_interface(&buffer->private_store, guid, data); + return d3d11_buffer_SetPrivateDataInterface(&buffer->ID3D11Buffer_iface, guid, data); }
/* ID3D10Resource methods */ @@ -367,7 +395,7 @@ static void STDMETHODCALLTYPE d3d_buffer_wined3d_object_released(void *parent) { struct d3d_buffer *buffer = parent;
- wined3d_private_store_cleanup(&buffer->private_store); + if (buffer->dxgi_resource) IUnknown_Release(buffer->dxgi_resource); heap_free(parent); }
@@ -446,14 +474,23 @@ static HRESULT d3d_buffer_init(struct d3d_buffer *buffer, struct d3d_device *dev wined3d_desc.structure_byte_stride = buffer->desc.StructureByteStride;
wined3d_mutex_lock(); - wined3d_private_store_init(&buffer->private_store);
if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &wined3d_desc, (const struct wined3d_sub_resource_data *)data, buffer, &d3d_buffer_wined3d_parent_ops, &buffer->wined3d_buffer))) { WARN("Failed to create wined3d buffer, hr %#lx.\n", hr); - wined3d_private_store_cleanup(&buffer->private_store); + wined3d_mutex_unlock(); + return hr; + } + + hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface, + wined3d_buffer_get_resource(buffer->wined3d_buffer), (IUnknown *)&buffer->ID3D10Buffer_iface, + FALSE, &buffer->dxgi_resource); + if (FAILED(hr)) + { + ERR("Failed to create DXGI resource, returning %#.lx\n", hr); + wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_mutex_unlock(); return hr; } diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 8b3f1ab5717..6728f36a473 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -72,6 +72,8 @@ DWORD wined3d_map_flags_from_d3d11_map_type(D3D11_MAP map_type) DECLSPEC_HIDDEN; DWORD wined3d_map_flags_from_d3d10_map_type(D3D10_MAP map_type) DECLSPEC_HIDDEN; DWORD wined3d_clear_flags_from_d3d11_clear_flags(UINT clear_flags) DECLSPEC_HIDDEN; unsigned int wined3d_access_from_d3d11(D3D11_USAGE usage, UINT cpu_access) DECLSPEC_HIDDEN; +HRESULT d3d_device_create_dxgi_resource(IUnknown *device, struct wined3d_resource *wined3d_resource, + IUnknown *outer, BOOL needs_surface, IUnknown **dxgi_resource) DECLSPEC_HIDDEN;
enum D3D11_USAGE d3d11_usage_from_d3d10_usage(enum D3D10_USAGE usage) DECLSPEC_HIDDEN; enum D3D10_USAGE d3d10_usage_from_d3d11_usage(enum D3D11_USAGE usage) DECLSPEC_HIDDEN; @@ -188,7 +190,7 @@ struct d3d_buffer ID3D10Buffer ID3D10Buffer_iface; LONG refcount;
- struct wined3d_private_store private_store; + IUnknown *dxgi_resource; struct wined3d_buffer *wined3d_buffer; D3D11_BUFFER_DESC desc; ID3D11Device2 *device; diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 3628a0bd573..345a87c4194 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -3603,7 +3603,6 @@ static void test_create_buffer(void) continue; }
- todo_wine check_interface(buffer, &IID_IDXGIResource, TRUE, FALSE);
if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)) diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index fb4c1cdc597..7be689d1f0f 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -413,7 +413,7 @@ static const struct wined3d_parent_ops d3d_texture1d_wined3d_parent_ops = d3d_texture1d_wined3d_object_released, };
-static HRESULT d3d_device_create_dxgi_resource(IUnknown *device, struct wined3d_resource *wined3d_resource, +HRESULT d3d_device_create_dxgi_resource(IUnknown *device, struct wined3d_resource *wined3d_resource, IUnknown *outer, BOOL needs_surface, IUnknown **dxgi_resource) { IWineDXGIDevice *wine_device;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=116530
Your paranoid android.
=== w1064_tsign (32 bit report) ===
d3d11: d3d11.c:5908: Test failed: Got unexpected query result 0x0000000000000000.
This patch series looks sensible to me, given the current structure of the code, but I'm not familiar with all of the considerations here. Henri, do you have any thoughts?
On Fri, 10 Jun 2022 at 01:38, Zebediah Figura zfigura@codeweavers.com wrote:
This patch series looks sensible to me, given the current structure of the code, but I'm not familiar with all of the considerations here. Henri, do you have any thoughts?
I didn't review this line-by-line, but on a high level this seems fine.
Jan Sikorski (@jsikorski) commented about dlls/d3d11/texture.c:
return S_OK; }
- if (texture->dxgi_surface)
- if (texture->dxgi_resource)
Mostly to test my understanding, do we still actually need to check this for some reason?
On Fri, 10 Jun 2022 at 12:34, Jan Sikorski (@jsikorski) wine@gitlab.winehq.org wrote:
Jan Sikorski (@jsikorski) commented about dlls/d3d11/texture.c:
return S_OK; }
- if (texture->dxgi_surface)
- if (texture->dxgi_resource)
Mostly to test my understanding, do we still actually need to check this for some reason?
I think we should be able to drop the check and do this unconditionally. That would apply to e.g. d3d_texture1d_wined3d_object_released() as well.
On Fri Jun 10 10:46:28 2022 +0000, **** wrote:
Henri Verbeet replied on the mailing list:
On Fri, 10 Jun 2022 at 12:34, Jan Sikorski (@jsikorski) <wine@gitlab.winehq.org> wrote: > > Jan Sikorski (@jsikorski) commented about dlls/d3d11/texture.c: > > return S_OK; > > } > > > > - if (texture->dxgi_surface) > > + if (texture->dxgi_resource) > Mostly to test my understanding, do we still actually need to check this for some reason? I think we should be able to drop the check and do this unconditionally. That would apply to e.g. d3d_texture1d_wined3d_object_released() as well.
I'm not sure about the released() procedures - it looks like if we fail to create the dxgi_resource, we decref the texture or buffer and then it gets released with dxgi_resource set to NULL, no?
On Fri, 10 Jun 2022 at 12:51, Jan Sikorski (@jsikorski) wine@gitlab.winehq.org wrote:
I'm not sure about the released() procedures - it looks like if we fail to create the dxgi_resource, we decref the texture or buffer and then it gets released with dxgi_resource set to NULL, no?
Hmm, right. That's unfortunate though; ideally wined3d_object_released() would only be called on fully initialised objects.
On Fri Jun 10 11:00:08 2022 +0000, **** wrote:
Henri Verbeet replied on the mailing list:
On Fri, 10 Jun 2022 at 12:51, Jan Sikorski (@jsikorski) <wine@gitlab.winehq.org> wrote: > I'm not sure about the released() procedures - it looks like if we fail to create the dxgi_resource, we decref the texture or buffer and then it gets released with dxgi_resource set to NULL, no? Hmm, right. That's unfortunate though; ideally wined3d_object_released() would only be called on fully initialised objects.
Yes, for QueryInterface() it could be removed, like it's done for buffers. I was thinking removing it later with additional patch to keep the diff size down.
On Fri Jun 10 11:03:37 2022 +0000, Nikolay Sivov wrote:
Yes, for QueryInterface() it could be removed, like it's done for buffers. I was thinking removing it later with additional patch to keep the diff size down.
As far as I'm concerned, that's fine.
This merge request was approved by Jan Sikorski.
On Fri Jun 10 11:05:14 2022 +0000, Jan Sikorski wrote:
As far as I'm concerned, that's fine.
I agree with Henri's point though, perhaps it would be better to reorder initialization so that we create dxgi_resource first?
On Fri, 10 Jun 2022 at 13:11, Jan Sikorski (@jsikorski) wine@gitlab.winehq.org wrote:
On Fri Jun 10 11:05:14 2022 +0000, Jan Sikorski wrote:
As far as I'm concerned, that's fine.
I agree with Henri's point though, perhaps it would be better to reorder initialization so that we create dxgi_resource first?
The issue with that is that dxgi_resource_init() takes the wined3d resource as parameter. Perhaps that could be avoided, but it would likely introduce its own set of issues.
On 6/10/22 06:18, Henri Verbeet wrote:
On Fri, 10 Jun 2022 at 13:11, Jan Sikorski (@jsikorski) wine@gitlab.winehq.org wrote:
On Fri Jun 10 11:05:14 2022 +0000, Jan Sikorski wrote:
As far as I'm concerned, that's fine.
I agree with Henri's point though, perhaps it would be better to reorder initialization so that we create dxgi_resource first?
The issue with that is that dxgi_resource_init() takes the wined3d resource as parameter. Perhaps that could be avoided, but it would likely introduce its own set of issues.
One thing we could probably do in general is make it possible to delay setting the parent ops, e.g. set it as wined3d_null_parent_ops initially and then add a separate function like wined3d_resource_set_parent_ops() once the client object is fully initialized.
On Wed, 15 Jun 2022 at 20:09, Zebediah Figura zfigura@codeweavers.com wrote:
One thing we could probably do in general is make it possible to delay setting the parent ops, e.g. set it as wined3d_null_parent_ops initially and then add a separate function like wined3d_resource_set_parent_ops() once the client object is fully initialized.
Right, that probably makes sense, although the implications for objects currently referenced by the command stream probably deserve a look.
On 6/16/22 05:01, Henri Verbeet wrote:
On Wed, 15 Jun 2022 at 20:09, Zebediah Figura zfigura@codeweavers.com wrote:
One thing we could probably do in general is make it possible to delay setting the parent ops, e.g. set it as wined3d_null_parent_ops initially and then add a separate function like wined3d_resource_set_parent_ops() once the client object is fully initialized.
Right, that probably makes sense, although the implications for objects currently referenced by the command stream probably deserve a look.
Hmm, I don't see what you mean? Since the only parent op is currently the destruction callback, it can't be called until all references have been dropped, and it'd definitely be an error to call wined3d_resource_set_parent_ops() without holding a reference to the resource.
On Thu, 16 Jun 2022 at 20:38, Zebediah Figura zfigura@codeweavers.com wrote:
On 6/16/22 05:01, Henri Verbeet wrote:
Right, that probably makes sense, although the implications for objects currently referenced by the command stream probably deserve a look.
Hmm, I don't see what you mean? Since the only parent op is currently the destruction callback, it can't be called until all references have been dropped, and it'd definitely be an error to call wined3d_resource_set_parent_ops() without holding a reference to the resource.
Oh, I just meant I'm waving my hand at that part and haven't thought that part through; it may very well be fine.
On Fri Jun 10 11:11:22 2022 +0000, Jan Sikorski wrote:
I agree with Henri's point though, perhaps it would be better to reorder initialization so that we create dxgi_resource first?
You can't reorder right now, because dxgi side needs wined3d_resource pointer which you get from earlier wined3d_texture_create().