Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d12/tests/d3d12.c | 271 +++++++++++++++++++++++---------------- 1 file changed, 161 insertions(+), 110 deletions(-)
diff --git a/dlls/d3d12/tests/d3d12.c b/dlls/d3d12/tests/d3d12.c index dec7cf855839..5cb9a2991639 100644 --- a/dlls/d3d12/tests/d3d12.c +++ b/dlls/d3d12/tests/d3d12.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <assert.h> #include <stdlib.h> #define COBJMACROS #include "initguid.h" @@ -274,37 +275,25 @@ static ID3D12PipelineState *create_pipeline_state_(unsigned int line, ID3D12Devi return pipeline_state; }
-#define reset_command_list(a, b) reset_command_list_(__LINE__, a, b) -static void reset_command_list_(unsigned int line, - ID3D12GraphicsCommandList *list, ID3D12CommandAllocator *allocator) -{ - HRESULT hr; - - hr = ID3D12CommandAllocator_Reset(allocator); - ok_(__FILE__, line)(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); - hr = ID3D12GraphicsCommandList_Reset(list, allocator, NULL); - ok_(__FILE__, line)(hr == S_OK, "Failed to reset command list, hr %#x.\n", hr); -} - struct test_context_desc { BOOL no_pipeline; const D3D12_SHADER_BYTECODE *ps; };
+#define MAX_FRAME_COUNT 4 + struct test_context { ID3D12Device *device;
ID3D12CommandQueue *queue; - ID3D12CommandAllocator *allocator; - ID3D12GraphicsCommandList *list; - - D3D12_RESOURCE_DESC render_target_desc; - ID3D12Resource *render_target; + ID3D12CommandAllocator *allocator[MAX_FRAME_COUNT]; + ID3D12GraphicsCommandList *list[MAX_FRAME_COUNT];
ID3D12DescriptorHeap *rtv_heap; - D3D12_CPU_DESCRIPTOR_HANDLE rtv; + D3D12_CPU_DESCRIPTOR_HANDLE rtv[MAX_FRAME_COUNT]; + ID3D12Resource *render_target[MAX_FRAME_COUNT];
ID3D12RootSignature *root_signature; ID3D12PipelineState *pipeline_state; @@ -313,15 +302,43 @@ struct test_context RECT scissor_rect; };
-#define create_render_target(context, a, b) create_render_target_(__LINE__, context, a, b) -static void create_render_target_(unsigned int line, struct test_context *context, - ID3D12Resource **render_target, const D3D12_CPU_DESCRIPTOR_HANDLE *rtv) +#define reset_command_list(a, b) reset_command_list_(__LINE__, a, b) +static void reset_command_list_(unsigned int line, struct test_context *context, unsigned int index) +{ + HRESULT hr; + + assert(index < MAX_FRAME_COUNT); + + hr = ID3D12CommandAllocator_Reset(context->allocator[index]); + ok_(__FILE__, line)(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr); + hr = ID3D12GraphicsCommandList_Reset(context->list[index], context->allocator[index], NULL); + ok_(__FILE__, line)(hr == S_OK, "Failed to reset command list, hr %#x.\n", hr); +} + +static void destroy_render_targets(struct test_context *context) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(context->render_target); ++i) + { + if (context->render_target[i]) + { + ID3D12Resource_Release(context->render_target[i]); + context->render_target[i] = NULL; + } + } +} + +#define create_render_target(context) create_render_target_(__LINE__, context) +static void create_render_target_(unsigned int line, struct test_context *context) { D3D12_HEAP_PROPERTIES heap_properties; D3D12_RESOURCE_DESC resource_desc; D3D12_CLEAR_VALUE clear_value; HRESULT hr;
+ destroy_render_targets(context); + memset(&heap_properties, 0, sizeof(heap_properties)); heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
@@ -344,13 +361,13 @@ static void create_render_target_(unsigned int line, struct test_context *contex hr = ID3D12Device_CreateCommittedResource(context->device, &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value, - &IID_ID3D12Resource, (void **)render_target); + &IID_ID3D12Resource, (void **)&context->render_target[0]); ok_(__FILE__, line)(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
- context->render_target_desc = resource_desc; + set_viewport(&context->viewport, 0.0f, 0.0f, resource_desc.Width, resource_desc.Height, 0.0f, 1.0f); + SetRect(&context->scissor_rect, 0, 0, resource_desc.Width, resource_desc.Height);
- if (rtv) - ID3D12Device_CreateRenderTargetView(context->device, *render_target, NULL, *rtv); + ID3D12Device_CreateRenderTargetView(context->device, context->render_target[0], NULL, context->rtv[0]); }
#define init_test_context(a, b) init_test_context_(__LINE__, a, b) @@ -359,7 +376,9 @@ static BOOL init_test_context_(unsigned int line, struct test_context *context, { D3D12_COMMAND_QUEUE_DESC command_queue_desc; D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc; + unsigned int rtv_size; ID3D12Device *device; + unsigned int i; HRESULT hr;
memset(context, 0, sizeof(*context)); @@ -379,15 +398,21 @@ static BOOL init_test_context_(unsigned int line, struct test_context *context, &IID_ID3D12CommandQueue, (void **)&context->queue); ok_(__FILE__, line)(hr == S_OK, "Failed to create command queue, hr %#x.\n", hr);
- hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, - &IID_ID3D12CommandAllocator, (void **)&context->allocator); - ok_(__FILE__, line)(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(context->allocator); ++i) + { + hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, + &IID_ID3D12CommandAllocator, (void **)&context->allocator[i]); + ok_(__FILE__, line)(hr == S_OK, "Failed to create command allocator %u, hr %#x.\n", i, hr); + }
- hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, - context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list); - ok_(__FILE__, line)(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(context->list); ++i) + { + hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, + context->allocator[i], NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list[i]); + ok_(__FILE__, line)(hr == S_OK, "Failed to create command list %u, hr %#x.\n", i, hr); + }
- rtv_heap_desc.NumDescriptors = 16; + rtv_heap_desc.NumDescriptors = MAX_FRAME_COUNT; rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; rtv_heap_desc.NodeMask = 0; @@ -395,14 +420,12 @@ static BOOL init_test_context_(unsigned int line, struct test_context *context, &IID_ID3D12DescriptorHeap, (void **)&context->rtv_heap); ok_(__FILE__, line)(hr == S_OK, "Failed to create descriptor heap, hr %#x.\n", hr);
- context->rtv = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(context->rtv_heap); - - create_render_target_(line, context, &context->render_target, &context->rtv); - - set_viewport(&context->viewport, 0.0f, 0.0f, - context->render_target_desc.Width, context->render_target_desc.Height, 0.0f, 1.0f); - SetRect(&context->scissor_rect, 0, 0, - context->render_target_desc.Width, context->render_target_desc.Height); + rtv_size = ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + for (i = 0; i < ARRAY_SIZE(context->rtv); ++i) + { + context->rtv[i] = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(context->rtv_heap); + context->rtv[i].ptr += i * rtv_size; + }
context->root_signature = create_default_root_signature(device);
@@ -410,8 +433,7 @@ static BOOL init_test_context_(unsigned int line, struct test_context *context, return TRUE;
context->pipeline_state = create_pipeline_state_(line, device, - context->root_signature, context->render_target_desc.Format, - desc ? desc->ps : NULL); + context->root_signature, DXGI_FORMAT_B8G8R8A8_UNORM, desc ? desc->ps : NULL);
return TRUE; } @@ -419,6 +441,7 @@ static BOOL init_test_context_(unsigned int line, struct test_context *context, #define destroy_test_context(context) destroy_test_context_(__LINE__, context) static void destroy_test_context_(unsigned int line, struct test_context *context) { + unsigned int i; ULONG refcount;
if (context->pipeline_state) @@ -428,12 +451,13 @@ static void destroy_test_context_(unsigned int line, struct test_context *contex
if (context->rtv_heap) ID3D12DescriptorHeap_Release(context->rtv_heap); - if (context->render_target) - ID3D12Resource_Release(context->render_target); + destroy_render_targets(context);
- ID3D12CommandAllocator_Release(context->allocator); + for (i = 0; i < ARRAY_SIZE(context->allocator); ++i) + ID3D12CommandAllocator_Release(context->allocator[i]); ID3D12CommandQueue_Release(context->queue); - ID3D12GraphicsCommandList_Release(context->list); + for (i = 0; i < ARRAY_SIZE(context->list); ++i) + ID3D12GraphicsCommandList_Release(context->list[i]);
refcount = ID3D12Device_Release(context->device); ok_(__FILE__, line)(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); @@ -546,15 +570,22 @@ static HWND create_window(DWORD style) return CreateWindowA("static", "d3d12_test", style, 0, 0, 256, 256, NULL, NULL, NULL, NULL); }
-static IDXGISwapChain3 *create_swapchain(ID3D12CommandQueue *queue, HWND window, - DXGI_FORMAT format, unsigned int width, unsigned int height) +static IDXGISwapChain3 *create_swapchain(struct test_context *context, HWND window, + unsigned int buffer_count, DXGI_FORMAT format, unsigned int width, unsigned int height) { + ID3D12CommandQueue *queue = context->queue; + ID3D12Device *device = context->device; IDXGISwapChain1 *swapchain1; DXGI_SWAP_CHAIN_DESC1 desc; IDXGISwapChain3 *swapchain; IDXGIFactory4 *factory; + unsigned int i; HRESULT hr;
+ assert(buffer_count <= MAX_FRAME_COUNT); + + destroy_render_targets(context); + hr = CreateDXGIFactory2(0, &IID_IDXGIFactory4, (void **)&factory); ok(hr == S_OK, "Failed to create factory, hr %#x.\n", hr);
@@ -565,7 +596,7 @@ static IDXGISwapChain3 *create_swapchain(ID3D12CommandQueue *queue, HWND window, desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.BufferCount = 2; + desc.BufferCount = buffer_count; desc.Scaling = DXGI_SCALING_STRETCH; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; @@ -578,6 +609,17 @@ static IDXGISwapChain3 *create_swapchain(ID3D12CommandQueue *queue, HWND window, hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain); ok(hr == S_OK, "Failed to query IDXGISwapChain3, hr %#x.\n", hr); IDXGISwapChain1_Release(swapchain1); + + for (i = 0; i < buffer_count; ++i) + { + hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&context->render_target[i]); + ok(hr == S_OK, "Failed to get swapchain buffer %u, hr %#x.\n", i, hr); + ID3D12Device_CreateRenderTargetView(device, context->render_target[i], NULL, context->rtv[i]); + } + + set_viewport(&context->viewport, 0.0f, 0.0f, width, height, 0.0f, 1.0f); + SetRect(&context->scissor_rect, 0, 0, width, height); + return swapchain; }
@@ -768,12 +810,14 @@ static void test_draw(void)
if (!init_test_context(&context, NULL)) return; - command_list = context.list; + command_list = context.list[0]; queue = context.queue;
- ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); + create_render_target(&context); + + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv[0], white, 0, NULL);
- ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv[0], FALSE, NULL); ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -781,10 +825,10 @@ static void test_draw(void) ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
- transition_sub_resource_state(command_list, context.render_target, 0, + transition_sub_resource_state(command_list, context.render_target[0], 0, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0); + check_sub_resource_uint(context.render_target[0], 0, queue, command_list, 0xff00ff00, 0);
destroy_test_context(&context); } @@ -793,6 +837,7 @@ static void test_swapchain_draw(void) { static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; ID3D12GraphicsCommandList *command_list; + D3D12_CPU_DESCRIPTOR_HANDLE rtv; struct test_context_desc desc; struct test_context context; ID3D12Resource *backbuffer; @@ -845,7 +890,7 @@ static void test_swapchain_draw(void) if (!init_test_context(&context, &desc)) return; device = context.device; - command_list = context.list; + command_list = context.list[0]; queue = context.queue;
window = create_window(WS_VISIBLE); @@ -858,18 +903,17 @@ static void test_swapchain_draw(void) context.pipeline_state = create_pipeline_state(device, context.root_signature, tests[i].format, &ps);
- swapchain = create_swapchain(queue, window, tests[i].format, rect.right, rect.bottom); + swapchain = create_swapchain(&context, window, 2, tests[i].format, rect.right, rect.bottom); index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain); - hr = IDXGISwapChain3_GetBuffer(swapchain, index, &IID_ID3D12Resource, (void **)&backbuffer); - ok(hr == S_OK, "Failed to get swapchain buffer %u, hr %#x.\n", index, hr); - ID3D12Device_CreateRenderTargetView(device, backbuffer, NULL, context.rtv); + backbuffer = context.render_target[index]; + rtv = context.rtv[index];
transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
- ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, white, 0, NULL);
- ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, FALSE, NULL); ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -882,7 +926,7 @@ static void test_swapchain_draw(void) D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); check_sub_resource_uint(backbuffer, 0, queue, command_list, tests[i].color, 0);
- reset_command_list(command_list, context.allocator); + reset_command_list(&context, 0); transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_PRESENT); hr = ID3D12GraphicsCommandList_Close(command_list); @@ -894,14 +938,13 @@ static void test_swapchain_draw(void)
wait_queue_idle(device, queue);
- refcount = ID3D12Resource_Release(backbuffer); - ok(!refcount, "Backbuffer has %u references left.\n", refcount); + destroy_render_targets(&context); refcount = IDXGISwapChain3_Release(swapchain); ok(!refcount, "Swapchain has %u references left.\n", refcount); ID3D12PipelineState_Release(context.pipeline_state); context.pipeline_state = NULL;
- reset_command_list(command_list, context.allocator); + reset_command_list(&context, 0); }
DestroyWindow(window); @@ -912,7 +955,7 @@ static void test_swapchain_size_mismatch(void) { static const float green[] = {0.0f, 1.0f, 0.0f, 1.0f}; ID3D12GraphicsCommandList *command_list; - ID3D12Resource *backbuffers[2]; + D3D12_CPU_DESCRIPTOR_HANDLE rtv; struct test_context_desc desc; struct test_context context; ID3D12Resource *backbuffer; @@ -930,24 +973,23 @@ static void test_swapchain_size_mismatch(void) if (!init_test_context(&context, &desc)) return; device = context.device; - command_list = context.list; + command_list = context.list[0]; queue = context.queue;
window = CreateWindowA("static", "d3d12_test", WS_VISIBLE, 0, 0, 200, 200, NULL, NULL, NULL, NULL); - swapchain = create_swapchain(queue, window, DXGI_FORMAT_B8G8R8A8_UNORM, 400, 400); + swapchain = create_swapchain(&context, window, 2, DXGI_FORMAT_B8G8R8A8_UNORM, 400, 400); index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain); - hr = IDXGISwapChain3_GetBuffer(swapchain, index, &IID_ID3D12Resource, (void **)&backbuffer); - ok(hr == S_OK, "Failed to get swapchain buffer %u, hr %#x.\n", index, hr); - ID3D12Device_CreateRenderTargetView(device, backbuffer, NULL, context.rtv); + backbuffer = context.render_target[index]; + rtv = context.rtv[index];
transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); - ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, green, 0, NULL); + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, green, 0, NULL); transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); check_sub_resource_uint(backbuffer, 0, queue, command_list, 0xff00ff00, 0);
- reset_command_list(command_list, context.allocator); + reset_command_list(&context, 0); transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_PRESENT); hr = ID3D12GraphicsCommandList_Close(command_list); @@ -958,10 +1000,9 @@ static void test_swapchain_size_mismatch(void) ok(hr == S_OK, "Failed to present, hr %#x.\n", hr);
wait_queue_idle(device, queue); - reset_command_list(command_list, context.allocator); + reset_command_list(&context, 0);
- refcount = ID3D12Resource_Release(backbuffer); - ok(!refcount, "Backbuffer has %u references left.\n", refcount); + destroy_render_targets(&context); refcount = IDXGISwapChain3_Release(swapchain); ok(!refcount, "Swapchain has %u references left.\n", refcount); DestroyWindow(window); @@ -969,23 +1010,18 @@ static void test_swapchain_size_mismatch(void) window = create_window(WS_VISIBLE); ret = GetClientRect(window, &rect); ok(ret, "Failed to get client rect.\n"); - swapchain = create_swapchain(queue, window, DXGI_FORMAT_B8G8R8A8_UNORM, rect.right, rect.bottom); - - for (i = 0; i < ARRAY_SIZE(backbuffers); ++i) - { - hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&backbuffers[i]); - ok(hr == S_OK, "Failed to get swapchain buffer %u, hr %#x.\n", i, hr); - } + swapchain = create_swapchain(&context, window, 2, DXGI_FORMAT_B8G8R8A8_UNORM, rect.right, rect.bottom);
for (i = 0; i < 20; ++i) { index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain); - ID3D12Device_CreateRenderTargetView(device, backbuffers[index], NULL, context.rtv); + backbuffer = context.render_target[index]; + rtv = context.rtv[index];
- transition_sub_resource_state(command_list, backbuffers[index], 0, + transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); - ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, green, 0, NULL); - transition_sub_resource_state(command_list, backbuffers[index], 0, + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, green, 0, NULL); + transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); hr = ID3D12GraphicsCommandList_Close(command_list); ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr); @@ -995,14 +1031,13 @@ static void test_swapchain_size_mismatch(void) ok(hr == S_OK, "Failed to present, hr %#x.\n", hr);
wait_queue_idle(device, queue); - reset_command_list(command_list, context.allocator); + reset_command_list(&context, 0);
if (i == 6) MoveWindow(window, 0, 0, 100, 100, TRUE); }
- for (i = 0; i < ARRAY_SIZE(backbuffers); ++i) - ID3D12Resource_Release(backbuffers[i]); + destroy_render_targets(&context); refcount = IDXGISwapChain3_Release(swapchain); ok(!refcount, "Swapchain has %u references left.\n", refcount); DestroyWindow(window); @@ -1012,15 +1047,20 @@ static void test_swapchain_size_mismatch(void) static void test_swapchain_backbuffer_index(void) { static const float green[] = {0.0f, 1.0f, 0.0f, 1.0f}; - unsigned int previous_index, expected_index, index, i; + UINT64 frame_fence_value[MAX_FRAME_COUNT] = {0}; ID3D12GraphicsCommandList *command_list; - ID3D12Resource *backbuffers[2]; + unsigned int expected_index, index, i; + const unsigned int buffer_count = 2; + D3D12_CPU_DESCRIPTOR_HANDLE rtv; struct test_context_desc desc; struct test_context context; + ID3D12Resource *backbuffer; unsigned int sync_interval; IDXGISwapChain3 *swapchain; ID3D12CommandQueue *queue; ID3D12Device *device; + ID3D12Fence *fence; + UINT64 fence_value; ULONG refcount; HWND window; HRESULT hr; @@ -1031,33 +1071,42 @@ static void test_swapchain_backbuffer_index(void) if (!init_test_context(&context, &desc)) return; device = context.device; - command_list = context.list; queue = context.queue;
window = create_window(WS_VISIBLE); ret = GetClientRect(window, &rect); ok(ret, "Failed to get client rect.\n"); - swapchain = create_swapchain(queue, window, DXGI_FORMAT_B8G8R8A8_UNORM, rect.right, rect.bottom); + swapchain = create_swapchain(&context, window, buffer_count, DXGI_FORMAT_B8G8R8A8_UNORM, rect.right, rect.bottom);
- for (i = 0; i < ARRAY_SIZE(backbuffers); ++i) + hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence); + ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(context.list); ++i) { - hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&backbuffers[i]); - ok(hr == S_OK, "Failed to get swapchain buffer %u, hr %#x.\n", i, hr); + hr = ID3D12GraphicsCommandList_Close(context.list[i]); + ok(hr == S_OK, "Failed to close command list %u, hr %#x.\n", i, hr); }
- previous_index = 1; + index = 1; + fence_value = 1; for (i = 0; i < 20; ++i) { + expected_index = (index + 1) % buffer_count; index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain); - ID3D12Device_CreateRenderTargetView(device, backbuffers[index], NULL, context.rtv); - - expected_index = (previous_index + 1) % 2; ok(index == expected_index, "Test %u: Got index %u, expected %u.\n", i, index, expected_index);
- transition_sub_resource_state(command_list, backbuffers[index], 0, + hr = wait_for_fence(fence, frame_fence_value[index]); + ok(hr == S_OK, "Failed to wait for fence, hr %#x.\n", hr); + + reset_command_list(&context, index); + backbuffer = context.render_target[index]; + command_list = context.list[index]; + rtv = context.rtv[index]; + + transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); - ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, green, 0, NULL); - transition_sub_resource_state(command_list, backbuffers[index], 0, + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, green, 0, NULL); + transition_sub_resource_state(command_list, backbuffer, 0, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); hr = ID3D12GraphicsCommandList_Close(command_list); ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr); @@ -1071,14 +1120,16 @@ static void test_swapchain_backbuffer_index(void) hr = IDXGISwapChain3_Present(swapchain, sync_interval, 0); ok(hr == S_OK, "Failed to present, hr %#x.\n", hr);
- wait_queue_idle(device, queue); - reset_command_list(command_list, context.allocator); - - previous_index = index; + frame_fence_value[index] = fence_value; + hr = ID3D12CommandQueue_Signal(queue, fence, fence_value); + ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr); + ++fence_value; }
- for (i = 0; i < ARRAY_SIZE(backbuffers); ++i) - ID3D12Resource_Release(backbuffers[i]); + wait_queue_idle(device, queue); + + ID3D12Fence_Release(fence); + destroy_render_targets(&context); refcount = IDXGISwapChain3_Release(swapchain); ok(!refcount, "Swapchain has %u references left.\n", refcount); DestroyWindow(window);
Hi,
While running your changed tests on Windows, 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=48529
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/dxgi/swapchain.c:1067 error: patch failed: dlls/dxgi/swapchain.c:1422 error: patch failed: dlls/dxgi/swapchain.c:1421 error: patch failed: dlls/d3d12/tests/d3d12.c:912 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/dxgi/swapchain.c:1067 error: patch failed: dlls/dxgi/swapchain.c:1422 error: patch failed: dlls/dxgi/swapchain.c:1421 error: patch failed: dlls/d3d12/tests/d3d12.c:912 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/dxgi/swapchain.c:1067 error: patch failed: dlls/dxgi/swapchain.c:1422 error: patch failed: dlls/dxgi/swapchain.c:1421 error: patch failed: dlls/d3d12/tests/d3d12.c:912 Task: Patch failed to apply