vkd3d: Reimplement frame latency event as a semaphore.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
parent
fef30f5037
commit
715eca1b95
|
@ -1009,7 +1009,7 @@ static CONST_VTBL struct ID3D12Fence1Vtbl d3d12_fence_vtbl =
|
||||||
d3d12_fence_GetCreationFlags,
|
d3d12_fence_GetCreationFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct d3d12_fence *unsafe_impl_from_ID3D12Fence1(ID3D12Fence1 *iface)
|
struct d3d12_fence *unsafe_impl_from_ID3D12Fence1(ID3D12Fence1 *iface)
|
||||||
{
|
{
|
||||||
if (!iface)
|
if (!iface)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1017,7 +1017,7 @@ static struct d3d12_fence *unsafe_impl_from_ID3D12Fence1(ID3D12Fence1 *iface)
|
||||||
return impl_from_ID3D12Fence(iface);
|
return impl_from_ID3D12Fence(iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface)
|
struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface)
|
||||||
{
|
{
|
||||||
return unsafe_impl_from_ID3D12Fence1((ID3D12Fence1 *)iface);
|
return unsafe_impl_from_ID3D12Fence1((ID3D12Fence1 *)iface);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1967,33 +1967,15 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)
|
if (FAILED(hr = d3d12_fence_set_event_on_completion(unsafe_impl_from_ID3D12Fence(swapchain->frame_latency_fence),
|
||||||
|
swapchain->frame_number, swapchain->frame_latency_event, VKD3D_WAITING_EVENT_TYPE_SEMAPHORE)))
|
||||||
{
|
{
|
||||||
if (FAILED(hr = ID3D12Fence_SetEventOnCompletion(swapchain->frame_latency_fence,
|
ERR("Failed to enqueue frame latency event, hr %#x.\n", hr);
|
||||||
swapchain->frame_number - swapchain->frame_latency, swapchain->frame_latency_event)))
|
return hr;
|
||||||
{
|
|
||||||
ERR("Failed to enqueue frame latency event, hr %#x.\n", hr);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
const uint32_t sync_latency = min(swapchain->frame_latency, swapchain->desc.BufferCount + 1);
|
|
||||||
const uint64_t frame_target = swapchain->frame_number - sync_latency;
|
|
||||||
|
|
||||||
if (ID3D12Fence_GetCompletedValue(swapchain->frame_latency_fence) < frame_target)
|
if (!(swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT))
|
||||||
{
|
WaitForSingleObject(swapchain->frame_latency_event, INFINITE);
|
||||||
/* Wait on the latency. */
|
|
||||||
if (FAILED(hr = ID3D12Fence_SetEventOnCompletion(swapchain->frame_latency_fence,
|
|
||||||
frame_target, swapchain->frame_latency_event)))
|
|
||||||
{
|
|
||||||
ERR("Failed to enqueue frame latency event (internal), hr %#x.\n", hr);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitForSingleObject(swapchain->frame_latency_event, INFINITE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
swapchain->current_buffer_index = (swapchain->current_buffer_index + 1) % swapchain->desc.BufferCount;
|
swapchain->current_buffer_index = (swapchain->current_buffer_index + 1) % swapchain->desc.BufferCount;
|
||||||
return hresult_from_vk_result(vr);
|
return hresult_from_vk_result(vr);
|
||||||
|
@ -2480,6 +2462,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMaximumFrameLatency(dxgi_swa
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only increasing the latency is handled here; apparently it is
|
||||||
|
* the application's responsibility to reduce the semaphore value
|
||||||
|
* in case the latency gets reduced. */
|
||||||
|
if (max_latency > swapchain->frame_latency)
|
||||||
|
ReleaseSemaphore(swapchain->frame_latency_event, max_latency - swapchain->frame_latency, NULL);
|
||||||
|
|
||||||
swapchain->frame_latency = max_latency;
|
swapchain->frame_latency = max_latency;
|
||||||
LeaveCriticalSection(&swapchain->mutex);
|
LeaveCriticalSection(&swapchain->mutex);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -2847,7 +2835,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IDXGIFact
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(swapchain->frame_latency_event = CreateEventW(NULL, FALSE, TRUE, NULL)))
|
if (!(swapchain->frame_latency_event = CreateSemaphore(NULL, swapchain->frame_latency, DXGI_MAX_SWAP_CHAIN_BUFFERS, NULL)))
|
||||||
{
|
{
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
WARN("Failed to create frame latency event, hr %#x.\n", hr);
|
WARN("Failed to create frame latency event, hr %#x.\n", hr);
|
||||||
|
|
|
@ -570,6 +570,8 @@ struct d3d12_fence
|
||||||
struct vkd3d_private_store private_store;
|
struct vkd3d_private_store private_store;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct d3d12_fence *unsafe_impl_from_ID3D12Fence1(ID3D12Fence1 *iface);
|
||||||
|
struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface);
|
||||||
HRESULT d3d12_fence_create(struct d3d12_device *device,
|
HRESULT d3d12_fence_create(struct d3d12_device *device,
|
||||||
uint64_t initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence);
|
uint64_t initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence);
|
||||||
HRESULT d3d12_fence_set_event_on_completion(struct d3d12_fence *fence,
|
HRESULT d3d12_fence_set_event_on_completion(struct d3d12_fence *fence,
|
||||||
|
|
Loading…
Reference in New Issue