vkd3d: Handle NULL event handles in ID3D12Fence::SetEvent*().
We need to block here for whatever reason. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
455f00fe26
commit
e1bb5f3b77
|
@ -559,12 +559,14 @@ static void d3d12_fence_dec_ref(struct d3d12_fence *fence)
|
||||||
vkd3d_free(fence->pending_updates);
|
vkd3d_free(fence->pending_updates);
|
||||||
pthread_mutex_destroy(&fence->mutex);
|
pthread_mutex_destroy(&fence->mutex);
|
||||||
pthread_cond_destroy(&fence->cond);
|
pthread_cond_destroy(&fence->cond);
|
||||||
|
pthread_cond_destroy(&fence->null_event_cond);
|
||||||
vkd3d_free(fence);
|
vkd3d_free(fence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence)
|
static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence)
|
||||||
{
|
{
|
||||||
|
bool signal_null_event_cond = false;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -573,11 +575,19 @@ static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence)
|
||||||
struct vkd3d_waiting_event *current = &fence->events[i];
|
struct vkd3d_waiting_event *current = &fence->events[i];
|
||||||
|
|
||||||
if (current->value <= fence->virtual_value)
|
if (current->value <= fence->virtual_value)
|
||||||
|
{
|
||||||
|
if (current->event)
|
||||||
{
|
{
|
||||||
if (FAILED(hr = fence->device->signal_event(current->event)))
|
if (FAILED(hr = fence->device->signal_event(current->event)))
|
||||||
ERR("Failed to signal event, hr #%x.\n", hr);
|
ERR("Failed to signal event, hr #%x.\n", hr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
*current->latch = true;
|
||||||
|
signal_null_event_cond = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (i != j)
|
if (i != j)
|
||||||
fence->events[j] = *current;
|
fence->events[j] = *current;
|
||||||
|
@ -586,6 +596,9 @@ static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence)
|
||||||
}
|
}
|
||||||
|
|
||||||
fence->event_count = j;
|
fence->event_count = j;
|
||||||
|
|
||||||
|
if (signal_null_event_cond)
|
||||||
|
pthread_cond_broadcast(&fence->null_event_cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d12_fence_block_until_pending_value_reaches_locked(struct d3d12_fence *fence, UINT64 pending_value)
|
static void d3d12_fence_block_until_pending_value_reaches_locked(struct d3d12_fence *fence, UINT64 pending_value)
|
||||||
|
@ -862,6 +875,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(d3d12_fence_if
|
||||||
struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
bool latch;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
TRACE("iface %p, value %#"PRIx64", event %p.\n", iface, value, event);
|
TRACE("iface %p, value %#"PRIx64", event %p.\n", iface, value, event);
|
||||||
|
@ -873,6 +887,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(d3d12_fence_if
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value <= fence->virtual_value)
|
if (value <= fence->virtual_value)
|
||||||
|
{
|
||||||
|
if (event)
|
||||||
{
|
{
|
||||||
if (FAILED(hr = fence->device->signal_event(event)))
|
if (FAILED(hr = fence->device->signal_event(event)))
|
||||||
{
|
{
|
||||||
|
@ -880,6 +896,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(d3d12_fence_if
|
||||||
pthread_mutex_unlock(&fence->mutex);
|
pthread_mutex_unlock(&fence->mutex);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&fence->mutex);
|
pthread_mutex_unlock(&fence->mutex);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -888,7 +905,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(d3d12_fence_if
|
||||||
for (i = 0; i < fence->event_count; ++i)
|
for (i = 0; i < fence->event_count; ++i)
|
||||||
{
|
{
|
||||||
struct vkd3d_waiting_event *current = &fence->events[i];
|
struct vkd3d_waiting_event *current = &fence->events[i];
|
||||||
if (current->value == value && current->event == event)
|
if (current->value == value && event && current->event == event)
|
||||||
{
|
{
|
||||||
WARN("Event completion for (%p, %#"PRIx64") is already in the list.\n",
|
WARN("Event completion for (%p, %#"PRIx64") is already in the list.\n",
|
||||||
event, value);
|
event, value);
|
||||||
|
@ -907,8 +924,20 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(d3d12_fence_if
|
||||||
|
|
||||||
fence->events[fence->event_count].value = value;
|
fence->events[fence->event_count].value = value;
|
||||||
fence->events[fence->event_count].event = event;
|
fence->events[fence->event_count].event = event;
|
||||||
|
fence->events[fence->event_count].latch = &latch;
|
||||||
++fence->event_count;
|
++fence->event_count;
|
||||||
|
|
||||||
|
/* If event is NULL, we need to block until the fence value completes.
|
||||||
|
* Implement this in a uniform way where we pretend we have a dummy event.
|
||||||
|
* A NULL fence->events[].event means that we should set latch to true
|
||||||
|
* and signal a condition variable instead of calling external signal_event callback. */
|
||||||
|
if (!event)
|
||||||
|
{
|
||||||
|
latch = false;
|
||||||
|
while (!latch)
|
||||||
|
pthread_cond_wait(&fence->null_event_cond, &fence->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&fence->mutex);
|
pthread_mutex_unlock(&fence->mutex);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -998,6 +1027,15 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
||||||
if ((rc = pthread_cond_init(&fence->cond, NULL)))
|
if ((rc = pthread_cond_init(&fence->cond, NULL)))
|
||||||
{
|
{
|
||||||
ERR("Failed to initialize cond variable, error %d.\n", rc);
|
ERR("Failed to initialize cond variable, error %d.\n", rc);
|
||||||
|
pthread_mutex_destroy(&fence->mutex);
|
||||||
|
return hresult_from_errno(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rc = pthread_cond_init(&fence->null_event_cond, NULL)))
|
||||||
|
{
|
||||||
|
ERR("Failed to initialize cond variable, error %d.\n", rc);
|
||||||
|
pthread_mutex_destroy(&fence->mutex);
|
||||||
|
pthread_cond_destroy(&fence->cond);
|
||||||
return hresult_from_errno(rc);
|
return hresult_from_errno(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,6 +1053,8 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
||||||
if (FAILED(hr = vkd3d_private_store_init(&fence->private_store)))
|
if (FAILED(hr = vkd3d_private_store_init(&fence->private_store)))
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&fence->mutex);
|
pthread_mutex_destroy(&fence->mutex);
|
||||||
|
pthread_cond_destroy(&fence->cond);
|
||||||
|
pthread_cond_destroy(&fence->null_event_cond);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,11 +547,13 @@ struct d3d12_fence
|
||||||
|
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
|
pthread_cond_t null_event_cond;
|
||||||
|
|
||||||
struct vkd3d_waiting_event
|
struct vkd3d_waiting_event
|
||||||
{
|
{
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
|
bool *latch;
|
||||||
} *events;
|
} *events;
|
||||||
size_t events_size;
|
size_t events_size;
|
||||||
size_t event_count;
|
size_t event_count;
|
||||||
|
|
Loading…
Reference in New Issue