-- v5: 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. d3d12/tests: Test that D3D12 swapchains can only be created on direct command queues.
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/d3d12/tests/d3d12.c | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+)
diff --git a/dlls/d3d12/tests/d3d12.c b/dlls/d3d12/tests/d3d12.c index 5d3f8a36a2d..84e99a930d4 100644 --- a/dlls/d3d12/tests/d3d12.c +++ b/dlls/d3d12/tests/d3d12.c @@ -1415,6 +1415,89 @@ static void test_desktop_window(void) destroy_test_context(&context); }
+static void test_invalid_command_queue_types(void) +{ + static const enum D3D12_COMMAND_LIST_TYPE queue_types[] = + { + D3D12_COMMAND_LIST_TYPE_DIRECT, + D3D12_COMMAND_LIST_TYPE_COMPUTE, + D3D12_COMMAND_LIST_TYPE_COPY, + }; + + DXGI_SWAP_CHAIN_DESC swapchain_desc; + ID3D12CommandQueue *queue; + IDXGISwapChain *swapchain; + IDXGIFactory *factory; + ID3D12Device *device; + HRESULT hr, expected; + IUnknown *queue_unk; + RECT client_rect; + ULONG refcount; + unsigned int i; + HWND window; + BOOL ret; + + if (!(device = create_device())) + { + skip("Failed to create Direct3D 12 device.\n"); + return; + } + + window = create_window(WS_VISIBLE); + ret = GetClientRect(window, &client_rect); + ok(ret, "Failed to get client rect.\n"); + + for (i = 0; i < ARRAY_SIZE(queue_types); ++i) + { + queue = create_command_queue(device, queue_types[i]); + hr = ID3D12CommandQueue_QueryInterface(queue, &IID_IUnknown, (void **)&queue_unk); + ok(hr == S_OK, "Got unexpected hr %lx.\n", hr); + + hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory); + ok(hr == S_OK, "Got unexpected hr %lx.\n", hr); + + 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); + expected = queue_types[i] == D3D12_COMMAND_LIST_TYPE_DIRECT ? S_OK : DXGI_ERROR_INVALID_CALL; + todo_wine_if(queue_types[i] != D3D12_COMMAND_LIST_TYPE_DIRECT) + ok(hr == expected, "Got unexpected hr %#lx.\n", hr); + + if (hr == S_OK) + { + refcount = IDXGISwapChain_Release(swapchain); + ok(!refcount, "Swapchain has %lu references left.\n", refcount); + } + + 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(d3d12) { BOOL enable_debug_layer = FALSE; @@ -1450,4 +1533,5 @@ START_TEST(d3d12) test_swapchain_size_mismatch(); test_swapchain_backbuffer_index(); test_desktop_window(); + test_invalid_command_queue_types(); }
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/d3d12/tests/d3d12.c | 1 - dlls/dxgi/swapchain.c | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d12/tests/d3d12.c b/dlls/d3d12/tests/d3d12.c index 84e99a930d4..fd134830f55 100644 --- a/dlls/d3d12/tests/d3d12.c +++ b/dlls/d3d12/tests/d3d12.c @@ -1474,7 +1474,6 @@ static void test_invalid_command_queue_types(void)
hr = IDXGIFactory_CreateSwapChain(factory, queue_unk, &swapchain_desc, &swapchain); expected = queue_types[i] == D3D12_COMMAND_LIST_TYPE_DIRECT ? S_OK : DXGI_ERROR_INVALID_CALL; - todo_wine_if(queue_types[i] != D3D12_COMMAND_LIST_TYPE_DIRECT) ok(hr == expected, "Got unexpected hr %#lx.\n", hr);
if (hr == S_OK) 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));
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dxgi/swapchain.c | 210 +++++++++++------------------------------- 1 file changed, 54 insertions(+), 156 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index a665342812a..a80e9ac0cf5 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; @@ -1478,6 +1472,17 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, return hresult_from_vk_result(vr); }
+ queue_family_index = vkd3d_get_vk_queue_family_index(queue); + + 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 (swapchain->buffers[0]) + return S_OK; + resource_info.type = VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO; resource_info.next = NULL; resource_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; @@ -1492,48 +1497,11 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain, resource_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; 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_prepare_command_buffers(swapchain, queue_family_index))) - return hr; - } - - if (swapchain->buffers[0]) - return S_OK; + resource_info.present_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
for (i = 0; i < swapchain->desc.BufferCount; ++i) { - if (swapchain->vk_images[i]) - { - resource_info.vk_image = swapchain->vk_images[i]; - resource_info.present_state = D3D12_RESOURCE_STATE_COPY_SOURCE; - } - else - { - resource_info.vk_image = swapchain->vk_swapchain_images[i]; - resource_info.present_state = D3D12_RESOURCE_STATE_PRESENT; - } + resource_info.vk_image = swapchain->vk_images[i];
if (FAILED(hr = vkd3d_create_image_resource(device, &resource_info, &swapchain->buffers[i]))) { @@ -1575,23 +1543,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 +1565,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 +1708,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 +1883,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 +1891,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 +1912,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 +1950,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 +1995,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 +2038,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 +2255,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 +2936,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 e0465b90ed0..14dc09269f9 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 a80e9ac0cf5..e00867f8069 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2249,6 +2249,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 14dc09269f9..4703bd8ee27 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);
This merge request was approved by Jan Sikorski.
This merge request was approved by Zebediah Figura.