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_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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
while (!e->signalled)
|
||||
@@ -55,20 +48,20 @@ static void vkd3d_null_event_wait(struct vkd3d_null_event *e)
|
||||
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_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_cond_init(&e->cond);
|
||||
e->signalled = false;
|
||||
}
|
||||
|
||||
static HRESULT vkd3d_signal_null_event(HANDLE h)
|
||||
HRESULT vkd3d_signal_null_event(HANDLE h)
|
||||
{
|
||||
vkd3d_null_event_signal(h);
|
||||
|
||||
|
@@ -4948,6 +4948,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
|
||||
D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event)
|
||||
{
|
||||
struct d3d12_device *device = impl_from_ID3D12Device9(iface);
|
||||
struct vkd3d_null_event null_event;
|
||||
struct waiting_event_semaphore *s;
|
||||
PFN_vkd3d_signal_event signal;
|
||||
struct d3d12_fence *fence;
|
||||
@@ -4969,20 +4970,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
|
||||
if (fence_count == 1)
|
||||
return ID3D12Fence_SetEventOnCompletion(fences[0], values[0], event);
|
||||
|
||||
if (!event)
|
||||
{
|
||||
FIXME("Unhandled NULL event.\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (!(s = vkd3d_malloc(sizeof(*s))))
|
||||
{
|
||||
WARN("Failed to allocate semaphore memory.\n");
|
||||
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->signal = device->signal_event;
|
||||
s->signal = signal;
|
||||
s->value = fence_count;
|
||||
|
||||
if (flags & D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY)
|
||||
@@ -5017,6 +5019,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
|
||||
vkd3d_mutex_unlock(&fence->mutex);
|
||||
}
|
||||
|
||||
if (event == &null_event)
|
||||
{
|
||||
vkd3d_null_event_wait(&null_event);
|
||||
vkd3d_null_event_cleanup(&null_event);
|
||||
}
|
||||
|
||||
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);
|
||||
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
|
||||
{
|
||||
uint64_t value;
|
||||
|
@@ -38915,8 +38915,7 @@ static void multi_fence_event_wait_main(void *ctx)
|
||||
|
||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(data->device,
|
||||
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);
|
||||
}
|
||||
@@ -39050,7 +39049,7 @@ static void test_multi_fence_event(void)
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||
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);
|
||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||
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);
|
||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||
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);
|
||||
ok(ret == WAIT_TIMEOUT, "Got ret %#x.\n", ret);
|
||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||
@@ -39100,25 +39099,16 @@ static void test_multi_fence_event(void)
|
||||
ok(thread, "Failed to create thread.\n");
|
||||
ret = wait_event(thread_data.started, INFINITE);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
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");
|
||||
ret = wait_event(thread_data.started, INFINITE);
|
||||
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);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
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");
|
||||
ret = wait_event(thread_data.started, INFINITE);
|
||||
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);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ret = wait_event(thread_data.completed, INFINITE);
|
||||
@@ -39211,7 +39195,7 @@ static void test_multi_fence_event(void)
|
||||
|
||||
hr = ID3D12Device1_SetEventOnMultipleFenceCompletion(device1, fences,
|
||||
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.started);
|
||||
|
Reference in New Issue
Block a user