mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
libs/vkd3d: Implement d3d12_fence_SetEventOnCompletion().
This commit is contained in:
parent
733f720ee4
commit
8ab2ebdd22
@ -73,6 +73,7 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence *iface)
|
||||
{
|
||||
struct d3d12_device *device = fence->device;
|
||||
|
||||
vkd3d_free(fence->events);
|
||||
if ((rc = pthread_mutex_destroy(&fence->mutex)))
|
||||
ERR("Failed to destroy mutex, error %d.\n", rc);
|
||||
vkd3d_free(fence);
|
||||
@ -147,14 +148,66 @@ static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence *iface
|
||||
static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *iface,
|
||||
UINT64 value, HANDLE event)
|
||||
{
|
||||
FIXME("iface %p, value %s, event %p stub!\n", iface, debugstr_uint64(value), event);
|
||||
struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("iface %p, value %s, event %p.\n", iface, debugstr_uint64(value), event);
|
||||
|
||||
if ((rc = pthread_mutex_lock(&fence->mutex)))
|
||||
{
|
||||
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (value <= fence->value)
|
||||
{
|
||||
VKD3DSignalEvent(event);
|
||||
pthread_mutex_unlock(&fence->mutex);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
for (i = 0; i < fence->event_count; ++i)
|
||||
{
|
||||
struct vkd3d_waiting_event *current = &fence->events[i];
|
||||
if (current->value == value && current->event == event)
|
||||
{
|
||||
WARN("Event completion for (%p, %s) is already in the list.\n",
|
||||
event, debugstr_uint64(value));
|
||||
pthread_mutex_unlock(&fence->mutex);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (fence->event_array_size == fence->event_count)
|
||||
{
|
||||
unsigned int new_size = 2 * fence->event_array_size;
|
||||
struct vkd3d_waiting_event *new_events;
|
||||
|
||||
TRACE("Resizing waiting events array from %u to %u.\n", fence->event_array_size, new_size);
|
||||
|
||||
if (!(new_events = vkd3d_realloc(fence->events, new_size * sizeof(*fence->events))))
|
||||
{
|
||||
pthread_mutex_unlock(&fence->mutex);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
fence->event_array_size = new_size;
|
||||
fence->events = new_events;
|
||||
}
|
||||
|
||||
fence->events[fence->event_count].value = value;
|
||||
fence->events[fence->event_count].event = event;
|
||||
++fence->event_count;
|
||||
|
||||
pthread_mutex_unlock(&fence->mutex);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 value)
|
||||
{
|
||||
struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
||||
unsigned int i, j;
|
||||
int rc;
|
||||
|
||||
TRACE("iface %p, value %s.\n", iface, debugstr_uint64(value));
|
||||
@ -164,7 +217,26 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 v
|
||||
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
fence->value = value;
|
||||
|
||||
for (i = 0, j = 0; i < fence->event_count; ++i)
|
||||
{
|
||||
struct vkd3d_waiting_event *current = &fence->events[i];
|
||||
|
||||
if (current->value <= value)
|
||||
{
|
||||
VKD3DSignalEvent(current->event);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i != j)
|
||||
fence->events[j] = *current;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
fence->event_count = j;
|
||||
|
||||
pthread_mutex_unlock(&fence->mutex);
|
||||
|
||||
return S_OK;
|
||||
@ -208,6 +280,14 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
||||
if (flags)
|
||||
FIXME("Ignoring flags %#x.\n", flags);
|
||||
|
||||
fence->event_array_size = 2;
|
||||
if (!(fence->events = vkd3d_calloc(fence->event_array_size, sizeof(*fence->events))))
|
||||
{
|
||||
pthread_mutex_destroy(&fence->mutex);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
fence->event_count = 0;
|
||||
|
||||
fence->device = device;
|
||||
ID3D12Device_AddRef(&device->ID3D12Device_iface);
|
||||
|
||||
@ -231,6 +311,7 @@ HRESULT d3d12_fence_create(struct d3d12_device *device,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Command buffers */
|
||||
static HRESULT vkd3d_begin_command_buffer(struct d3d12_command_list *list)
|
||||
{
|
||||
struct d3d12_device *device = list->device;
|
||||
|
@ -53,6 +53,12 @@ struct vkd3d_event
|
||||
BOOL is_signaled;
|
||||
};
|
||||
|
||||
struct vkd3d_waiting_event
|
||||
{
|
||||
UINT64 value;
|
||||
HANDLE event;
|
||||
};
|
||||
|
||||
/* ID3D12Fence */
|
||||
struct d3d12_fence
|
||||
{
|
||||
@ -62,6 +68,10 @@ struct d3d12_fence
|
||||
UINT64 value;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
unsigned int event_array_size;
|
||||
unsigned int event_count;
|
||||
struct vkd3d_waiting_event *events;
|
||||
|
||||
struct d3d12_device *device;
|
||||
};
|
||||
|
||||
@ -259,6 +269,13 @@ static inline void *vkd3d_malloc(size_t size)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline void *vkd3d_realloc(void *ptr, size_t size)
|
||||
{
|
||||
if (!(ptr = realloc(ptr, size)))
|
||||
ERR("Out of memory.\n");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline void *vkd3d_calloc(size_t count, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
Loading…
Reference in New Issue
Block a user