-- v3: dxgi/tests: Test the frame latency waitable more thoroughly.
From: Giovanni Mascellani gmascellani@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); }
From: Giovanni Mascellani gmascellani@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);
From: Giovanni Mascellani gmascellani@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);
From: Giovanni Mascellani gmascellani@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);
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index b8863594090..d29c5577c14 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,107 @@ 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); + }
+ Sleep(100); + + 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);
Once `todo_wine_if()` is removed, the `Sleep(100)` can be removed to
All right, if it's temporary, that works for me.
(what is the future tense of "can" in English, in the contexts where "be able to" is not a valid replacement for "can"?).
Present "can" is actually the most idiomatic wording here. "will be able to" isn't invalid either, though maybe a bit unwieldy with the passive. I think "once we do X, we'll be able to do Y" is a pretty common construction. The simple present "can" is I think always valid in those contexts, though. The meaning is probably about the same but maybe a little less stressed.
This merge request was approved by Zebediah Figura.
This merge request was approved by Jan Sikorski.