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);
|
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 */
|
/* ID3D12Device */
|
||||||
static inline struct d3d12_device *impl_from_ID3D12Device(d3d12_device_iface *iface)
|
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)
|
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);
|
d3d12_device_destroy(device);
|
||||||
vkd3d_free(device);
|
vkd3d_free(device);
|
||||||
}
|
}
|
||||||
|
@ -4662,12 +4729,27 @@ HRESULT d3d12_device_create(struct vkd3d_instance *instance,
|
||||||
struct d3d12_device *object;
|
struct d3d12_device *object;
|
||||||
HRESULT hr;
|
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))))
|
if (!(object = vkd3d_malloc(sizeof(*object))))
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
if (FAILED(hr = d3d12_device_init(object, instance, create_info)))
|
if (FAILED(hr = d3d12_device_init(object, instance, create_info)))
|
||||||
{
|
{
|
||||||
vkd3d_free(object);
|
vkd3d_free(object);
|
||||||
|
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||||
return hr;
|
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);
|
WARN("Feature level %#x is not supported.\n", create_info->minimum_feature_level);
|
||||||
d3d12_device_destroy(object);
|
d3d12_device_destroy(object);
|
||||||
vkd3d_free(object);
|
vkd3d_free(object);
|
||||||
|
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Created device %p.\n", object);
|
TRACE("Created device %p.\n", object);
|
||||||
|
|
||||||
|
d3d12_add_device_singleton(object, create_info->adapter_luid);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&d3d12_device_map_mutex);
|
||||||
|
|
||||||
*device = object;
|
*device = object;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
Loading…
Reference in New Issue