-- v2: dxgi: Reset the back buffer index to zero on ResizeBuffers(). dxgi/tests: Test that ResizeBuffers() resets the back buffer index to zero. dxgi: Always assume that a D3D12 swapchain always uses user images. dxgi: Immediately error out when creating a D3D12 swapchain on a non-immediate queue. dxgi/tests: Test that D3D12 swapchains can only be created on direct command queues.
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 84 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index e0465b90ed0..0a5b0a584d2 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -776,13 +776,13 @@ static ID3D12Device *create_d3d12_device(void) return device; }
-static ID3D12CommandQueue *create_d3d12_direct_queue(ID3D12Device *device) +static ID3D12CommandQueue *create_d3d12_queue(ID3D12Device *device, D3D12_COMMAND_LIST_TYPE type) { D3D12_COMMAND_QUEUE_DESC command_queue_desc; ID3D12CommandQueue *queue; HRESULT hr;
- command_queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + command_queue_desc.Type = type; command_queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; command_queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; command_queue_desc.NodeMask = 0; @@ -7610,7 +7610,7 @@ static void run_on_d3d12(void (*test_func)(IUnknown *device, BOOL is_d3d12)) return; }
- queue = create_d3d12_direct_queue(device); + queue = create_d3d12_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT);
test_func((IUnknown *)queue, TRUE);
@@ -7622,6 +7622,82 @@ static void run_on_d3d12(void (*test_func)(IUnknown *device, BOOL is_d3d12)) ok(!refcount, "Device has %lu references left.\n", refcount); }
+static void test_invalid_command_queue_types(void) +{ + /* Other queue types (except DIRECT) should be added here as soon + * as they are supported by vkd3d. */ + static const enum D3D12_COMMAND_LIST_TYPE queue_types[] = + { + D3D12_COMMAND_LIST_TYPE_COMPUTE, + D3D12_COMMAND_LIST_TYPE_COPY, + }; + + DXGI_SWAP_CHAIN_DESC swapchain_desc; + ID3D12CommandQueue *queue; + IDXGISwapChain *swapchain; + IDXGIFactory *factory; + ID3D12Device *device; + IUnknown *queue_unk; + RECT client_rect; + ULONG refcount; + unsigned int i; + HWND window; + HRESULT hr; + BOOL ret; + + if (!(device = create_d3d12_device())) + { + skip("Failed to create Direct3D 12 device.\n"); + return; + } + + window = create_window(); + ret = GetClientRect(window, &client_rect); + ok(ret, "Failed to get client rect.\n"); + + for (i = 0; i < ARRAY_SIZE(queue_types); ++i) + { + queue = create_d3d12_queue(device, queue_types[i]); + hr = ID3D12CommandQueue_QueryInterface(queue, &IID_IUnknown, (void **)&queue_unk); + ok(hr == S_OK, "Got unexpected hr %lx.\n", hr); + + get_factory(queue_unk, TRUE, &factory); + + swapchain_desc.BufferDesc.Width = 640; + swapchain_desc.BufferDesc.Height = 480; + swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; + swapchain_desc.BufferDesc.RefreshRate.Denominator = 1; + swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 2; + swapchain_desc.OutputWindow = window; + swapchain_desc.Windowed = TRUE; + swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapchain_desc.Flags = 0; + + hr = IDXGIFactory_CreateSwapChain(factory, queue_unk, &swapchain_desc, &swapchain); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); + + wait_queue_idle(device, queue); + + IDXGIFactory_Release(factory); + + IUnknown_Release(queue_unk); + refcount = ID3D12CommandQueue_Release(queue); + ok(!refcount, "Command queue has %lu references left.\n", refcount); + } + + DestroyWindow(window); + + refcount = ID3D12Device_Release(device); + ok(!refcount, "Device has %lu references left.\n", refcount); +} + START_TEST(dxgi) { HMODULE dxgi_module, d3d11_module, d3d12_module, gdi32_module; @@ -7721,6 +7797,8 @@ START_TEST(dxgi) ID3D12Debug_Release(debug); }
+ test_invalid_command_queue_types(); + run_on_d3d12(test_set_fullscreen); run_on_d3d12(test_resize_target); run_on_d3d12(test_swapchain_resize);
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dxgi/swapchain.c | 5 +++++ dlls/dxgi/tests/dxgi.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 9677142e0af..a665342812a 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -3071,6 +3071,7 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu IDXGISwapChain1 **swapchain) { DXGI_SWAP_CHAIN_FULLSCREEN_DESC default_fullscreen_desc; + struct D3D12_COMMAND_QUEUE_DESC queue_desc; struct d3d12_swapchain *object; ID3D12Device *device; HRESULT hr; @@ -3078,6 +3079,10 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu if (swapchain_desc->Format == DXGI_FORMAT_UNKNOWN) return DXGI_ERROR_INVALID_CALL;
+ queue_desc = ID3D12CommandQueue_GetDesc(queue); + if (queue_desc.Type != D3D12_COMMAND_LIST_TYPE_DIRECT) + return DXGI_ERROR_INVALID_CALL; + if (!fullscreen_desc) { memset(&default_fullscreen_desc, 0, sizeof(default_fullscreen_desc)); diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 0a5b0a584d2..6180577cc05 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -7680,7 +7680,6 @@ static void test_invalid_command_queue_types(void) swapchain_desc.Flags = 0;
hr = IDXGIFactory_CreateSwapChain(factory, queue_unk, &swapchain_desc, &swapchain); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr);
wait_queue_idle(device, queue);
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dxgi/swapchain.c | 184 +++++++++++------------------------------- 1 file changed, 45 insertions(+), 139 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index a665342812a..35551ab1c7e 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1184,11 +1184,6 @@ static BOOL d3d12_swapchain_is_present_mode_supported(struct d3d12_swapchain *sw return supported; }
-static BOOL d3d12_swapchain_has_user_images(struct d3d12_swapchain *swapchain) -{ - return !!swapchain->vk_images[0]; -} - static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapchain, VkFormat vk_format) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; @@ -1203,7 +1198,7 @@ static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapc VkResult vr; HRESULT hr;
- if (d3d12_swapchain_has_user_images(swapchain)) + if (swapchain->vk_images[0]) return S_OK;
memset(&image_info, 0, sizeof(image_info)); @@ -1455,7 +1450,6 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, VkDevice vk_device = swapchain->vk_device; ID3D12Device *device = swapchain->device; uint32_t image_count, queue_family_index; - D3D12_COMMAND_QUEUE_DESC queue_desc; unsigned int i; VkResult vr; HRESULT hr; @@ -1493,31 +1487,13 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, resource_info.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; resource_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION;
- queue_desc = ID3D12CommandQueue_GetDesc(queue); - if (queue_desc.Type != D3D12_COMMAND_LIST_TYPE_DIRECT) - { - /* vkCmdBlitImage() is only supported for graphics queues. */ - FIXME("Swapchain blit not implemented for command queue type %#x.\n", queue_desc.Type); - if (vk_swapchain_format != vk_format) - return E_NOTIMPL; - if (image_count != swapchain->desc.BufferCount) - { - FIXME("Got %u swapchain images, expected %u.\n", image_count, swapchain->desc.BufferCount); - return E_NOTIMPL; - } - } queue_family_index = vkd3d_get_vk_queue_family_index(queue);
- if (queue_desc.Type == D3D12_COMMAND_LIST_TYPE_DIRECT) - { - TRACE("Creating user swapchain buffers.\n"); - - if (FAILED(hr = d3d12_swapchain_create_user_buffers(swapchain, vk_format))) - return hr; + if (FAILED(hr = d3d12_swapchain_create_user_buffers(swapchain, vk_format))) + return hr;
- if (FAILED(hr = d3d12_swapchain_prepare_command_buffers(swapchain, queue_family_index))) - return hr; - } + if (FAILED(hr = d3d12_swapchain_prepare_command_buffers(swapchain, queue_family_index))) + return hr;
if (swapchain->buffers[0]) return S_OK; @@ -1575,23 +1551,6 @@ static VkResult d3d12_swapchain_acquire_next_vulkan_image(struct d3d12_swapchain return vr; }
-static VkResult d3d12_swapchain_acquire_next_back_buffer(struct d3d12_swapchain *swapchain) -{ - VkResult vr; - - /* If we don't have user images, we need to acquire a Vulkan image in order - * to get the correct value for the current back buffer index. */ - if (d3d12_swapchain_has_user_images(swapchain)) - return VK_SUCCESS; - - if ((vr = d3d12_swapchain_acquire_next_vulkan_image(swapchain)) >= 0) - swapchain->current_buffer_index = swapchain->vk_image_index; - else - ERR("Failed to acquire Vulkan image, vr %d.\n", vr); - - return vr; -} - static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain, BOOL destroy_user_buffers) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; @@ -1614,7 +1573,7 @@ static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain, B
for (i = 0; i < swapchain->desc.BufferCount; ++i) { - if (swapchain->buffers[i] && (destroy_user_buffers || !d3d12_swapchain_has_user_images(swapchain))) + if (swapchain->buffers[i] && (destroy_user_buffers || !swapchain->vk_images[0])) { vkd3d_resource_decref(swapchain->buffers[i]); swapchain->buffers[i] = NULL; @@ -1757,24 +1716,6 @@ static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *s return d3d12_swapchain_create_buffers(swapchain, vk_swapchain_format, vk_format); }
-static HRESULT d3d12_swapchain_recreate_vulkan_swapchain(struct d3d12_swapchain *swapchain) -{ - VkResult vr; - HRESULT hr; - - if (SUCCEEDED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain))) - { - vr = d3d12_swapchain_acquire_next_back_buffer(swapchain); - hr = hresult_from_vk_result(vr); - } - else - { - ERR("Failed to recreate Vulkan swapchain, hr %#lx.\n", hr); - } - - return hr; -} - static inline struct d3d12_swapchain *d3d12_swapchain_from_IDXGISwapChain4(IDXGISwapChain4 *iface) { return CONTAINING_RECORD(iface, struct d3d12_swapchain, IDXGISwapChain4_iface); @@ -1950,12 +1891,6 @@ static HRESULT d3d12_swapchain_set_sync_interval(struct d3d12_swapchain *swapcha if (swapchain->present_mode == present_mode) return S_OK;
- if (!d3d12_swapchain_has_user_images(swapchain)) - { - FIXME("Cannot recreate swapchain without user images.\n"); - return S_OK; - } - if (!d3d12_swapchain_is_present_mode_supported(swapchain, present_mode)) { FIXME("Vulkan present mode %#x is not supported.\n", present_mode); @@ -1964,14 +1899,17 @@ static HRESULT d3d12_swapchain_set_sync_interval(struct d3d12_swapchain *swapcha
d3d12_swapchain_destroy_buffers(swapchain, FALSE); swapchain->present_mode = present_mode; - return d3d12_swapchain_recreate_vulkan_swapchain(swapchain); + return d3d12_swapchain_create_vulkan_swapchain(swapchain); }
static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain, VkQueue vk_queue) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; VkPresentInfoKHR present_info; + VkCommandBuffer vk_cmd_buffer; VkSubmitInfo submit_info; + VkImage vk_dst_image; + VkImage vk_src_image; VkResult vr;
if (swapchain->vk_image_index == INVALID_VK_IMAGE_INDEX) @@ -1982,6 +1920,36 @@ static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain,
assert(swapchain->vk_image_index < swapchain->buffer_count);
+ vk_cmd_buffer = swapchain->vk_cmd_buffers[swapchain->vk_image_index]; + vk_dst_image = swapchain->vk_swapchain_images[swapchain->vk_image_index]; + vk_src_image = swapchain->vk_images[swapchain->current_buffer_index]; + + if ((vr = vk_funcs->p_vkResetCommandBuffer(vk_cmd_buffer, 0)) < 0) + { + ERR("Failed to reset command buffer, vr %d.\n", vr); + return vr; + } + + if ((vr = d3d12_swapchain_record_swapchain_blit(swapchain, + vk_cmd_buffer, vk_dst_image, vk_src_image)) < 0 ) + return vr; + + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = NULL; + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = NULL; + submit_info.pWaitDstStageMask = NULL; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &vk_cmd_buffer; + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = &swapchain->vk_semaphores[swapchain->vk_image_index]; + + if ((vr = vk_funcs->p_vkQueueSubmit(vk_queue, 1, &submit_info, VK_NULL_HANDLE)) < 0) + { + ERR("Failed to blit swapchain buffer, vr %d.\n", vr); + return vr; + } + present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.pNext = NULL; present_info.waitSemaphoreCount = 0; @@ -1990,43 +1958,8 @@ static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain, present_info.pSwapchains = &swapchain->vk_swapchain; present_info.pImageIndices = &swapchain->vk_image_index; present_info.pResults = NULL; - - if (d3d12_swapchain_has_user_images(swapchain)) - { - /* blit */ - VkCommandBuffer vk_cmd_buffer = swapchain->vk_cmd_buffers[swapchain->vk_image_index]; - VkImage vk_dst_image = swapchain->vk_swapchain_images[swapchain->vk_image_index]; - VkImage vk_src_image = swapchain->vk_images[swapchain->current_buffer_index]; - - if ((vr = vk_funcs->p_vkResetCommandBuffer(vk_cmd_buffer, 0)) < 0) - { - ERR("Failed to reset command buffer, vr %d.\n", vr); - return vr; - } - - if ((vr = d3d12_swapchain_record_swapchain_blit(swapchain, - vk_cmd_buffer, vk_dst_image, vk_src_image)) < 0 ) - return vr; - - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = NULL; - submit_info.waitSemaphoreCount = 0; - submit_info.pWaitSemaphores = NULL; - submit_info.pWaitDstStageMask = NULL; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &vk_cmd_buffer; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = &swapchain->vk_semaphores[swapchain->vk_image_index]; - - if ((vr = vk_funcs->p_vkQueueSubmit(vk_queue, 1, &submit_info, VK_NULL_HANDLE)) < 0) - { - ERR("Failed to blit swapchain buffer, vr %d.\n", vr); - return vr; - } - - present_info.waitSemaphoreCount = 1; - present_info.pWaitSemaphores = &swapchain->vk_semaphores[swapchain->vk_image_index]; - } + present_info.waitSemaphoreCount = 1; + present_info.pWaitSemaphores = &swapchain->vk_semaphores[swapchain->vk_image_index];
if ((vr = vk_funcs->p_vkQueuePresentKHR(vk_queue, &present_info)) >= 0) swapchain->vk_image_index = INVALID_VK_IMAGE_INDEX; @@ -2070,16 +2003,10 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain, { vkd3d_release_vk_queue(swapchain->command_queue);
- if (!d3d12_swapchain_has_user_images(swapchain)) - { - FIXME("Cannot recreate swapchain without user images.\n"); - return DXGI_STATUS_MODE_CHANGED; - } - TRACE("Recreating Vulkan swapchain.\n");
d3d12_swapchain_destroy_buffers(swapchain, FALSE); - if (FAILED(hr = d3d12_swapchain_recreate_vulkan_swapchain(swapchain))) + if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain))) return hr;
if (!(vk_queue = vkd3d_acquire_vk_queue(swapchain->command_queue))) @@ -2119,23 +2046,7 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain, }
swapchain->current_buffer_index = (swapchain->current_buffer_index + 1) % swapchain->desc.BufferCount; - vr = d3d12_swapchain_acquire_next_back_buffer(swapchain); - if (vr == VK_ERROR_OUT_OF_DATE_KHR) - { - if (!d3d12_swapchain_has_user_images(swapchain)) - { - FIXME("Cannot recreate swapchain without user images.\n"); - return DXGI_STATUS_MODE_CHANGED; - } - - TRACE("Recreating Vulkan swapchain.\n"); - - d3d12_swapchain_destroy_buffers(swapchain, FALSE); - return d3d12_swapchain_recreate_vulkan_swapchain(swapchain); - } - if (vr < 0) - ERR("Failed to acquire next Vulkan image, vr %d.\n", vr); - return hresult_from_vk_result(vr); + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_Present(IDXGISwapChain4 *iface, UINT sync_interval, UINT flags) @@ -2352,7 +2263,7 @@ static HRESULT d3d12_swapchain_resize_buffers(struct d3d12_swapchain *swapchain,
d3d12_swapchain_destroy_buffers(swapchain, TRUE); swapchain->desc = new_desc; - return d3d12_swapchain_recreate_vulkan_swapchain(swapchain); + return d3d12_swapchain_create_vulkan_swapchain(swapchain); }
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain4 *iface, @@ -3033,11 +2944,6 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI swapchain->vk_fence = vk_fence;
swapchain->current_buffer_index = 0; - if ((vr = d3d12_swapchain_acquire_next_back_buffer(swapchain)) < 0) - { - d3d12_swapchain_destroy(swapchain); - return hresult_from_vk_result(vr); - }
if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) {
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 49 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 6180577cc05..8b8749c721a 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -4941,7 +4941,6 @@ static void test_swapchain_backbuffer_index(IUnknown *device, BOOL is_d3d12) swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchain_desc.BufferCount = 4; swapchain_desc.OutputWindow = create_window(); swapchain_desc.Windowed = TRUE; swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; @@ -4954,6 +4953,7 @@ static void test_swapchain_backbuffer_index(IUnknown *device, BOOL is_d3d12)
for (i = 0; i < ARRAY_SIZE(swap_effects); ++i) { + swapchain_desc.BufferCount = 4; swapchain_desc.SwapEffect = swap_effects[i]; expected_hr = is_d3d12 && !is_flip_model(swap_effects[i]) ? DXGI_ERROR_INVALID_CALL : S_OK; hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); @@ -4969,10 +4969,55 @@ static void test_swapchain_backbuffer_index(IUnknown *device, BOOL is_d3d12) goto done; }
- for (j = 0; j < 2 * swapchain_desc.BufferCount; ++j) + for (j = 0; j < 2 * swapchain_desc.BufferCount + 2; ++j) + { + index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); + expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; + ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); + hr = IDXGISwapChain3_Present(swapchain3, 0, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + } + + swapchain_desc.BufferCount = 3; + hr = IDXGISwapChain_ResizeBuffers(swapchain, swapchain_desc.BufferCount, + rect.right, rect.bottom, DXGI_FORMAT_UNKNOWN, swapchain_desc.Flags); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* The back buffer index restarts from 0. */ + for (j = 0; j < swapchain_desc.BufferCount + 2; ++j) + { + index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); + expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; + todo_wine_if(is_d3d12) + ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); + hr = IDXGISwapChain3_Present(swapchain3, 0, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + } + + hr = IDXGISwapChain_ResizeBuffers(swapchain, swapchain_desc.BufferCount, + rect.right, rect.bottom, DXGI_FORMAT_UNKNOWN, swapchain_desc.Flags); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Even when not really changing the buffer count. */ + for (j = 0; j < swapchain_desc.BufferCount + 1; ++j) + { + index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); + expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; + todo_wine_if(is_d3d12) + ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); + hr = IDXGISwapChain3_Present(swapchain3, 0, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + } + + hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, + rect.right, rect.bottom, DXGI_FORMAT_UNKNOWN, swapchain_desc.Flags); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (j = 0; j < swapchain_desc.BufferCount + 2; ++j) { index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; + todo_wine_if(is_d3d12) ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); hr = IDXGISwapChain3_Present(swapchain3, 0, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dxgi/swapchain.c | 2 ++ dlls/dxgi/tests/dxgi.c | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 35551ab1c7e..d4cef5cc586 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2257,6 +2257,8 @@ static HRESULT d3d12_swapchain_resize_buffers(struct d3d12_swapchain *swapchain, if (!dxgi_validate_swapchain_desc(&new_desc)) return DXGI_ERROR_INVALID_CALL;
+ swapchain->current_buffer_index = 0; + if (desc->Width == new_desc.Width && desc->Height == new_desc.Height && desc->Format == new_desc.Format && desc->BufferCount == new_desc.BufferCount) return S_OK; diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 8b8749c721a..84c978159ec 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -4988,7 +4988,6 @@ static void test_swapchain_backbuffer_index(IUnknown *device, BOOL is_d3d12) { index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; - todo_wine_if(is_d3d12) ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); hr = IDXGISwapChain3_Present(swapchain3, 0, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -5003,7 +5002,6 @@ static void test_swapchain_backbuffer_index(IUnknown *device, BOOL is_d3d12) { index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; - todo_wine_if(is_d3d12) ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); hr = IDXGISwapChain3_Present(swapchain3, 0, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -5017,7 +5015,6 @@ static void test_swapchain_backbuffer_index(IUnknown *device, BOOL is_d3d12) { index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; - todo_wine_if(is_d3d12) ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); hr = IDXGISwapChain3_Present(swapchain3, 0, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=130062
Your paranoid android.
=== w864 (32 bit report) ===
dxgi: dxgi.c:3335: Test failed: Got monitor rect (0,0)-(2560,1600), expected (0,0)-(1024,768). dxgi.c:3337: Test failed: Got monitor rect (0,0)-(2560,1600), expected (0,0)-(1024,768). dxgi.c:3350: Test failed: Got monitor rect (0,0)-(2560,1600), expected (0,0)-(1024,768). dxgi.c:4742: Test failed: Test 0: Got unexpected hr 0x887a0002. dxgi.c:4751: Test failed: Test 0: Got unexpected fullscreen status. dxgi.c:4752: Test failed: Test 0: Got unexpected output. dxgi.c:4760: Test failed: Test 0: Got unexpected fullscreen status. dxgi.c:4785: Test failed: Test 0: Got unexpected hr 0x887a0002. dxgi.c:4789: Test failed: Test 0: Got unexpected fullscreen status. dxgi.c:4805: Test failed: Test 0: Got unexpected fullscreen status. dxgi.c:4854: Test failed: Test 0: Got unexpected hr 0x887a0002. dxgi.c:4742: Test failed: Test 1: Got unexpected hr 0x887a0002. dxgi.c:4751: Test failed: Test 1: Got unexpected fullscreen status. dxgi.c:4752: Test failed: Test 1: Got unexpected output. dxgi.c:4760: Test failed: Test 1: Got unexpected fullscreen status. dxgi.c:4772: Test failed: Test 1: Got unexpected fullscreen status. dxgi.c:4785: Test failed: Test 1: Got unexpected hr 0x887a0002. dxgi.c:4789: Test failed: Test 1: Got unexpected fullscreen status. dxgi.c:4805: Test failed: Test 1: Got unexpected fullscreen status. dxgi.c:4854: Test failed: Test 1: Got unexpected hr 0x887a0002.
From patch 1/5:
+static void test_invalid_command_queue_types(void) +{ + /* Other queue types (except DIRECT) should be added here as soon + * as they are supported by vkd3d. */ + static const enum D3D12_COMMAND_LIST_TYPE queue_types[] = + { + D3D12_COMMAND_LIST_TYPE_COMPUTE, + D3D12_COMMAND_LIST_TYPE_COPY, + };
Why is that? We'll fail to create unimplemented command list types, but we have todo_wine for that.
It might not be a bad idea to test command list types that are supposed to succeed as well, to avoid the CreateSwapChain() call failing due to e.g. an unsupported swapchain_desc parameter.
@@ -7721,6 +7797,8 @@ START_TEST(dxgi) ID3D12Debug_Release(debug); } + test_invalid_command_queue_types(); + run_on_d3d12(test_set_fullscreen); run_on_d3d12(test_resize_target); run_on_d3d12(test_swapchain_resize);
Should this perhaps be a d3d12 test instead?
Why is that? We'll fail to create unimplemented command list types, but we have todo_wine for that.
Mmh, even on Windows trying to create a command queue on any type other than `DIRECT`, `COMPUTE` or `COPY` fails with `E_INVALIDARG`.
Looking at the docs, I think that `D3D12_COMMAND_LIST_TYPE_BUNDLE` is not supposed to be passed to `CreateCommandQueue()` but to `CreateCommandList()`, so makes no sense here. The other possible values are for video decoding/encoding, which is (AFAIK) completely unsupported on Wine anyway, so it would make little sense to check that queue creation works. I suppose it fails on the testbot because it misses some configuration/support.
All in all, I think that these two are the things it makes sense to test anyway, so it is the comment that has to be deleted.
It might not be a bad idea to test command list types that are supposed to succeed as well, to avoid the CreateSwapChain() call failing due to e.g. an unsupported swapchain_desc parameter.
Creating a swap chain on a direct command queue is already well tested in many other places. Here I think it would complicate the control flow without adding much useful signal.
Should this perhaps be a d3d12 test instead?
You mean it should use the `run_on_d3d12()` helper? I figured that was just for tests that could make sense for both D3D10 and D3D12. This doesn't make sense on D3D10, because the swapchain is not created from a command queue, so I thought it would be pointless to use that helper. But if you prefer to use it, it's not difficult to adapt it.