Prevents test failure and crash until multi-monitor support is improved.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 0f256d4c..7a1baa82 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -1935,6 +1935,22 @@ done: DestroyWindow(creation_desc.OutputWindow); }
+static HMONITOR get_primary_if_right_side_secondary(const DXGI_OUTPUT_DESC *output_desc) +{ + HMONITOR primary, secondary; + MONITORINFO mi; + POINT pt = {0, 0}; + + primary = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); + pt.x = output_desc->DesktopCoordinates.right; + secondary = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); + mi.cbSize = sizeof(mi); + if (secondary && secondary != primary + && GetMonitorInfoW(primary, &mi) && (mi.dwFlags & MONITORINFOF_PRIMARY)) + return primary; + return NULL; +} + static void test_get_containing_output(void) { unsigned int output_count, output_idx; @@ -1949,6 +1965,7 @@ static void test_get_containing_output(void) IDXGIDevice *device; unsigned int i, j; HMONITOR monitor; + HMONITOR primary; ULONG refcount; HRESULT hr; BOOL ret; @@ -2031,6 +2048,8 @@ static void test_get_containing_output(void) wine_dbgstr_rect(&output_desc.DesktopCoordinates), wine_dbgstr_rect(&monitor_info.rcMonitor));
+ primary = get_primary_if_right_side_secondary(&output_desc); + output_idx = 0; while ((hr = IDXGIAdapter_EnumOutputs(adapter, output_idx, &output)) != DXGI_ERROR_NOT_FOUND) { @@ -2113,9 +2132,11 @@ static void test_get_containing_output(void) ok(ret, "Failed to get monitor info.\n");
hr = IDXGISwapChain_GetContainingOutput(swapchain, &output); + /* Hack to prevent test failures with secondary on the right until multi-monitor support is improved. */ + todo_wine_if(primary && monitor != primary) ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED), "Failed to get containing output, hr %#x.\n", hr); - if (hr == DXGI_ERROR_UNSUPPORTED) + if (hr != S_OK) continue; ok(!!output, "Got unexpected containing output %p.\n", output); hr = IDXGIOutput_GetDesc(output, &output_desc);
For D3D12 use in dxgi.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/wined3d/swapchain.c | 84 ++++++++++++++++++++++------------ dlls/wined3d/wined3d.spec | 4 ++ dlls/wined3d/wined3d_private.h | 2 - include/wine/wined3d.h | 7 +++ 4 files changed, 65 insertions(+), 32 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 62bab65f..29e63d0e 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -29,7 +29,6 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) { - HRESULT hr; UINT i;
TRACE("Destroying swapchain %p.\n", swapchain); @@ -61,30 +60,39 @@ void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) swapchain->back_buffers = NULL; }
+ wined3d_swapchain_state_cleanup_fullscreen(&swapchain->state, swapchain->device->wined3d, + swapchain->device->adapter->ordinal, swapchain->device); +} + +void CDECL wined3d_swapchain_state_cleanup_fullscreen(struct wined3d_swapchain_state *state, + struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_device *device) +{ + HRESULT hr; + /* Restore the screen resolution if we rendered in fullscreen. * This will restore the screen resolution to what it was before creating * the swapchain. In case of d3d8 and d3d9 this will be the original * desktop resolution. In case of d3d7 this will be a NOP because ddraw * sets the resolution before starting up Direct3D, thus orig_width and * orig_height will be equal to the modes in the presentation params. */ - if (!swapchain->state.desc.windowed) + if (!state->desc.windowed) { - if (swapchain->state.desc.auto_restore_display_mode) + if (state->desc.auto_restore_display_mode) { - if (FAILED(hr = wined3d_set_adapter_display_mode(swapchain->device->wined3d, - swapchain->device->adapter->ordinal, &swapchain->state.original_mode))) + if (FAILED(hr = wined3d_set_adapter_display_mode(wined3d, adapter_idx, &state->original_mode))) ERR("Failed to restore display mode, hr %#x.\n", hr);
- if (swapchain->state.desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) + if (state->desc.flags & WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT) { - wined3d_swapchain_state_restore_from_fullscreen(&swapchain->state, - swapchain->state.device_window, &swapchain->state.original_window_rect); - wined3d_device_release_focus_window(swapchain->device); + wined3d_swapchain_state_restore_from_fullscreen(state, + state->device_window, &state->original_window_rect); + if (device) + wined3d_device_release_focus_window(device); } } else { - wined3d_swapchain_state_restore_from_fullscreen(&swapchain->state, swapchain->state.device_window, NULL); + wined3d_swapchain_state_restore_from_fullscreen(state, state->device_window, NULL); } } } @@ -809,7 +817,6 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc struct wined3d_resource_desc texture_desc; BOOL displaymode_set = FALSE; DWORD texture_flags = 0; - RECT client_rect; unsigned int i; HWND window; HRESULT hr; @@ -840,27 +847,9 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT; swapchain_set_max_frame_latency(swapchain, device);
- GetClientRect(window, &client_rect); if (desc->windowed) { - TRACE("Client rect %s.\n", wine_dbgstr_rect(&client_rect)); - - if (!desc->backbuffer_width) - { - desc->backbuffer_width = client_rect.right ? client_rect.right : 8; - TRACE("Updating width to %u.\n", desc->backbuffer_width); - } - if (!desc->backbuffer_height) - { - desc->backbuffer_height = client_rect.bottom ? client_rect.bottom : 8; - TRACE("Updating height to %u.\n", desc->backbuffer_height); - } - - if (desc->backbuffer_format == WINED3DFMT_UNKNOWN) - { - desc->backbuffer_format = swapchain->state.original_mode.format_id; - TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->state.original_mode.format_id)); - } + wined3d_swapchain_desc_set_backbuffer_defaults(desc, window, device->wined3d, adapter->ordinal); } else { @@ -1378,6 +1367,41 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha return WINED3D_OK; }
+void CDECL wined3d_swapchain_desc_set_backbuffer_defaults(struct wined3d_swapchain_desc *desc, + HWND window, const struct wined3d *wined3d, unsigned int adapter_idx) +{ + struct wined3d_display_mode mode; + RECT client_rect; + HRESULT hr; + + GetClientRect(window, &client_rect); + TRACE("Client rect %s.\n", wine_dbgstr_rect(&client_rect)); + + if (!desc->backbuffer_width) + { + desc->backbuffer_width = client_rect.right ? client_rect.right : 8; + TRACE("Updating width to %u.\n", desc->backbuffer_width); + } + if (!desc->backbuffer_height) + { + desc->backbuffer_height = client_rect.bottom ? client_rect.bottom : 8; + TRACE("Updating height to %u.\n", desc->backbuffer_height); + } + + if (desc->backbuffer_format == WINED3DFMT_UNKNOWN) + { + if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, NULL))) + { + WARN("Failed to get current display mode, hr %#x.\n", hr); + } + else + { + desc->backbuffer_format = mode.format_id; + TRACE("Updating format to %s.\n", debug_d3dformat(mode.format_id)); + } + } +} + static HRESULT wined3d_swapchain_state_set_display_mode(struct wined3d_swapchain_state *state, struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_display_mode *mode) { diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index b65681f2..2fbf21b7 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -286,10 +286,14 @@ @ cdecl wined3d_swapchain_set_palette(ptr ptr) @ cdecl wined3d_swapchain_set_window(ptr ptr)
+@ cdecl wined3d_swapchain_desc_set_backbuffer_defaults(ptr ptr) + +@ cdecl wined3d_swapchain_state_cleanup_fullscreen(ptr ptr long ptr) @ cdecl wined3d_swapchain_state_create(ptr ptr ptr long ptr) @ cdecl wined3d_swapchain_state_destroy(ptr) @ cdecl wined3d_swapchain_state_resize_target(ptr ptr long ptr) @ cdecl wined3d_swapchain_state_set_fullscreen(ptr ptr ptr long ptr) +@ cdecl wined3d_swapchain_state_setup_fullscreen(ptr ptr long long)
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr) @ cdecl wined3d_texture_blt(ptr long ptr ptr long ptr long ptr long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 307f7a42..bc853875 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4439,8 +4439,6 @@ struct wined3d_swapchain_state
void wined3d_swapchain_state_restore_from_fullscreen(struct wined3d_swapchain_state *state, HWND window, const RECT *window_rect) DECLSPEC_HIDDEN; -HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state *state, - HWND window, unsigned int w, unsigned int h) DECLSPEC_HIDDEN;
struct wined3d_swapchain_ops { diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index f79cd212..69000fe4 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2706,11 +2706,18 @@ HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette); void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window);
+void __cdecl wined3d_swapchain_desc_set_backbuffer_defaults(struct wined3d_swapchain_desc *desc, + HWND window, const struct wined3d *wined3d, unsigned int adapter_idx); + +void __cdecl wined3d_swapchain_state_cleanup_fullscreen(struct wined3d_swapchain_state *state, + struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_device *device); HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc, HWND window, struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_swapchain_state **state); void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state); HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state, struct wined3d *wined3d, unsigned int adapter_idx, const struct wined3d_display_mode *mode); +HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state *state, + HWND window, unsigned int w, unsigned int h); HRESULT __cdecl wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_state *state, const struct wined3d_swapchain_desc *desc, struct wined3d *wined3d, unsigned int adapter_idx, const struct wined3d_display_mode *mode);
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/swapchain.c | 89 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 6 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index c76ad1d1..1787ced5 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1877,6 +1877,10 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; void *vulkan_module = vk_funcs->vulkan_module; + struct dxgi_adapter *dxgi_adapter; + IUnknown *device_parent; + IDXGIAdapter *adapter; + HRESULT hr;
d3d12_swapchain_destroy_buffers(swapchain, TRUE);
@@ -1885,6 +1889,18 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain)
wined3d_private_store_cleanup(&swapchain->private_store);
+ device_parent = vkd3d_get_device_parent(swapchain->device); + if (SUCCEEDED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter))) + { + dxgi_adapter = unsafe_impl_from_IDXGIAdapter(adapter); + wined3d_swapchain_state_cleanup_fullscreen(swapchain->state, dxgi_adapter->factory->wined3d, dxgi_adapter->ordinal, NULL); + IDXGIAdapter_Release(adapter); + } + else + { + ERR("Failed to get adapter for fullscreen state cleanup, hr %#x.\n", hr); + } + if (swapchain->vk_device) { vk_funcs->p_vkDestroyFence(swapchain->vk_device, swapchain->vk_fence, NULL); @@ -2807,6 +2823,36 @@ static BOOL init_vk_funcs(struct dxgi_vk_funcs *dxgi, VkInstance vk_instance, Vk return TRUE; }
+static HRESULT d3d12_swapchain_desc_adjust_display_mode(HWND window, struct wined3d_swapchain_desc *wined3d_desc, + const struct dxgi_adapter *dxgi_adapter) +{ + struct wined3d_display_mode wined3d_mode; + HRESULT hr; + + wined3d_mode.width = wined3d_desc->backbuffer_width; + wined3d_mode.height = wined3d_desc->backbuffer_height; + wined3d_mode.refresh_rate = wined3d_desc->refresh_rate; + wined3d_mode.format_id = wined3d_desc->backbuffer_format; + wined3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; + + wined3d_mutex_lock(); + hr = wined3d_find_closest_matching_adapter_mode(dxgi_adapter->factory->wined3d, dxgi_adapter->ordinal, &wined3d_mode); + wined3d_mutex_unlock(); + + if (SUCCEEDED(hr)) + { + if (wined3d_desc->backbuffer_width != wined3d_mode.width || wined3d_desc->backbuffer_height != wined3d_mode.height) + TRACE("Adjusting resolution from (%ux%u) to (%ux%u).\n", wined3d_desc->backbuffer_width, + wined3d_desc->backbuffer_height, wined3d_mode.width, wined3d_mode.height); + wined3d_desc->backbuffer_width = wined3d_mode.width; + wined3d_desc->backbuffer_height = wined3d_mode.height; + wined3d_desc->backbuffer_format = wined3d_mode.format_id; + wined3d_desc->refresh_rate = wined3d_mode.refresh_rate; + } + + return hr; +} + static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGIFactory *factory, ID3D12Device *device, ID3D12CommandQueue *queue, HWND window, const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc) @@ -2867,10 +2913,21 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI IDXGIAdapter_Release(adapter); if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, swapchain_desc, fullscreen_desc))) return hr; + + /* For fullscreen swapchains, D3D12 changes the swapchain size to match the mode resolution. */ + if (!fullscreen_desc->Windowed && FAILED(hr = d3d12_swapchain_desc_adjust_display_mode(window, + &wined3d_desc, dxgi_adapter))) + ERR("Failed to adjust resolution for fullscreen swapchain, hr %#x.\n", hr); + + wined3d_desc.windowed = TRUE; if (FAILED(hr = wined3d_swapchain_state_create(&wined3d_desc, window, dxgi_adapter->factory->wined3d, dxgi_adapter->ordinal, &swapchain->state))) return hr;
+ swapchain->desc.Width = wined3d_desc.backbuffer_width; + swapchain->desc.Height = wined3d_desc.backbuffer_height; + swapchain->desc.Format = dxgi_format_from_wined3dformat(wined3d_desc.backbuffer_format); + if (swapchain_desc->BufferUsage && swapchain_desc->BufferUsage != DXGI_USAGE_RENDER_TARGET_OUTPUT) FIXME("Ignoring buffer usage %#x.\n", swapchain_desc->BufferUsage); if (swapchain_desc->Scaling != DXGI_SCALING_STRETCH) @@ -2885,8 +2942,6 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI FIXME("Unhandled scanline ordering %#x.\n", fullscreen_desc->ScanlineOrdering); if (fullscreen_desc->Scaling) FIXME("Unhandled mode scaling %#x.\n", fullscreen_desc->Scaling); - if (!fullscreen_desc->Windowed) - FIXME("Fullscreen not supported yet.\n");
vk_instance = vkd3d_instance_get_vk_instance(vkd3d_instance_from_device(device)); vk_physical_device = vkd3d_get_vk_physical_device(device); @@ -2930,10 +2985,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI ID3D12Device_AddRef(swapchain->device = device);
if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain))) - { - d3d12_swapchain_destroy(swapchain); - return hr; - } + goto cleanup;
fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_desc.pNext = NULL; @@ -2955,7 +3007,32 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
IWineDXGIFactory_AddRef(swapchain->factory = factory);
+ if (!fullscreen_desc->Windowed) + { + if (FAILED(hr = IDXGISwapChain3_GetContainingOutput(&swapchain->IDXGISwapChain3_iface, + &swapchain->target))) + { + ERR("Failed to get target output for fullscreen swapchain, hr %#x.\n", hr); + goto cleanup; + } + + wined3d_desc.windowed = FALSE; + wined3d_mutex_lock(); + hr = dxgi_swapchain_set_fullscreen_state(swapchain->state, &wined3d_desc, swapchain->target); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("Failed to set fullscreen state, hr %#x.\n", hr); + IDXGIOutput_Release(swapchain->target); + goto cleanup; + } + } + return S_OK; + +cleanup: + d3d12_swapchain_destroy(swapchain); + return hr; }
HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window,
Both values will be zero if fullscreen_desc was NULL.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/swapchain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 1787ced5..0a661273 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2937,7 +2937,8 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI if (swapchain_desc->Flags) FIXME("Ignoring swapchain flags %#x.\n", swapchain_desc->Flags);
- FIXME("Ignoring refresh rate.\n"); + if (fullscreen_desc->RefreshRate.Numerator || fullscreen_desc->RefreshRate.Denominator) + FIXME("Ignoring refresh rate.\n"); if (fullscreen_desc->ScanlineOrdering) FIXME("Unhandled scanline ordering %#x.\n", fullscreen_desc->ScanlineOrdering); if (fullscreen_desc->Scaling)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/swapchain.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 0a661273..af87c055 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2913,6 +2913,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI IDXGIAdapter_Release(adapter); if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, swapchain_desc, fullscreen_desc))) return hr; + wined3d_swapchain_desc_set_backbuffer_defaults(&wined3d_desc, window, dxgi_adapter->factory->wined3d, dxgi_adapter->ordinal);
/* For fullscreen swapchains, D3D12 changes the swapchain size to match the mode resolution. */ if (!fullscreen_desc->Windowed && FAILED(hr = d3d12_swapchain_desc_adjust_display_mode(window,
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);
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=57625
Your paranoid android.
=== wvistau64 (64 bit report) ===
dxgi: dxgi.c:5097: Test failed: Expected message 0x47.
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=57619
Your paranoid android.
=== w8adm (32 bit report) ===
dxgi: dxgi.c:2421: Test failed: Got unexpected hr 0x887a0022. dxgi.c:2424: Test failed: Got unexpected hr 0x887a0022.