mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d: Handle multiple fence NULL event waits in d3d12_device_SetEventOnMultipleFenceCompletion().
This commit is contained in:
Notes:
Henri Verbeet
2025-05-06 19:05:21 +02:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1476
@@ -31,13 +31,6 @@ static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue)
|
|||||||
static HRESULT d3d12_command_queue_flush_ops(struct d3d12_command_queue *queue, bool *flushed_any);
|
static HRESULT d3d12_command_queue_flush_ops(struct d3d12_command_queue *queue, bool *flushed_any);
|
||||||
static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *queue, bool *flushed_any);
|
static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *queue, bool *flushed_any);
|
||||||
|
|
||||||
struct vkd3d_null_event
|
|
||||||
{
|
|
||||||
struct vkd3d_mutex mutex;
|
|
||||||
struct vkd3d_cond cond;
|
|
||||||
bool signalled;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void vkd3d_null_event_signal(struct vkd3d_null_event *e)
|
static void vkd3d_null_event_signal(struct vkd3d_null_event *e)
|
||||||
{
|
{
|
||||||
vkd3d_mutex_lock(&e->mutex);
|
vkd3d_mutex_lock(&e->mutex);
|
||||||
@@ -46,7 +39,7 @@ static void vkd3d_null_event_signal(struct vkd3d_null_event *e)
|
|||||||
vkd3d_mutex_unlock(&e->mutex);
|
vkd3d_mutex_unlock(&e->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vkd3d_null_event_wait(struct vkd3d_null_event *e)
|
void vkd3d_null_event_wait(struct vkd3d_null_event *e)
|
||||||
{
|
{
|
||||||
vkd3d_mutex_lock(&e->mutex);
|
vkd3d_mutex_lock(&e->mutex);
|
||||||
while (!e->signalled)
|
while (!e->signalled)
|
||||||
@@ -55,20 +48,20 @@ static void vkd3d_null_event_wait(struct vkd3d_null_event *e)
|
|||||||
vkd3d_mutex_unlock(&e->mutex);
|
vkd3d_mutex_unlock(&e->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vkd3d_null_event_cleanup(struct vkd3d_null_event *e)
|
void vkd3d_null_event_cleanup(struct vkd3d_null_event *e)
|
||||||
{
|
{
|
||||||
vkd3d_cond_destroy(&e->cond);
|
vkd3d_cond_destroy(&e->cond);
|
||||||
vkd3d_mutex_destroy(&e->mutex);
|
vkd3d_mutex_destroy(&e->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vkd3d_null_event_init(struct vkd3d_null_event *e)
|
void vkd3d_null_event_init(struct vkd3d_null_event *e)
|
||||||
{
|
{
|
||||||
vkd3d_mutex_init(&e->mutex);
|
vkd3d_mutex_init(&e->mutex);
|
||||||
vkd3d_cond_init(&e->cond);
|
vkd3d_cond_init(&e->cond);
|
||||||
e->signalled = false;
|
e->signalled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT vkd3d_signal_null_event(HANDLE h)
|
HRESULT vkd3d_signal_null_event(HANDLE h)
|
||||||
{
|
{
|
||||||
vkd3d_null_event_signal(h);
|
vkd3d_null_event_signal(h);
|
||||||
|
|
||||||
|
@@ -4948,6 +4948,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
|
|||||||
D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event)
|
D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event)
|
||||||
{
|
{
|
||||||
struct d3d12_device *device = impl_from_ID3D12Device9(iface);
|
struct d3d12_device *device = impl_from_ID3D12Device9(iface);
|
||||||
|
struct vkd3d_null_event null_event;
|
||||||
struct waiting_event_semaphore *s;
|
struct waiting_event_semaphore *s;
|
||||||
PFN_vkd3d_signal_event signal;
|
PFN_vkd3d_signal_event signal;
|
||||||
struct d3d12_fence *fence;
|
struct d3d12_fence *fence;
|
||||||
@@ -4969,20 +4970,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
|
|||||||
if (fence_count == 1)
|
if (fence_count == 1)
|
||||||
return ID3D12Fence_SetEventOnCompletion(fences[0], values[0], event);
|
return ID3D12Fence_SetEventOnCompletion(fences[0], values[0], event);
|
||||||
|
|
||||||
if (!event)
|
|
||||||
{
|
|
||||||
FIXME("Unhandled NULL event.\n");
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(s = vkd3d_malloc(sizeof(*s))))
|
if (!(s = vkd3d_malloc(sizeof(*s))))
|
||||||
{
|
{
|
||||||
WARN("Failed to allocate semaphore memory.\n");
|
WARN("Failed to allocate semaphore memory.\n");
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signal = device->signal_event;
|
||||||
|
if (!event)
|
||||||
|
{
|
||||||
|
vkd3d_null_event_init(&null_event);
|
||||||
|
event = &null_event;
|
||||||
|
signal = vkd3d_signal_null_event;
|
||||||
|
}
|
||||||
s->event = event;
|
s->event = event;
|
||||||
s->signal = device->signal_event;
|
s->signal = signal;
|
||||||
s->value = fence_count;
|
s->value = fence_count;
|
||||||
|
|
||||||
if (flags & D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY)
|
if (flags & D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY)
|
||||||
@@ -5017,6 +5019,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
|
|||||||
vkd3d_mutex_unlock(&fence->mutex);
|
vkd3d_mutex_unlock(&fence->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event == &null_event)
|
||||||
|
{
|
||||||
|
vkd3d_null_event_wait(&null_event);
|
||||||
|
vkd3d_null_event_cleanup(&null_event);
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -357,6 +357,18 @@ HRESULT vkd3d_set_private_data(struct vkd3d_private_store *store,
|
|||||||
const GUID *tag, unsigned int data_size, const void *data);
|
const GUID *tag, unsigned int data_size, const void *data);
|
||||||
HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store, const GUID *tag, const IUnknown *object);
|
HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store, const GUID *tag, const IUnknown *object);
|
||||||
|
|
||||||
|
struct vkd3d_null_event
|
||||||
|
{
|
||||||
|
struct vkd3d_mutex mutex;
|
||||||
|
struct vkd3d_cond cond;
|
||||||
|
bool signalled;
|
||||||
|
};
|
||||||
|
|
||||||
|
void vkd3d_null_event_cleanup(struct vkd3d_null_event *e);
|
||||||
|
void vkd3d_null_event_init(struct vkd3d_null_event *e);
|
||||||
|
void vkd3d_null_event_wait(struct vkd3d_null_event *e);
|
||||||
|
HRESULT vkd3d_signal_null_event(HANDLE h);
|
||||||
|
|
||||||
struct vkd3d_signaled_semaphore
|
struct vkd3d_signaled_semaphore
|
||||||
{
|
{
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
@@ -38915,8 +38915,7 @@ static void multi_fence_event_wait_main(void *ctx)
|
|||||||
|
|
||||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(data->device,
|
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(data->device,
|
||||||
data->fences, data->values, data->fence_count, data->flags, NULL);
|
data->fences, data->values, data->fence_count, data->flags, NULL);
|
||||||
if (vkd3d_test_platform_is_windows() || data->fence_count == 1)
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
|
||||||
|
|
||||||
signal_event(data->completed);
|
signal_event(data->completed);
|
||||||
}
|
}
|
||||||
@@ -39050,7 +39049,7 @@ static void test_multi_fence_event(void)
|
|||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||||
fence_values, 3, D3D12_MULTIPLE_FENCE_WAIT_FLAG_ALL, NULL);
|
fence_values, 3, D3D12_MULTIPLE_FENCE_WAIT_FLAG_ALL, NULL);
|
||||||
todo ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ret = wait_event(event, 0);
|
ret = wait_event(event, 0);
|
||||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||||
@@ -39060,7 +39059,7 @@ static void test_multi_fence_event(void)
|
|||||||
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
||||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||||
fence_values, 3, D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY, NULL);
|
fence_values, 3, D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY, NULL);
|
||||||
todo ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ret = wait_event(event, 0);
|
ret = wait_event(event, 0);
|
||||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||||
@@ -39100,25 +39099,16 @@ static void test_multi_fence_event(void)
|
|||||||
ok(thread, "Failed to create thread.\n");
|
ok(thread, "Failed to create thread.\n");
|
||||||
ret = wait_event(thread_data.started, INFINITE);
|
ret = wait_event(thread_data.started, INFINITE);
|
||||||
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
||||||
if (vkd3d_test_platform_is_windows())
|
ret = wait_event(thread_data.completed, 0);
|
||||||
{
|
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||||
ret = wait_event(thread_data.completed, 0);
|
|
||||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
|
||||||
}
|
|
||||||
hr = ID3D12Fence_Signal(fences[1], 41);
|
hr = ID3D12Fence_Signal(fences[1], 41);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
if (vkd3d_test_platform_is_windows())
|
ret = wait_event(thread_data.completed, 0);
|
||||||
{
|
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||||
ret = wait_event(thread_data.completed, 0);
|
|
||||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
|
||||||
}
|
|
||||||
hr = ID3D12Fence_Signal(fences[0], 40);
|
hr = ID3D12Fence_Signal(fences[0], 40);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
if (vkd3d_test_platform_is_windows())
|
ret = wait_event(thread_data.completed, 0);
|
||||||
{
|
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||||
ret = wait_event(thread_data.completed, 0);
|
|
||||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
|
||||||
}
|
|
||||||
hr = ID3D12Fence_Signal(fences[2], 42);
|
hr = ID3D12Fence_Signal(fences[2], 42);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ret = wait_event(thread_data.completed, INFINITE);
|
ret = wait_event(thread_data.completed, INFINITE);
|
||||||
@@ -39154,11 +39144,8 @@ static void test_multi_fence_event(void)
|
|||||||
ok(thread, "Failed to create thread.\n");
|
ok(thread, "Failed to create thread.\n");
|
||||||
ret = wait_event(thread_data.started, INFINITE);
|
ret = wait_event(thread_data.started, INFINITE);
|
||||||
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
||||||
if (vkd3d_test_platform_is_windows())
|
ret = wait_event(thread_data.completed, 0);
|
||||||
{
|
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||||
ret = wait_event(thread_data.completed, 0);
|
|
||||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
|
||||||
}
|
|
||||||
hr = ID3D12Fence_Signal(fences[1], 57);
|
hr = ID3D12Fence_Signal(fences[1], 57);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ret = wait_event(thread_data.completed, INFINITE);
|
ret = wait_event(thread_data.completed, INFINITE);
|
||||||
@@ -39189,11 +39176,8 @@ static void test_multi_fence_event(void)
|
|||||||
ok(thread, "Failed to create thread.\n");
|
ok(thread, "Failed to create thread.\n");
|
||||||
ret = wait_event(thread_data.started, INFINITE);
|
ret = wait_event(thread_data.started, INFINITE);
|
||||||
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
ok(ret == WAIT_OBJECT_0, "Got ret %#x.\n", ret);
|
||||||
if (vkd3d_test_platform_is_windows())
|
ret = wait_event(thread_data.completed, 0);
|
||||||
{
|
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||||
ret = wait_event(thread_data.completed, 0);
|
|
||||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
|
||||||
}
|
|
||||||
hr = ID3D12Fence_Signal(fences[1], 67);
|
hr = ID3D12Fence_Signal(fences[1], 67);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ret = wait_event(thread_data.completed, INFINITE);
|
ret = wait_event(thread_data.completed, INFINITE);
|
||||||
@@ -39211,7 +39195,7 @@ static void test_multi_fence_event(void)
|
|||||||
|
|
||||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||||
fence_values, 3, D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY, NULL);
|
fence_values, 3, D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY, NULL);
|
||||||
todo ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
destroy_event(thread_data.completed);
|
destroy_event(thread_data.completed);
|
||||||
destroy_event(thread_data.started);
|
destroy_event(thread_data.started);
|
||||||
|
Reference in New Issue
Block a user