HACK: Implement singleton devices
This commit is contained in:
parent
b514f03906
commit
a9fab2a64d
|
@ -2165,6 +2165,70 @@ static void vkd3d_gpu_va_allocator_cleanup(struct vkd3d_gpu_va_allocator *alloca
|
|||
pthread_mutex_destroy(&allocator->mutex);
|
||||
}
|
||||
|
||||
struct d3d12_device_singleton
|
||||
{
|
||||
struct list entry;
|
||||
LUID adapter_luid;
|
||||
struct d3d12_device *device;
|
||||
};
|
||||
|
||||
static pthread_once_t d3d12_device_map_mutex_init_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_mutex_t d3d12_device_map_mutex;
|
||||
static struct list d3d12_device_map;
|
||||
|
||||
static void d3d12_init_device_map_once(void)
|
||||
{
|
||||
pthread_mutex_init(&d3d12_device_map_mutex, NULL);
|
||||
list_init(&d3d12_device_map);
|
||||
}
|
||||
|
||||
static struct d3d12_device *d3d12_find_device_singleton(LUID luid)
|
||||
{
|
||||
struct d3d12_device_singleton* current;
|
||||
struct d3d12_device *device = NULL;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(current, &d3d12_device_map, struct d3d12_device_singleton, entry)
|
||||
{
|
||||
/* Avoid the bubble of time between no ref and death. */
|
||||
if (!vkd3d_atomic_uint32_load_explicit(¤t->device->refcount, vkd3d_memory_order_seq_cst))
|
||||
continue;
|
||||
|
||||
if (!memcmp(¤t->adapter_luid, &luid, sizeof(LUID)))
|
||||
return current->device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void d3d12_add_device_singleton(struct d3d12_device *device, LUID luid)
|
||||
{
|
||||
struct d3d12_device_singleton *e;
|
||||
|
||||
if (!(e = vkd3d_malloc(sizeof(*e))))
|
||||
{
|
||||
ERR("Failed to register device singleton for adapter.");
|
||||
return;
|
||||
}
|
||||
e->adapter_luid = luid;
|
||||
e->device = device;
|
||||
|
||||
list_add_tail(&d3d12_device_map, &e->entry);
|
||||
}
|
||||
|
||||
static void d3d12_remove_device_singleton(LUID luid)
|
||||
{
|
||||
struct d3d12_device_singleton *current;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(current, &d3d12_device_map, struct d3d12_device_singleton, entry)
|
||||
{
|
||||
if (!memcmp(¤t->adapter_luid, &luid, sizeof(LUID)))
|
||||
{
|
||||
list_remove(¤t->entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ID3D12Device */
|
||||
static inline struct d3d12_device *impl_from_ID3D12Device(d3d12_device_iface *iface)
|
||||
{
|
||||
|
@ -2240,6 +2304,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(d3d12_device_iface *iface)
|
|||
|
||||
if (!refcount)
|
||||
{
|
||||
pthread_mutex_lock(&d3d12_device_map_mutex);
|
||||
d3d12_remove_device_singleton(device->adapter_luid);
|
||||
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||
d3d12_device_destroy(device);
|
||||
vkd3d_free(device);
|
||||
}
|
||||
|
@ -4662,12 +4729,27 @@ HRESULT d3d12_device_create(struct vkd3d_instance *instance,
|
|||
struct d3d12_device *object;
|
||||
HRESULT hr;
|
||||
|
||||
pthread_once(&d3d12_device_map_mutex_init_once, d3d12_init_device_map_once);
|
||||
pthread_mutex_lock(&d3d12_device_map_mutex);
|
||||
if ((object = d3d12_find_device_singleton(create_info->adapter_luid)))
|
||||
{
|
||||
TRACE("Returned existing singleton device %p.\n", object);
|
||||
|
||||
d3d12_device_add_ref(*device = object);
|
||||
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (!(object = vkd3d_malloc(sizeof(*object))))
|
||||
{
|
||||
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (FAILED(hr = d3d12_device_init(object, instance, create_info)))
|
||||
{
|
||||
vkd3d_free(object);
|
||||
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -4676,11 +4758,16 @@ HRESULT d3d12_device_create(struct vkd3d_instance *instance,
|
|||
WARN("Feature level %#x is not supported.\n", create_info->minimum_feature_level);
|
||||
d3d12_device_destroy(object);
|
||||
vkd3d_free(object);
|
||||
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
TRACE("Created device %p.\n", object);
|
||||
|
||||
d3d12_add_device_singleton(object, create_info->adapter_luid);
|
||||
|
||||
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||
|
||||
*device = object;
|
||||
|
||||
return S_OK;
|
||||
|
|
Loading…
Reference in New Issue