It is not yet possible to get an IDXGIAdapter in Wine's D3D12. This makes most of the multithreadable tests unworkable at the moment.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 557 ++++++++++++++++++++++------------------- 1 file changed, 293 insertions(+), 264 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 7a1baa82..a3ac788d 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -291,6 +291,9 @@ static BOOL output_belongs_to_adapter(IDXGIOutput *output, IDXGIAdapter *adapter IDXGIOutput *o; HRESULT hr;
+ if (!adapter) + return FALSE; + hr = IDXGIOutput_GetDesc(output, &output_desc); ok(SUCCEEDED(hr), "Failed to get output desc, hr %#x.\n", hr);
@@ -737,6 +740,7 @@ static IDXGIAdapter *get_adapter_(unsigned int line, IUnknown *device, BOOL is_d hr = IDXGIFactory_QueryInterface(factory, &IID_IDXGIFactory4, (void **)&factory4); ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#x.\n", hr); hr = IDXGIFactory4_EnumAdapterByLuid(factory4, luid, &IID_IDXGIAdapter, (void **)&adapter); + todo_wine ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#x.\n", hr); IDXGIFactory4_Release(factory4); IDXGIFactory_Release(factory); @@ -1450,21 +1454,21 @@ struct refresh_rates BOOL denominator_should_pass; };
-static void test_create_swapchain(void) +static void test_create_swapchain(IUnknown *device, BOOL is_d3d12) { struct swapchain_fullscreen_state initial_state, expected_state; unsigned int i, expected_width, expected_height; DXGI_SWAP_CHAIN_DESC creation_desc, result_desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; + IUnknown *obj = device, *obj2, *parent; + ULONG refcount, expected_refcount = 0; DXGI_SWAP_CHAIN_DESC1 swapchain_desc; - IDXGIDevice *device, *bgra_device; - ULONG refcount, expected_refcount; - IUnknown *obj, *obj2, *parent; + IDXGIAdapter *adapter = NULL; IDXGISwapChain1 *swapchain1; RECT *expected_client_rect; IDXGISwapChain *swapchain; + IDXGIDevice *bgra_device; IDXGISurface1 *surface; - IDXGIAdapter *adapter; IDXGIFactory *factory; IDXGIOutput *target; BOOL fullscreen; @@ -1480,11 +1484,7 @@ static void test_create_swapchain(void) { 0, 0, TRUE, FALSE}, };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } + get_factory(device, is_d3d12, &factory);
creation_desc.BufferDesc.Width = 800; creation_desc.BufferDesc.Height = 600; @@ -1496,26 +1496,29 @@ static void test_create_swapchain(void) creation_desc.SampleDesc.Count = 1; creation_desc.SampleDesc.Quality = 0; creation_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - creation_desc.BufferCount = 1; + creation_desc.BufferCount = is_d3d12 ? 2 : 1; creation_desc.OutputWindow = NULL; creation_desc.Windowed = TRUE; - creation_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + creation_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; creation_desc.Flags = 0;
- hr = IDXGIDevice_QueryInterface(device, &IID_IUnknown, (void **)&obj); - ok(hr == S_OK, "IDXGIDevice does not implement IUnknown.\n"); - - hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); - - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Failed to get parent, hr %#x.\n", hr); + if (!is_d3d12) + { + hr = IDXGIDevice_QueryInterface((IDXGIDevice *)device, &IID_IUnknown, (void **)&obj); + ok(hr == S_OK, "IDXGIDevice does not implement IUnknown.\n");
- expected_refcount = get_refcount(adapter); - refcount = get_refcount(factory); - ok(refcount == 2, "Got unexpected refcount %u.\n", refcount); - refcount = get_refcount(device); - ok(refcount == 2, "Got unexpected refcount %u.\n", refcount); + hr = IDXGIDevice_GetAdapter((IDXGIDevice *)device, &adapter); + ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); + expected_refcount = get_refcount(adapter); + refcount = get_refcount(factory); + ok(refcount == 2, "Got unexpected refcount %u.\n", refcount); + refcount = get_refcount(device); + ok(refcount == 2, "Got unexpected refcount %u.\n", refcount); + } + else + { + adapter = get_adapter(device, TRUE); + }
creation_desc.OutputWindow = NULL; hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain); @@ -1534,12 +1537,13 @@ static void test_create_swapchain(void) hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain); ok(hr == S_OK, "Failed to create swapchain, hr %#x.\n", hr);
- refcount = get_refcount(adapter); + refcount = !adapter ? 0 : get_refcount(adapter); ok(refcount >= expected_refcount, "Got refcount %u, expected >= %u.\n", refcount, expected_refcount); refcount = get_refcount(factory); - todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount); + todo_wine ok(refcount == 5 || broken(refcount == 4), "Got unexpected refcount %u.\n", refcount); refcount = get_refcount(device); - ok(refcount == 3, "Got unexpected refcount %u.\n", refcount); + todo_wine_if(is_d3d12) + ok(refcount == (is_d3d12 ? 6 : 3), "Got unexpected refcount %u.\n", refcount);
hr = IDXGISwapChain_GetDesc(swapchain, NULL); ok(hr == E_INVALIDARG, "GetDesc unexpectedly returned %#x.\n", hr); @@ -1548,13 +1552,13 @@ static void test_create_swapchain(void) ok(hr == S_OK, "Failed to get parent,%#x.\n", hr); ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent); refcount = IUnknown_Release(parent); - todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount); + todo_wine ok(refcount == 5 || broken(refcount == 4), "Got unexpected refcount %u.\n", refcount);
hr = IDXGISwapChain_GetParent(swapchain, &IID_IDXGIFactory, (void **)&parent); ok(hr == S_OK, "Failed to get parent,%#x.\n", hr); ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent); refcount = IUnknown_Release(parent); - todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount); + todo_wine ok(refcount == 5 || broken(refcount == 4), "Got unexpected refcount %u.\n", refcount);
hr = IDXGISwapChain_QueryInterface(swapchain, &IID_IDXGISwapChain1, (void **)&swapchain1); ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */, @@ -1586,7 +1590,7 @@ static void test_create_swapchain(void) ok(!refcount, "Swapchain has %u references left.\n", refcount);
refcount = get_refcount(factory); - ok(refcount == 2, "Got unexpected refcount %u.\n", refcount); + ok(refcount == (is_d3d12 ? 1 : 2), "Got unexpected refcount %u.\n", refcount);
for (i = 0; i < ARRAY_SIZE(refresh_list); ++i) { @@ -1602,11 +1606,11 @@ static void test_create_swapchain(void) ok(result_desc.Windowed == creation_desc.Windowed, "Test %u: Got unexpected windowed %#x.\n", i, result_desc.Windowed);
- todo_wine_if (!refresh_list[i].numerator_should_pass) + todo_wine_if (!is_d3d12 && !refresh_list[i].numerator_should_pass) ok(result_desc.BufferDesc.RefreshRate.Numerator == refresh_list[i].numerator, "Numerator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Numerator);
- todo_wine_if (!refresh_list[i].denominator_should_pass) + todo_wine_if (!is_d3d12 && !refresh_list[i].denominator_should_pass) ok(result_desc.BufferDesc.RefreshRate.Denominator == refresh_list[i].denominator, "Denominator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Denominator);
@@ -1700,11 +1704,11 @@ static void test_create_swapchain(void) if (result_desc.Windowed != creation_desc.Windowed) trace("Test %u: Failed to change fullscreen state.\n", i);
- todo_wine_if (!refresh_list[i].numerator_should_pass) + todo_wine_if (!is_d3d12 && !refresh_list[i].numerator_should_pass) ok(result_desc.BufferDesc.RefreshRate.Numerator == refresh_list[i].numerator, "Numerator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Numerator);
- todo_wine_if (!refresh_list[i].denominator_should_pass) + todo_wine_if (!is_d3d12 && !refresh_list[i].denominator_should_pass) ok(result_desc.BufferDesc.RefreshRate.Denominator == refresh_list[i].denominator, "Denominator %u is %u.\n", i, result_desc.BufferDesc.RefreshRate.Denominator);
@@ -1724,6 +1728,7 @@ static void test_create_swapchain(void) i, containing_output); IDXGIOutput_Release(containing_output);
+ todo_wine_if(is_d3d12) ok(output_belongs_to_adapter(target, adapter), "Test %u: Output %p doesn't belong to adapter %p.\n", i, target, adapter); @@ -1763,19 +1768,22 @@ static void test_create_swapchain(void) creation_desc.Windowed = TRUE; creation_desc.Flags = 0; hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain); - ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG || hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
creation_desc.Windowed = FALSE; hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain); - ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); - - creation_desc.BufferCount = 2; - creation_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain); ok(hr == E_INVALIDARG || hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); - creation_desc.BufferCount = 1; - creation_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ /* BufferCount and SwapEffect are already set to these values in D3D12. */ + if (!is_d3d12) + { + creation_desc.BufferCount = 2; + creation_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + hr = IDXGIFactory_CreateSwapChain(factory, obj, &creation_desc, &swapchain); + ok(hr == E_INVALIDARG || hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); + creation_desc.BufferCount = 1; + creation_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + } check_window_fullscreen_state(creation_desc.OutputWindow, &initial_state.fullscreen_state);
/* Test swapchain creation with backbuffer width and height equal to 0. */ @@ -1911,9 +1919,9 @@ static void test_create_swapchain(void) ok(hr == S_OK, "Failed to create swapchain, hr %#x.\n", hr); hr = IDXGISwapChain_GetDesc(swapchain, &result_desc); ok(hr == S_OK, "Failed to get swapchain desc, hr %#x.\n", hr); - todo_wine ok(result_desc.BufferDesc.Width == expected_width, "Got width %u, expected %u.\n", + todo_wine_if(!is_d3d12) ok(result_desc.BufferDesc.Width == expected_width, "Got width %u, expected %u.\n", result_desc.BufferDesc.Width, expected_width); - todo_wine ok(result_desc.BufferDesc.Height == expected_height, "Got height %u, expected %u.\n", + todo_wine_if(!is_d3d12) ok(result_desc.BufferDesc.Height == expected_height, "Got height %u, expected %u.\n", result_desc.BufferDesc.Height, expected_height); check_swapchain_fullscreen_state(swapchain, &expected_state); hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); @@ -1924,13 +1932,15 @@ static void test_create_swapchain(void) IDXGIOutput_Release(expected_state.target);
done: - IUnknown_Release(obj); - refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); - refcount = IDXGIAdapter_Release(adapter); - ok(!refcount, "Adapter has %u references left.\n", refcount); + if (!is_d3d12) + { + IUnknown_Release(obj); + refcount = IDXGIAdapter_Release(adapter); + todo_wine + ok(refcount == 2 || broken(refcount == 1), "Adapter has %u references left.\n", refcount); + } refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Factory has %u references left.\n", refcount); check_window_fullscreen_state(creation_desc.OutputWindow, &initial_state.fullscreen_state); DestroyWindow(creation_desc.OutputWindow); } @@ -3008,16 +3018,14 @@ static void test_resize_target_wndproc(void) CloseHandle(thread_data.finished); }
-static void test_inexact_modes(void) +static void test_inexact_modes(IUnknown *device, BOOL is_d3d12) { struct swapchain_fullscreen_state initial_state, expected_state; DXGI_SWAP_CHAIN_DESC swapchain_desc, result_desc; + unsigned int i, expected_width, expected_height; IDXGIOutput *output = NULL; IDXGISwapChain *swapchain; IDXGIFactory *factory; - IDXGIAdapter *adapter; - IDXGIDevice *device; - unsigned int i; ULONG refcount; HRESULT hr;
@@ -3032,17 +3040,7 @@ static void test_inexact_modes(void) {799, 601}, };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } - - hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr); - - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr); + get_factory(device, is_d3d12, &factory);
swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; @@ -3054,10 +3052,10 @@ static void test_inexact_modes(void) swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchain_desc.BufferCount = 1; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); swapchain_desc.Windowed = FALSE; - swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
memset(&initial_state, 0, sizeof(initial_state)); @@ -3105,10 +3103,12 @@ static void test_inexact_modes(void) check_swapchain_fullscreen_state(swapchain, &expected_state); hr = IDXGISwapChain_GetDesc(swapchain, &result_desc); ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr); - ok(result_desc.BufferDesc.Width == sizes[i].width, "Got width %u, expected %u.\n", - result_desc.BufferDesc.Width, sizes[i].width); - ok(result_desc.BufferDesc.Height == sizes[i].height, "Got height %u, expected %u.\n", - result_desc.BufferDesc.Height, sizes[i].height); + expected_width = is_d3d12 ? expected_state.fullscreen_state.client_rect.right : sizes[i].width; + expected_height = is_d3d12 ? expected_state.fullscreen_state.client_rect.bottom : sizes[i].height; + ok(result_desc.BufferDesc.Width == expected_width, "Got width %u, expected %u.\n", + result_desc.BufferDesc.Width, expected_width); + ok(result_desc.BufferDesc.Height == expected_height, "Got height %u, expected %u.\n", + result_desc.BufferDesc.Height, expected_height);
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr); @@ -3176,11 +3176,8 @@ static void test_inexact_modes(void) done: if (output) IDXGIOutput_Release(output); - IDXGIAdapter_Release(adapter); - refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Factory has %u references left.\n", refcount); }
static void test_create_factory(void) @@ -3780,22 +3777,21 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12) ok(refcount == !is_d3d12, "Got unexpected refcount %u.\n", refcount); }
-static void test_swapchain_parameters(void) +static void test_swapchain_parameters(IUnknown *device, BOOL is_d3d12) { DXGI_USAGE usage, expected_usage, broken_usage; D3D10_TEXTURE2D_DESC d3d10_texture_desc; D3D11_TEXTURE2D_DESC d3d11_texture_desc; + D3D12_RESOURCE_DESC d3d12_resource_desc; unsigned int expected_bind_flags; ID3D10Texture2D *d3d10_texture; ID3D11Texture2D *d3d11_texture; + ID3D12Resource *d3d12_resource; DXGI_SWAP_CHAIN_DESC desc; IDXGISwapChain *swapchain; IDXGIResource *resource; - IDXGIAdapter *adapter; IDXGIFactory *factory; - IDXGIDevice *device; unsigned int i, j; - ULONG refcount; IUnknown *obj; HWND window; HRESULT hr; @@ -3805,71 +3801,71 @@ static void test_swapchain_parameters(void) BOOL windowed; UINT buffer_count; DXGI_SWAP_EFFECT swap_effect; - HRESULT hr, vista_hr; + HRESULT hr, vista_hr, d3d12_hr; UINT highest_accessible_buffer; } tests[] = { - {TRUE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, - {TRUE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, - {TRUE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 0}, - {TRUE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 1}, - {TRUE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 2}, - {TRUE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 1}, - {TRUE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 2}, - {TRUE, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, - {TRUE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 15}, - {TRUE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 15}, - {TRUE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {TRUE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - - {FALSE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, - {FALSE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, - {FALSE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 0}, - {FALSE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 1}, - {FALSE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 2}, - {FALSE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 1}, - {FALSE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 2}, - {FALSE, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, - {FALSE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 15}, - {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 15}, + {TRUE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 1}, + {TRUE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 2}, + {TRUE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 1}, + {TRUE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 2}, + {TRUE, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 0}, + {TRUE, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 15}, + {TRUE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 15}, + {TRUE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 0}, + {TRUE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {TRUE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + + {FALSE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 1}, + {FALSE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 2}, + {FALSE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 1}, + {FALSE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 2}, + {FALSE, 0, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 1, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 2, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 0}, + {FALSE, 0, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 1, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 2, 5 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, DXGI_ERROR_INVALID_CALL, 15}, + {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, S_OK, 15}, /* The following test fails on Nvidia with E_OUTOFMEMORY and leaks device references in the * process. Disable it for now. {FALSE, 16, DXGI_SWAP_EFFECT_FLIP_DISCARD, S_OK, DXGI_ERROR_INVALID_CALL, 0}, */ - {FALSE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, - {FALSE, 17, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, + {FALSE, 17, DXGI_SWAP_EFFECT_FLIP_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, }; static const DXGI_USAGE usage_tests[] = { @@ -3885,21 +3881,20 @@ static void test_swapchain_parameters(void) DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_DISCARD_ON_PRESENT, };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } + get_factory(device, is_d3d12, &factory); window = create_window();
- hr = IDXGIDevice_QueryInterface(device, &IID_IUnknown, (void **)&obj); - ok(hr == S_OK, "IDXGIDevice does not implement IUnknown.\n"); - - hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Failed to get parent, hr %#x.\n", hr); - IDXGIAdapter_Release(adapter); + if (is_d3d12) + { + obj = device; + hr = ID3D12CommandQueue_QueryInterface((ID3D12CommandQueue *)device, &IID_IUnknown, (void **)&obj); + ok(hr == S_OK, "ID3D12CommandQueue does not implement IUnknown.\n"); + } + else + { + hr = IDXGIDevice_QueryInterface((IDXGIDevice *)device, &IID_IUnknown, (void **)&obj); + ok(hr == S_OK, "IDXGIDevice does not implement IUnknown.\n"); + }
for (i = 0; i < ARRAY_SIZE(tests); ++i) { @@ -3916,36 +3911,57 @@ static void test_swapchain_parameters(void) desc.SwapEffect = tests[i].swap_effect;
hr = IDXGIFactory_CreateSwapChain(factory, obj, &desc, &swapchain); - ok(hr == tests[i].hr || broken(hr == tests[i].vista_hr) + ok(hr == (is_d3d12 ? tests[i].d3d12_hr : tests[i].hr) || broken(hr == tests[i].vista_hr) || (SUCCEEDED(tests[i].hr) && hr == DXGI_STATUS_OCCLUDED), "Got unexpected hr %#x, test %u.\n", hr, i); if (FAILED(hr)) continue;
- hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource); - todo_wine ok(SUCCEEDED(hr), "GetBuffer(0) failed, hr %#x, test %u.\n", hr, i); - if (FAILED(hr)) + if (!is_d3d12) { - hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); - ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource); + todo_wine ok(SUCCEEDED(hr), "GetBuffer(0) failed, hr %#x, test %u.\n", hr, i); + if (FAILED(hr)) + { + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); + ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
- IDXGISwapChain_Release(swapchain); - continue; + IDXGISwapChain_Release(swapchain); + continue; + } + + expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; + if (tests[i].swap_effect == DXGI_SWAP_EFFECT_DISCARD) + expected_usage |= DXGI_USAGE_DISCARD_ON_PRESENT; + hr = IDXGIResource_GetUsage(resource, &usage); + ok(SUCCEEDED(hr), "Failed to get resource usage, hr %#x, test %u.\n", hr, i); + ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i); + + IDXGIResource_Release(resource); } + else + { + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D12Resource, (void **)&d3d12_resource); + ok(SUCCEEDED(hr), "GetBuffer(0) failed, hr %#x, test %u.\n", hr, i); + if (FAILED(hr)) + { + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); + ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
- expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; - if (tests[i].swap_effect == DXGI_SWAP_EFFECT_DISCARD) - expected_usage |= DXGI_USAGE_DISCARD_ON_PRESENT; - hr = IDXGIResource_GetUsage(resource, &usage); - ok(SUCCEEDED(hr), "Failed to get resource usage, hr %#x, test %u.\n", hr, i); - ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i); + IDXGISwapChain_Release(swapchain); + continue; + }
- IDXGIResource_Release(resource); + d3d12_resource_desc = ID3D12Resource_GetDesc(d3d12_resource); + ok(d3d12_resource_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, "D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET not set, test %u.\n", i); + + ID3D12Resource_Release(d3d12_resource); + }
hr = IDXGISwapChain_GetDesc(swapchain, &desc); ok(SUCCEEDED(hr), "Failed to get swapchain desc, hr %#x.\n", hr);
- for (j = 1; j <= tests[i].highest_accessible_buffer; j++) + if (!is_d3d12) for (j = 1; j <= tests[i].highest_accessible_buffer; j++) { hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource); ok(SUCCEEDED(hr), "GetBuffer(%u) failed, hr %#x, test %u.\n", hr, i, j); @@ -3980,8 +3996,29 @@ static void test_swapchain_parameters(void)
IDXGIResource_Release(resource); } - hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource); - ok(hr == DXGI_ERROR_INVALID_CALL, "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j, hr, i); + else for (j = 1; j <= tests[i].highest_accessible_buffer; j++) + { + hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_ID3D12Resource, (void **)&d3d12_resource); + ok(SUCCEEDED(hr), "GetBuffer(%u) failed, hr %#x, test %u.\n", hr, i, j); + d3d12_resource_desc = ID3D12Resource_GetDesc(d3d12_resource); + ok(d3d12_resource_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, + "D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET not set, test %u.\n", i); + + ID3D12Resource_Release(d3d12_resource); + } + if (!is_d3d12) + { + hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource); + ok(hr == DXGI_ERROR_INVALID_CALL, "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j, hr, i); + } + else + { + hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_ID3D12Resource, (void **)&d3d12_resource); + ok(hr == (tests[i].swap_effect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ? DXGI_ERROR_INVALID_CALL : tests[i].d3d12_hr), + "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j, hr, i); + if (SUCCEEDED(hr)) + ID3D12Resource_Release(d3d12_resource); + }
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr); @@ -3992,6 +4029,11 @@ static void test_swapchain_parameters(void) for (i = 0; i < ARRAY_SIZE(usage_tests); ++i) { usage = usage_tests[i]; + if (usage & DXGI_USAGE_DISCARD_ON_PRESENT) + { + skip("DXGI_USAGE_DISCARD_ON_PRESENT is not valid in D3D12.\n"); + continue; + }
memset(&desc, 0, sizeof(desc)); desc.BufferDesc.Width = registry_mode.dmPelsWidth; @@ -3999,16 +4041,16 @@ static void test_swapchain_parameters(void) desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.SampleDesc.Count = 1; desc.BufferUsage = usage; - desc.BufferCount = 1; + desc.BufferCount = is_d3d12 ? 2 : 1; desc.OutputWindow = window; desc.Windowed = TRUE; - desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; hr = IDXGIFactory_CreateSwapChain(factory, obj, &desc, &swapchain); ok(hr == S_OK, "Got unexpected hr %#x, test %u.\n", hr, i);
hr = IDXGISwapChain_GetDesc(swapchain, &desc); ok(hr == S_OK, "Failed to get swapchain desc, hr %#x, test %u.\n", hr, i); - todo_wine_if(usage & ~(DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT)) + todo_wine_if(!is_d3d12 && (usage & ~(DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT))) ok(desc.BufferUsage == usage, "Got usage %#x, expected %#x, test %u.\n", desc.BufferUsage, usage, i);
expected_bind_flags = 0; @@ -4017,42 +4059,64 @@ static void test_swapchain_parameters(void) if (usage & DXGI_USAGE_SHADER_INPUT) expected_bind_flags |= D3D11_BIND_SHADER_RESOURCE;
- hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&d3d10_texture); - ok(hr == S_OK, "Failed to get d3d10 texture, hr %#x, test %u.\n", hr, i); - ID3D10Texture2D_GetDesc(d3d10_texture, &d3d10_texture_desc); - ok(d3d10_texture_desc.BindFlags == expected_bind_flags, - "Got d3d10 bind flags %#x, expected %#x, test %u.\n", - d3d10_texture_desc.BindFlags, expected_bind_flags, i); - ID3D10Texture2D_Release(d3d10_texture); - - hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D11Texture2D, (void **)&d3d11_texture); - ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get d3d11 texture, hr %#x, test %u.\n", hr, i); - if (SUCCEEDED(hr)) + if (!is_d3d12) { - ID3D11Texture2D_GetDesc(d3d11_texture, &d3d11_texture_desc); - ok(d3d11_texture_desc.BindFlags == expected_bind_flags, - "Got d3d11 bind flags %#x, expected %#x, test %u.\n", - d3d11_texture_desc.BindFlags, expected_bind_flags, i); - ID3D11Texture2D_Release(d3d11_texture); - } + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&d3d10_texture); + ok(hr == S_OK, "Failed to get d3d10 texture, hr %#x, test %u.\n", hr, i); + ID3D10Texture2D_GetDesc(d3d10_texture, &d3d10_texture_desc); + ok(d3d10_texture_desc.BindFlags == expected_bind_flags, + "Got d3d10 bind flags %#x, expected %#x, test %u.\n", + d3d10_texture_desc.BindFlags, expected_bind_flags, i); + ID3D10Texture2D_Release(d3d10_texture); + + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D11Texture2D, (void **)&d3d11_texture); + ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get d3d11 texture, hr %#x, test %u.\n", hr, i); + if (SUCCEEDED(hr)) + { + ID3D11Texture2D_GetDesc(d3d11_texture, &d3d11_texture_desc); + ok(d3d11_texture_desc.BindFlags == expected_bind_flags, + "Got d3d11 bind flags %#x, expected %#x, test %u.\n", + d3d11_texture_desc.BindFlags, expected_bind_flags, i); + ID3D11Texture2D_Release(d3d11_texture); + }
- hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource); - todo_wine ok(hr == S_OK, "Failed to get buffer, hr %#x, test %u.\n", hr, i); - if (FAILED(hr)) + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource); + todo_wine ok(hr == S_OK, "Failed to get buffer, hr %#x, test %u.\n", hr, i); + if (FAILED(hr)) + { + IDXGISwapChain_Release(swapchain); + continue; + } + expected_usage = usage | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_DISCARD_ON_PRESENT; + hr = IDXGIResource_GetUsage(resource, &usage); + ok(hr == S_OK, "Failed to get resource usage, hr %#x, test %u.\n", hr, i); + ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i); + IDXGIResource_Release(resource); + } + else { - IDXGISwapChain_Release(swapchain); - continue; + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D12Resource, (void **)&d3d12_resource); + ok(hr == S_OK, "Failed to get buffer, hr %#x, test %u.\n", hr, i); + if (FAILED(hr)) + { + IDXGISwapChain_Release(swapchain); + continue; + } + d3d12_resource_desc = ID3D12Resource_GetDesc(d3d12_resource); + ok(d3d12_resource_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, "D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET not set, test %u.\n", i); + ID3D12Resource_Release(d3d12_resource); } - expected_usage = usage | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_DISCARD_ON_PRESENT; - hr = IDXGIResource_GetUsage(resource, &usage); - ok(hr == S_OK, "Failed to get resource usage, hr %#x, test %u.\n", hr, i); - ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i); - IDXGIResource_Release(resource);
IDXGISwapChain_Release(swapchain); }
/* multisampling */ + if (is_d3d12) + { + skip("Multisampled render targets are resolved explicitly in D3D12.\n"); + goto done; + } + memset(&desc, 0, sizeof(desc)); desc.BufferDesc.Width = registry_mode.dmPelsWidth; desc.BufferDesc.Height = registry_mode.dmPelsHeight; @@ -4068,7 +4132,7 @@ static void test_swapchain_parameters(void) desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; hr = IDXGIFactory_CreateSwapChain(factory, obj, &desc, &swapchain); ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); - if (check_multisample_quality_levels(device, desc.BufferDesc.Format, desc.SampleDesc.Count)) + if (check_multisample_quality_levels((IDXGIDevice *)device, desc.BufferDesc.Format, desc.SampleDesc.Count)) { desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; hr = IDXGIFactory_CreateSwapChain(factory, obj, &desc, &swapchain); @@ -4084,10 +4148,9 @@ static void test_swapchain_parameters(void) skip("Multisampling not supported for DXGI_FORMAT_R8G8B8A8_UNORM.\n"); }
+done: IDXGIFactory_Release(factory); IUnknown_Release(obj); - refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); DestroyWindow(window); }
@@ -4857,14 +4920,12 @@ static LRESULT CALLBACK test_wndproc(HWND hwnd, unsigned int message, WPARAM wpa return DefWindowProcA(hwnd, message, wparam, lparam); }
-static void test_swapchain_window_messages(void) +static void test_swapchain_window_messages(IUnknown *device, BOOL is_d3d12) { DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; DXGI_MODE_DESC mode_desc; IDXGIFactory *factory; - IDXGIAdapter *adapter; - IDXGIDevice *device; ULONG refcount; WNDCLASSA wc; HWND window; @@ -4926,11 +4987,7 @@ static void test_swapchain_window_messages(void) {0, FALSE, 0}, };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } + get_factory(device, is_d3d12, &factory);
memset(&wc, 0, sizeof(wc)); wc.lpfnWndProc = test_wndproc; @@ -4939,12 +4996,6 @@ static void test_swapchain_window_messages(void) window = CreateWindowA("dxgi_test_wndproc_wc", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); ok(!!window, "Failed to create window.\n");
- hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Failed to get parent, hr %#x.\n", hr); - IDXGIAdapter_Release(adapter); - swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; @@ -4955,10 +5006,10 @@ static void test_swapchain_window_messages(void) swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchain_desc.BufferCount = 1; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; swapchain_desc.OutputWindow = window; swapchain_desc.Windowed = TRUE; - swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; swapchain_desc.Flags = 0;
/* create swapchain */ @@ -5051,22 +5102,18 @@ done: ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount); DestroyWindow(window);
- refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Factory has %u references left.\n", refcount);
UnregisterClassA("dxgi_test_wndproc_wc", GetModuleHandleA(NULL)); }
-static void test_swapchain_window_styles(void) +static void test_swapchain_window_styles(IUnknown *device, BOOL is_d3d12) { LONG style, exstyle, fullscreen_style, fullscreen_exstyle; DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; IDXGIFactory *factory; - IDXGIAdapter *adapter; - IDXGIDevice *device; ULONG refcount; unsigned int i; HRESULT hr; @@ -5094,17 +5141,7 @@ static void test_swapchain_window_styles(void) WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE}, };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } - - hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Failed to get parent, hr %#x.\n", hr); - IDXGIAdapter_Release(adapter); + get_factory(device, is_d3d12, &factory);
swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; @@ -5116,9 +5153,9 @@ static void test_swapchain_window_styles(void) swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchain_desc.BufferCount = 1; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; swapchain_desc.Windowed = TRUE; - swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; swapchain_desc.Flags = 0;
for (i = 0; i < ARRAY_SIZE(tests); ++i) @@ -5192,10 +5229,8 @@ static void test_swapchain_window_styles(void) DestroyWindow(swapchain_desc.OutputWindow); }
- refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Factory has %u references left.\n", refcount); }
static void test_gamma_control(void) @@ -5310,15 +5345,13 @@ done: ok(!refcount, "Factory has %u references left.\n", refcount); }
-static void test_window_association(void) +static void test_window_association(IUnknown *device, BOOL is_d3d12) { DXGI_SWAP_CHAIN_DESC swapchain_desc; LONG_PTR original_wndproc, wndproc; IDXGIFactory *factory, *factory2; IDXGISwapChain *swapchain; IDXGIOutput *output; - IDXGIAdapter *adapter; - IDXGIDevice *device; HWND hwnd, hwnd2; BOOL fullscreen; unsigned int i; @@ -5355,12 +5388,6 @@ static void test_window_association(void) {0, FALSE} };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } - swapchain_desc.BufferDesc.Width = 640; swapchain_desc.BufferDesc.Height = 480; swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; @@ -5371,10 +5398,10 @@ static void test_window_association(void) swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchain_desc.BufferCount = 1; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); swapchain_desc.Windowed = TRUE; - swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; swapchain_desc.Flags = 0;
original_wndproc = GetWindowLongPtrW(swapchain_desc.OutputWindow, GWLP_WNDPROC); @@ -5383,11 +5410,7 @@ static void test_window_association(void) hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory2); ok(hr == S_OK, "Failed to create DXGI factory, hr %#x.\n", hr);
- hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); - refcount = IDXGIAdapter_Release(adapter); + get_factory(device, is_d3d12, &factory);
hr = IDXGIFactory_GetWindowAssociation(factory, NULL); ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); @@ -5463,6 +5486,7 @@ static void test_window_association(void) output = NULL; hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &output); ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr); + todo_wine_if(is_d3d12 && tests[i].expect_fullscreen) ok(fullscreen == tests[i].expect_fullscreen || broken(tests[i].broken_d3d10 && fullscreen), "Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen); @@ -5487,10 +5511,8 @@ static void test_window_association(void) ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount); DestroyWindow(swapchain_desc.OutputWindow);
- refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Factory has %u references left.\n", refcount); }
static void test_output_ownership(IUnknown *device, BOOL is_d3d12) @@ -5730,14 +5752,15 @@ START_TEST(dxgi) run_queued_tests();
/* These tests use full-screen swapchains, so shouldn't run in parallel. */ - test_create_swapchain(); + run_on_d3d10(test_create_swapchain); test_default_fullscreen_target_output(); - test_inexact_modes(); + run_on_d3d10(test_inexact_modes); + /* IDXGIOutput_GetGammaControlCapabilities is not available on D3D12. */ test_gamma_control(); - test_swapchain_parameters(); - test_swapchain_window_messages(); - test_swapchain_window_styles(); - test_window_association(); + run_on_d3d10(test_swapchain_parameters); + run_on_d3d10(test_swapchain_window_messages); + run_on_d3d10(test_swapchain_window_styles); + run_on_d3d10(test_window_association); run_on_d3d10(test_set_fullscreen); run_on_d3d10(test_resize_target); run_on_d3d10(test_swapchain_resize); @@ -5761,6 +5784,12 @@ START_TEST(dxgi) ID3D12Debug_Release(debug); }
+ run_on_d3d12(test_create_swapchain); + run_on_d3d12(test_inexact_modes); + run_on_d3d12(test_swapchain_parameters); + run_on_d3d12(test_swapchain_window_messages); + run_on_d3d12(test_swapchain_window_styles); + run_on_d3d12(test_window_association); run_on_d3d12(test_set_fullscreen); run_on_d3d12(test_resize_target); run_on_d3d12(test_swapchain_resize);