[PATCH 0/5] MR2486: D3D12 swapchain latency semaphore fixes
From: Giovanni Mascellani <gmascellani(a)codeweavers.com> --- dlls/dxgi/tests/dxgi.c | 100 ++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 41 deletions(-) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index ac302840dec..b5f1475ca78 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -908,8 +908,8 @@ static IDXGIAdapter *get_adapter_(unsigned int line, IUnknown *device, BOOL is_d return adapter; } -#define create_swapchain(a, b, c) create_swapchain_(__LINE__, a, b, c) -static IDXGISwapChain *create_swapchain_(unsigned int line, IUnknown *device, BOOL is_d3d12, HWND window) +#define create_swapchain(a, b, c, d) create_swapchain_(__LINE__, a, b, c, d) +static IDXGISwapChain *create_swapchain_(unsigned int line, IUnknown *device, BOOL is_d3d12, HWND window, UINT flags) { DXGI_SWAP_CHAIN_DESC desc; IDXGISwapChain *swapchain; @@ -930,7 +930,7 @@ static IDXGISwapChain *create_swapchain_(unsigned int line, IUnknown *device, BO desc.OutputWindow = window; desc.Windowed = TRUE; desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; - desc.Flags = 0; + desc.Flags = flags; get_factory(device, is_d3d12, &factory); hr = IDXGIFactory_CreateSwapChain(factory, device, &desc, &swapchain); @@ -7564,57 +7564,75 @@ done: static void test_swapchain_present_count(IUnknown *device, BOOL is_d3d12) { + static const UINT test_flags[] = + { + 0, + DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT, + }; + UINT present_count, expected; IDXGISwapChain *swapchain; + unsigned int i; HWND window; HRESULT hr; window = create_window(); - swapchain = create_swapchain(device, is_d3d12, window); - present_count = ~0u; - hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(!present_count, "Got unexpected present count %u.\n", present_count); + for (i = 0; i < ARRAY_SIZE(test_flags); ++i) + { + UINT flags = test_flags[i]; - hr = IDXGISwapChain_Present(swapchain, 0, 0); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - expected = present_count + 1; - hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + if (!is_d3d12 && (flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + continue; - hr = IDXGISwapChain_Present(swapchain, 10, 0); - ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); - expected = present_count; - hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + swapchain = create_swapchain(device, is_d3d12, window, flags); - hr = IDXGISwapChain_Present(swapchain, 0, DXGI_PRESENT_TEST); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - expected = present_count; - hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + present_count = ~0u; + hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) + ok(!present_count, "Got unexpected present count %u.\n", present_count); - ShowWindow(window, SW_MINIMIZE); - hr = IDXGISwapChain_Present(swapchain, 0, 0); - ok(hr == (is_d3d12 ? S_OK : DXGI_STATUS_OCCLUDED), "Got unexpected hr %#lx.\n", hr); - expected = present_count + !!is_d3d12; - hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + hr = IDXGISwapChain_Present(swapchain, 0, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + expected = present_count + 1; + hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); - ShowWindow(window, SW_NORMAL); - hr = IDXGISwapChain_Present(swapchain, 0, 0); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - expected = present_count + 1; - hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + hr = IDXGISwapChain_Present(swapchain, 10, 0); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); + expected = present_count; + hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + + hr = IDXGISwapChain_Present(swapchain, 0, DXGI_PRESENT_TEST); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + expected = present_count; + hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + + ShowWindow(window, SW_MINIMIZE); + hr = IDXGISwapChain_Present(swapchain, 0, 0); + ok(hr == (is_d3d12 ? S_OK : DXGI_STATUS_OCCLUDED), "Got unexpected hr %#lx.\n", hr); + expected = present_count + !!is_d3d12; + hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + + ShowWindow(window, SW_NORMAL); + hr = IDXGISwapChain_Present(swapchain, 0, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + expected = present_count + 1; + hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(present_count == expected, "Got unexpected present count %u, expected %u.\n", present_count, expected); + + IDXGISwapChain_Release(swapchain); + } - IDXGISwapChain_Release(swapchain); DestroyWindow(window); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2486
From: Giovanni Mascellani <gmascellani(a)codeweavers.com> --- dlls/dxgi/swapchain.c | 9 ++++++--- dlls/dxgi/tests/dxgi.c | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 1f5eb99ab4b..554e910de11 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2039,15 +2039,19 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain, ++swapchain->frame_number; if ((frame_latency_event = swapchain->frame_latency_event)) { + /* Bias the frame number to avoid underflowing in + * SetEventOnCompletion(). */ + uint64_t number = swapchain->frame_number + DXGI_MAX_SWAP_CHAIN_BUFFERS; + if (FAILED(hr = ID3D12CommandQueue_Signal(swapchain->command_queue, - swapchain->frame_latency_fence, swapchain->frame_number))) + swapchain->frame_latency_fence, number))) { ERR("Failed to signal frame latency fence, hr %#lx.\n", hr); return hr; } if (FAILED(hr = ID3D12Fence_SetEventOnCompletion(swapchain->frame_latency_fence, - swapchain->frame_number - swapchain->frame_latency, frame_latency_event))) + number - swapchain->frame_latency, frame_latency_event))) { ERR("Failed to enqueue frame latency event, hr %#lx.\n", hr); return hr; @@ -2979,7 +2983,6 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) { - swapchain->frame_number = DXGI_MAX_SWAP_CHAIN_BUFFERS; swapchain->frame_latency = 1; if (FAILED(hr = ID3D12Device_CreateFence(device, DXGI_MAX_SWAP_CHAIN_BUFFERS, diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index b5f1475ca78..0661c68b109 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -7590,7 +7590,6 @@ static void test_swapchain_present_count(IUnknown *device, BOOL is_d3d12) present_count = ~0u; hr = IDXGISwapChain_GetLastPresentCount(swapchain, &present_count); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine_if(flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) ok(!present_count, "Got unexpected present count %u.\n", present_count); hr = IDXGISwapChain_Present(swapchain, 0, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2486
From: Giovanni Mascellani <gmascellani(a)codeweavers.com> --- dlls/dxgi/swapchain.c | 16 +++++++++++++++- dlls/dxgi/tests/dxgi.c | 18 ++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 554e910de11..910286b8c5f 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2564,10 +2564,24 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetMaximumFrameLatency(IDXGISwa static HANDLE STDMETHODCALLTYPE d3d12_swapchain_GetFrameLatencyWaitableObject(IDXGISwapChain4 *iface) { struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain4(iface); + HANDLE dup; + BOOL ret; TRACE("iface %p.\n", iface); - return swapchain->frame_latency_event; + if (!swapchain->frame_latency_event) + return NULL; + + ret = DuplicateHandle(GetCurrentProcess(), swapchain->frame_latency_event, GetCurrentProcess(), + &dup, 0, FALSE, DUPLICATE_SAME_ACCESS); + + if (!ret) + { + ERR("Cannot duplicate handle, last error %lu.\n", GetLastError()); + return NULL; + } + + return dup; } static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMatrixTransform(IDXGISwapChain4 *iface, diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 0661c68b109..4cd122995ef 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -6981,13 +6981,14 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) IDXGISwapChain1 *swapchain1; IDXGIFactory2 *factory2; IDXGIFactory *factory; + HANDLE event, event2; UINT frame_latency; DWORD wait_result; ULONG ref_count; unsigned int i; - HANDLE event; HWND window; HRESULT hr; + BOOL ret; get_factory(device, is_d3d12, &factory); @@ -7052,7 +7053,20 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) IDXGISwapChain1_Release(swapchain1); event = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); - ok(!!event, "Got unexpected event %p.\n", event); + ok(!!event, "Got unexpected NULL event.\n"); + + /* a new duplicate handle is returned each time */ + event2 = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!!event2, "Got unexpected NULL event.\n"); + ok(event != event2, "Got the same event twice %p.\n", event); + + ret = CloseHandle(event); + ok(!!ret, "Failed to close handle, last error %lu.\n", GetLastError()); + ret = CloseHandle(event2); + ok(!!ret, "Failed to close handle, last error %lu.\n", GetLastError()); + + event = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!!event, "Got unexpected NULL event.\n"); /* auto-reset event */ wait_result = WaitForSingleObject(event, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2486
From: Giovanni Mascellani <gmascellani(a)codeweavers.com>
From the tests it behaves more like a semaphore than like an event.
I'm not testing explicitly because I'm not sure it's relevant, but another indication is that calling ReleaseSemaphore() returns ERROR_ACCESS_DENIED, while calling SetEvent() returns ERROR_INVALID_HANDLE. --- dlls/dxgi/tests/dxgi.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 4cd122995ef..b8863594090 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -6977,11 +6977,11 @@ static void test_factory_check_feature_support(void) static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) { DXGI_SWAP_CHAIN_DESC1 swapchain_desc; + HANDLE semaphore, semaphore2; IDXGISwapChain2 *swapchain2; IDXGISwapChain1 *swapchain1; IDXGIFactory2 *factory2; IDXGIFactory *factory; - HANDLE event, event2; UINT frame_latency; DWORD wait_result; ULONG ref_count; @@ -7036,8 +7036,8 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) ok(frame_latency == 0xdeadbeef, "Got unexpected frame latency %#x.\n", frame_latency); hr = IDXGISwapChain2_SetMaximumFrameLatency(swapchain2, 1); ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); - event = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); - ok(!event, "Got unexpected event %p.\n", event); + semaphore = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!semaphore, "Got unexpected semaphore %p.\n", semaphore); ref_count = IDXGISwapChain2_Release(swapchain2); ok(!ref_count, "Swap chain has %lu references left.\n", ref_count); @@ -7052,26 +7052,25 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); IDXGISwapChain1_Release(swapchain1); - event = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); - ok(!!event, "Got unexpected NULL event.\n"); + semaphore = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!!semaphore, "Got unexpected NULL semaphore.\n"); /* a new duplicate handle is returned each time */ - event2 = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); - ok(!!event2, "Got unexpected NULL event.\n"); - ok(event != event2, "Got the same event twice %p.\n", event); + semaphore2 = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!!semaphore2, "Got unexpected NULL semaphore.\n"); + ok(semaphore != semaphore2, "Got the same semaphore twice %p.\n", semaphore); - ret = CloseHandle(event); + ret = CloseHandle(semaphore); ok(!!ret, "Failed to close handle, last error %lu.\n", GetLastError()); - ret = CloseHandle(event2); + ret = CloseHandle(semaphore2); ok(!!ret, "Failed to close handle, last error %lu.\n", GetLastError()); - event = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); - ok(!!event, "Got unexpected NULL event.\n"); + semaphore = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!!semaphore, "Got unexpected NULL semaphore.\n"); - /* auto-reset event */ - wait_result = WaitForSingleObject(event, 0); + wait_result = WaitForSingleObject(semaphore, 0); ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); - wait_result = WaitForSingleObject(event, 0); + wait_result = WaitForSingleObject(semaphore, 0); ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); @@ -7090,11 +7089,11 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(frame_latency == 3, "Got unexpected frame latency %#x.\n", frame_latency); - wait_result = WaitForSingleObject(event, 0); + wait_result = WaitForSingleObject(semaphore, 0); todo_wine ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); - wait_result = WaitForSingleObject(event, 0); + wait_result = WaitForSingleObject(semaphore, 0); todo_wine ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); - wait_result = WaitForSingleObject(event, 100); + wait_result = WaitForSingleObject(semaphore, 100); ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); for (i = 0; i < 5; i++) @@ -7102,11 +7101,11 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) hr = IDXGISwapChain2_Present(swapchain2, 0, 0); ok(hr == S_OK, "Present %u failed with hr %#lx.\n", i, hr); - wait_result = WaitForSingleObject(event, 100); + wait_result = WaitForSingleObject(semaphore, 100); ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); } - wait_result = WaitForSingleObject(event, 100); + wait_result = WaitForSingleObject(semaphore, 100); ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); ref_count = IDXGISwapChain2_Release(swapchain2); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2486
From: Giovanni Mascellani <gmascellani(a)codeweavers.com> --- dlls/dxgi/tests/dxgi.c | 92 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index b8863594090..fb2e3c3114e 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -6980,8 +6980,11 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) HANDLE semaphore, semaphore2; IDXGISwapChain2 *swapchain2; IDXGISwapChain1 *swapchain1; + ID3D12Device *d3d12_device; + ID3D12CommandQueue *queue; IDXGIFactory2 *factory2; IDXGIFactory *factory; + ID3D12Fence *fence; UINT frame_latency; DWORD wait_result; ULONG ref_count; @@ -7083,6 +7086,8 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(frame_latency == 1, "Got unexpected frame latency %#x.\n", frame_latency); + /* raising the maximum frame latency releases the semaphore the + * corresponding number of times */ hr = IDXGISwapChain2_SetMaximumFrameLatency(swapchain2, 3); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); @@ -7096,18 +7101,105 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) wait_result = WaitForSingleObject(semaphore, 100); ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); + /* lowering the maximum frame latency doesn't seem to impact the + * semaphore */ + hr = IDXGISwapChain2_SetMaximumFrameLatency(swapchain2, 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(frame_latency == 1, "Got unexpected frame latency %#x.\n", frame_latency); + + wait_result = WaitForSingleObject(semaphore, 100); + ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); + + for (i = 0; i < 5; i++) + { + hr = IDXGISwapChain2_Present(swapchain2, 0, 0); + ok(hr == S_OK, "Present %u failed with hr %#lx.\n", i, hr); + + wait_result = WaitForSingleObject(semaphore, 100); + ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); + } + + wait_result = WaitForSingleObject(semaphore, 100); + ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); + + /* each frame presentation releases the semaphore */ for (i = 0; i < 5; i++) { hr = IDXGISwapChain2_Present(swapchain2, 0, 0); ok(hr == S_OK, "Present %u failed with hr %#lx.\n", i, hr); + } + for (i = 0; i < 5; i++) + { wait_result = WaitForSingleObject(semaphore, 100); + todo_wine_if(i != 0) ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); } wait_result = WaitForSingleObject(semaphore, 100); ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); + if (is_d3d12) + { + hr = IUnknown_QueryInterface(device, &IID_ID3D12CommandQueue, (void **)&queue); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID3D12CommandQueue_GetDevice(queue, &IID_ID3D12Device, (void **)&d3d12_device); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID3D12Device_CreateFence(d3d12_device, 0, 0, &IID_ID3D12Fence, (void **)&fence); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* the semaphore is released when the frame is really + * presented, not when Present() is called */ + for (i = 0; i < 3; i++) + { + hr = IDXGISwapChain2_Present(swapchain2, 0, 0); + ok(hr == S_OK, "Present %u failed with hr %#lx.\n", i, hr); + } + + hr = ID3D12CommandQueue_Wait(queue, fence, 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + for (i = 0; i < 4; i++) + { + hr = IDXGISwapChain2_Present(swapchain2, 0, 0); + ok(hr == S_OK, "Present %u failed with hr %#lx.\n", i, hr); + } + + for (i = 0; i < 3; i++) + { + wait_result = WaitForSingleObject(semaphore, 100); + todo_wine_if(i != 0) + ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); + } + + wait_result = WaitForSingleObject(semaphore, 100); + ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); + + hr = ID3D12Fence_Signal(fence, 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + Sleep(100); + + for (i = 0; i < 4; i++) + { + wait_result = WaitForSingleObject(semaphore, 100); + todo_wine_if(i != 0) + ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); + } + + wait_result = WaitForSingleObject(semaphore, 100); + ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); + + ref_count = ID3D12Fence_Release(fence); + ok(!ref_count, "Fence has %lu references left.\n", ref_count); + ID3D12Device_Release(d3d12_device); + ID3D12CommandQueue_Release(queue); + } + ref_count = IDXGISwapChain2_Release(swapchain2); ok(!ref_count, "Swap chain has %lu references left.\n", ref_count); DestroyWindow(window); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2486
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 full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=130986 Your paranoid android. === build (build log) === error: patch failed: dlls/dxgi/tests/dxgi.c:6977 error: patch failed: dlls/dxgi/tests/dxgi.c:6980 Task: Patch failed to apply === debian11 (build log) === error: patch failed: dlls/dxgi/tests/dxgi.c:6977 error: patch failed: dlls/dxgi/tests/dxgi.c:6980 Task: Patch failed to apply === debian11b (build log) === error: patch failed: dlls/dxgi/tests/dxgi.c:6977 error: patch failed: dlls/dxgi/tests/dxgi.c:6980 Task: Patch failed to apply
Zebediah Figura (@zfigura) commented about dlls/dxgi/tests/dxgi.c:
wait_result = WaitForSingleObject(semaphore, 100); ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result);
+ /* lowering the maximum frame latency doesn't seem to impact the + * semaphore */ + hr = IDXGISwapChain2_SetMaximumFrameLatency(swapchain2, 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(frame_latency == 1, "Got unexpected frame latency %#x.\n", frame_latency); + + wait_result = WaitForSingleObject(semaphore, 100); + ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result);
I'm not sure I understand what this test is proving? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2486#note_27717
Zebediah Figura (@zfigura) commented about dlls/dxgi/tests/dxgi.c:
+ + for (i = 0; i < 3; i++) + { + wait_result = WaitForSingleObject(semaphore, 100); + todo_wine_if(i != 0) + ok(!wait_result, "Got unexpected wait result %#lx.\n", wait_result); + } + + wait_result = WaitForSingleObject(semaphore, 100); + ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#lx.\n", wait_result); + + hr = ID3D12Fence_Signal(fence, 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + Sleep(100); + Is this a relic?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/2486#note_27718
On Fri Mar 24 01:26:06 2023 +0000, Zebediah Figura wrote:
I'm not sure I understand what this test is proving? Basically what the comment says: that lowering the maximum frame latency (here going from 3 to 1) doesn't cause any change in the semaphore state (which had value zero just before these lines and still has value zero here).
When I realized that raising the maximum frame latency causes the semaphore to be released I wondered what would happen when lowering it. For example, it could wait on it. However, it seems it doesn't (this is apparently also confirmed by vkd3d-proton's implementation). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2486#note_27786
On Fri Mar 24 01:26:07 2023 +0000, Zebediah Figura wrote:
Is this a relic? Not really a relic, but yes, I'd say it can be removed, given that the `WaitForSingleObject()` call already gives some time for the presentations to happen.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/2486#note_27787
participants (4)
-
Giovanni Mascellani -
Giovanni Mascellani (@giomasce) -
Marvin -
Zebediah Figura (@zfigura)