-- v2: d3d11: Expand tests for IDXGIResource. dxgi: Implement IDXGIResource::GetUsage(). wined3d: Introduce wined3d_texture_get_swapchain().
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 5 +++++ dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 1 + 3 files changed, 7 insertions(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 8d416494eb8..33b938ad460 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -4313,6 +4313,11 @@ HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, un return WINED3D_OK; }
+struct wined3d_swapchain * CDECL wined3d_texture_get_swapchain(struct wined3d_texture *texture) +{ + return texture->swapchain; +} + void * CDECL wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx) { TRACE("texture %p, sub_resource_idx %u.\n", texture, sub_resource_idx); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 827ac295ddc..b22adf07c9c 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -301,6 +301,7 @@ @ cdecl wined3d_texture_get_resource(ptr) @ cdecl wined3d_texture_get_sub_resource_desc(ptr long ptr) @ cdecl wined3d_texture_get_sub_resource_parent(ptr long) +@ cdecl wined3d_texture_get_swapchain(ptr) @ cdecl wined3d_texture_incref(ptr) @ cdecl wined3d_texture_release_dc(ptr long ptr) @ cdecl wined3d_texture_set_color_key(ptr long ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index f4ec2470bba..5d8a1156b21 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2857,6 +2857,7 @@ struct wined3d_resource * __cdecl wined3d_texture_get_resource(struct wined3d_te HRESULT __cdecl wined3d_texture_get_sub_resource_desc(const struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_sub_resource_desc *desc); void * __cdecl wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx); +struct wined3d_swapchain * __cdecl wined3d_texture_get_swapchain(struct wined3d_texture *texture); ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture); HRESULT __cdecl wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc); HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture,
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/dxgi/resource.c | 30 ++++++++++++++++++++++++++++-- dlls/dxgi/tests/dxgi.c | 25 +++++++++++++++++-------- dlls/dxgi/utils.c | 3 --- 3 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/dlls/dxgi/resource.c b/dlls/dxgi/resource.c index 86ad4ec3f09..9699b7672f9 100644 --- a/dlls/dxgi/resource.c +++ b/dlls/dxgi/resource.c @@ -350,9 +350,35 @@ static HRESULT STDMETHODCALLTYPE dxgi_resource_GetSharedHandle(IDXGIResource *if
static HRESULT STDMETHODCALLTYPE dxgi_resource_GetUsage(IDXGIResource *iface, DXGI_USAGE *usage) { - FIXME("iface %p, usage %p stub!\n", iface, usage); + struct dxgi_resource *resource = impl_from_IDXGIResource(iface); + struct wined3d_resource_desc resource_desc;
- return E_NOTIMPL; + TRACE("iface %p, usage %p.\n", iface, usage); + + wined3d_resource_get_desc(resource->wined3d_resource, &resource_desc); + + *usage = dxgi_usage_from_wined3d_bind_flags(resource_desc.bind_flags); + + if (resource_desc.resource_type != WINED3D_RTYPE_BUFFER) + { + struct wined3d_texture *texture = wined3d_texture_from_resource(resource->wined3d_resource); + struct wined3d_swapchain_desc swapchain_desc; + struct wined3d_swapchain *swapchain; + + if ((swapchain = wined3d_texture_get_swapchain(texture))) + { + *usage |= DXGI_USAGE_BACK_BUFFER; + + wined3d_swapchain_get_desc(swapchain, &swapchain_desc); + if (swapchain_desc.swap_effect == WINED3D_SWAP_EFFECT_DISCARD) + *usage |= DXGI_USAGE_DISCARD_ON_PRESENT; + + if (wined3d_swapchain_get_back_buffer(swapchain, 0) != texture) + *usage |= DXGI_USAGE_READ_ONLY; + } + } + + return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_resource_SetEvictionPriority(IDXGIResource *iface, UINT eviction_priority) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 73ea891119f..e0465b90ed0 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -4016,6 +4016,7 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12) { DXGI_SWAP_CHAIN_DESC swapchain_desc; DXGI_SWAP_EFFECT swap_effect; + IDXGIResource *dxgi_resource; IDXGISwapChain3 *swapchain3; IUnknown *present_queue[2]; IDXGISwapChain *swapchain; @@ -4056,13 +4057,18 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12)
hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface); + expected_hr = is_d3d12 ? E_NOINTERFACE : S_OK; + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&dxgi_resource); + ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); + ok(!dxgi_resource || hr == S_OK, "Got unexpected pointer %p.\n", dxgi_resource); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface); ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); ok(!surface || hr == S_OK, "Got unexpected pointer %p.\n", surface); hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&texture); ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); ok(!texture || hr == S_OK, "Got unexpected pointer %p.\n", texture); + expected_hr = is_d3d12 ? S_OK : E_NOINTERFACE; hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D12Resource, (void **)&resource); ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); @@ -4175,16 +4181,23 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12) check_resource_desc(resource, &swapchain_desc); ID3D12Resource_Release(resource); } + if (dxgi_resource) + IDXGIResource_Release(dxgi_resource);
hr = IDXGISwapChain_ResizeBuffers(swapchain, 2, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface); + expected_hr = is_d3d12 ? E_NOINTERFACE : S_OK; + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&dxgi_resource); + ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); + ok(!surface || hr == S_OK, "Got unexpected pointer %p.\n", surface); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface); ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); ok(!surface || hr == S_OK, "Got unexpected pointer %p.\n", surface); hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&texture); ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); ok(!texture || hr == S_OK, "Got unexpected pointer %p.\n", texture); + expected_hr = is_d3d12 ? S_OK : E_NOINTERFACE; hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D12Resource, (void **)&resource); ok(hr == expected_hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, expected_hr); @@ -4246,6 +4259,8 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12) check_resource_desc(resource, &swapchain_desc); ID3D12Resource_Release(resource); } + if (dxgi_resource) + IDXGIResource_Release(dxgi_resource);
hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -4495,9 +4510,7 @@ static void test_swapchain_parameters(void)
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);
@@ -4534,9 +4547,7 @@ 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); @@ -4607,9 +4618,7 @@ static void test_swapchain_parameters(void) 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/dlls/dxgi/utils.c b/dlls/dxgi/utils.c index d701725afa9..e99951e0a04 100644 --- a/dlls/dxgi/utils.c +++ b/dlls/dxgi/utils.c @@ -494,9 +494,6 @@ DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) if (wined3d_bind_flags & WINED3D_BIND_UNORDERED_ACCESS) dxgi_usage |= DXGI_USAGE_UNORDERED_ACCESS;
- wined3d_bind_flags &= ~(WINED3D_BIND_SHADER_RESOURCE | WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_UNORDERED_ACCESS); - if (wined3d_bind_flags) - FIXME("Unhandled wined3d bind flags %#x.\n", wined3d_bind_flags); return dxgi_usage; }
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d11/tests/d3d11.c | 146 ++++++++++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 26 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index a13d350c582..9bb585f8c13 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -2512,56 +2512,66 @@ 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) +static void test_dxgi_resource(void *iface, unsigned int bind_flags) { IDXGIResource *resource, *resource2; IDXGISurface *surface, *surface2; + DXGI_USAGE usage, expected_usage; 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; + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDXGIResource_GetUsage(resource, &usage); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + expected_usage = 0; + if (bind_flags & D3D11_BIND_RENDER_TARGET) + expected_usage |= DXGI_USAGE_RENDER_TARGET_OUTPUT; + if (bind_flags & D3D11_BIND_SHADER_RESOURCE) + expected_usage |= DXGI_USAGE_SHADER_INPUT; + if (bind_flags & D3D11_BIND_UNORDERED_ACCESS) + expected_usage |= DXGI_USAGE_UNORDERED_ACCESS; + ok(usage == expected_usage, "Got usage %#x.\n", usage);
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"); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok((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"); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok((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"); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(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"); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(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); + ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr); hr = IDXGIResource_GetParent(resource, &IID_IDXGISurface, (void **)&surface2); - ok_(__FILE__, line)(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + ok(hr == E_NOINTERFACE, "Got 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); + ok(hr == S_OK, "Got 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); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(data == 123, "Unexpected data %#lx.\n", data);
IDXGISurface_Release(surface); } @@ -2569,6 +2579,98 @@ static void test_dxgi_resource_(unsigned int line, void *iface) IDXGIResource_Release(resource); }
+static void test_dxgi_resources(void) +{ + struct d3d11_test_context test_context; + ID3D11Device *device; + unsigned int i, j; + HRESULT hr; + + static const unsigned int bind_flags[] = + { + 0, + D3D11_BIND_SHADER_RESOURCE, + D3D11_BIND_RENDER_TARGET, + D3D11_BIND_DEPTH_STENCIL, + D3D11_BIND_UNORDERED_ACCESS, + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS, + D3D11_BIND_CONSTANT_BUFFER, + D3D11_BIND_VERTEX_BUFFER, + D3D11_BIND_INDEX_BUFFER, + D3D11_BIND_STREAM_OUTPUT, + }; + + static const struct + { + D3D11_RESOURCE_DIMENSION dimension; + unsigned int level_count; + } + dimensions[] = + { + {D3D11_RESOURCE_DIMENSION_BUFFER, 0}, + {D3D11_RESOURCE_DIMENSION_TEXTURE1D, 1}, + {D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0}, + {D3D11_RESOURCE_DIMENSION_TEXTURE2D, 1}, + {D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0}, + {D3D11_RESOURCE_DIMENSION_TEXTURE3D, 1}, + {D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0}, + }; + + if (!init_test_context(&test_context, NULL)) + return; + device = test_context.device; + + for (i = 0; i < ARRAY_SIZE(bind_flags); ++i) + { + if ((bind_flags[i] & D3D11_BIND_UNORDERED_ACCESS) + && ID3D11Device_GetFeatureLevel(device) < D3D_FEATURE_LEVEL_11_0) + continue; + + for (j = 0; j < ARRAY_SIZE(dimensions); ++j) + { + struct resource_desc resource_desc = + { + .dimension = dimensions[j].dimension, + .width = 64, + .height = 64, + .depth_or_array_size = 1, + .level_count = dimensions[j].level_count, + .format = DXGI_FORMAT_R8G8B8A8_UNORM, + .sample_desc.Count = 1, + .usage = D3D11_USAGE_DEFAULT, + .bind_flags = bind_flags[i], + }; + ID3D11Resource *resource; + + if ((bind_flags[i] & (D3D11_BIND_CONSTANT_BUFFER | D3D11_BIND_VERTEX_BUFFER + | D3D11_BIND_INDEX_BUFFER | D3D11_BIND_STREAM_OUTPUT)) + && resource_desc.dimension != D3D11_RESOURCE_DIMENSION_BUFFER) + continue; + + if (bind_flags[i] & D3D11_BIND_DEPTH_STENCIL) + { + resource_desc.format = DXGI_FORMAT_D24_UNORM_S8_UINT; + if (resource_desc.dimension != D3D11_RESOURCE_DIMENSION_TEXTURE1D + && resource_desc.dimension != D3D11_RESOURCE_DIMENSION_TEXTURE2D) + continue; + } + + winetest_push_context("Bind flags %#x, dimension %#x, level_count %u", + bind_flags[i], dimensions[j].dimension, dimensions[j].level_count); + + hr = create_resource(device, &resource_desc, NULL, &resource); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + test_dxgi_resource(resource, bind_flags[i]); + ID3D11Resource_Release(resource); + + winetest_pop_context(); + } + } + + release_test_context(&test_context); +} + static void test_texture1d_interfaces(void) { ID3D10Texture1D *d3d10_texture; @@ -2628,15 +2730,12 @@ static void test_texture1d_interfaces(void)
hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - 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); - test_dxgi_resource(texture); check_interface(texture, &IID_IDXGISurface, FALSE, FALSE); - 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)) @@ -3025,16 +3124,12 @@ 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); - check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); - 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); - check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); - test_dxgi_resource(texture); hr = check_interface(texture, &IID_ID3D10Texture2D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture2D_Release(texture); if (FAILED(hr)) @@ -3299,8 +3394,6 @@ 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); - check_interface(texture, &IID_IDXGIResource, TRUE, FALSE); - test_dxgi_resource(texture); hr = check_interface(texture, &IID_ID3D10Texture3D, TRUE, TRUE); /* Not available on all Windows versions. */ ID3D11Texture3D_Release(texture); if (FAILED(hr)) @@ -35098,6 +35191,7 @@ START_TEST(d3d11) queue_test(test_logic_op); queue_test(test_rtv_depth_slice); queue_test(test_vertex_formats); + queue_test(test_dxgi_resources);
run_queued_tests();
This merge request was approved by Jan Sikorski.