[PATCH vkd3d 1/3] vkd3d: Track descriptor heaps to allow size querying by descriptor handle.
Conor McCarthy
cmccarthy at codeweavers.com
Wed May 26 03:07:52 CDT 2021
Required for variable Vulkan bindings. The actual size must be specified
when creating a Vulkan descriptor set.
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
libs/vkd3d/device.c | 68 ++++++++++++++++++++++++++++++++++++++
libs/vkd3d/resource.c | 14 ++++++++
libs/vkd3d/vkd3d_private.h | 9 +++++
3 files changed, 91 insertions(+)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 877512e3..a4c8bca8 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -2228,6 +2228,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
vkd3d_fence_worker_stop(&device->fence_worker, device);
d3d12_device_destroy_pipeline_cache(device);
d3d12_device_destroy_vkd3d_queues(device);
+ vkd3d_free(device->descriptor_heaps);
for (i = 0; i < ARRAY_SIZE(device->desc_mutex); ++i)
pthread_mutex_destroy(&device->desc_mutex[i]);
VK_CALL(vkDestroyDevice(device->vk_device, NULL));
@@ -3727,6 +3728,10 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
if ((device->parent = create_info->parent))
IUnknown_AddRef(device->parent);
+ device->descriptor_heap_capacity = 0;
+ device->descriptor_heap_count = 0;
+ device->descriptor_heaps = NULL;
+
return S_OK;
out_destroy_null_resources:
@@ -3782,6 +3787,69 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
device->removed_reason = reason;
}
+void d3d12_device_track_descriptor_heap(struct d3d12_device *device,
+ const struct d3d12_descriptor_heap *heap)
+{
+ if (!device->vk_info.EXT_descriptor_indexing)
+ return;
+
+ if (!vkd3d_array_reserve((void **)&device->descriptor_heaps, &device->descriptor_heap_capacity,
+ device->descriptor_heap_count + 1, sizeof(*device->descriptor_heaps)))
+ {
+ ERR("Cannot track descriptor heap for unbounded arrays. Out of memory.\n");
+ return;
+ }
+
+ device->descriptor_heaps[device->descriptor_heap_count++] = heap;
+ /* Do not increment the heap reference count. This reference is deleted on heap destruction. */
+}
+
+void d3d12_device_untrack_descriptor_heap(struct d3d12_device *device,
+ const struct d3d12_descriptor_heap *heap)
+{
+ size_t i;
+
+ if (!device->vk_info.EXT_descriptor_indexing)
+ return;
+
+ for (i = 0; i < device->descriptor_heap_count; ++i)
+ {
+ if (device->descriptor_heaps[i] != heap)
+ continue;
+ memmove(&device->descriptor_heaps[i], &device->descriptor_heaps[i + 1],
+ (device->descriptor_heap_count - i - 1) * sizeof(*device->descriptor_heaps));
+ --device->descriptor_heap_count;
+ return;
+ }
+
+ ERR("Attempted to untrack an already untracked heap.\n");
+}
+
+/* Return the available size from the specified descriptor to the heap end. */
+uint32_t d3d12_device_descriptor_heap_size_from_descriptor(struct d3d12_device *device,
+ const struct d3d12_desc *desc)
+{
+ size_t i;
+
+ for (i = 0; i < device->descriptor_heap_count; ++i)
+ {
+ unsigned int size;
+
+ if (device->descriptor_heaps[i]->descriptors > (const BYTE*)desc)
+ continue;
+ size = d3d12_device_get_descriptor_handle_increment_size(device, device->descriptor_heaps[i]->desc.Type);
+ if (device->descriptor_heaps[i]->descriptors + size * device->descriptor_heaps[i]->desc.NumDescriptors
+ <= (const BYTE*)desc)
+ continue;
+
+ return device->descriptor_heaps[i]->desc.NumDescriptors
+ - (uint32_t)(((const BYTE*)desc - device->descriptor_heaps[i]->descriptors) / size);
+ }
+
+ ERR("Failed to find descriptor heap size from descriptor pointer.\n");
+ return 0;
+}
+
HRESULT vkd3d_create_thread(struct vkd3d_instance *instance,
PFN_vkd3d_thread thread_main, void *data, union vkd3d_thread_handle *thread)
{
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index a9d4d464..f117efc8 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -3327,6 +3327,7 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea
{
struct d3d12_device *device = heap->device;
unsigned int i;
+ int rc;
vkd3d_private_store_destroy(&heap->private_store);
@@ -3372,6 +3373,12 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea
vkd3d_free(heap);
+ if ((rc = pthread_mutex_lock(&device->mutex)))
+ ERR("Failed to lock mutex, error %d.\n", rc);
+ d3d12_device_untrack_descriptor_heap(device, heap);
+ if (!rc)
+ pthread_mutex_unlock(&device->mutex);
+
d3d12_device_release(device);
}
@@ -3504,6 +3511,7 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
size_t max_descriptor_count, descriptor_size;
struct d3d12_descriptor_heap *object;
HRESULT hr;
+ int rc;
if (!(descriptor_size = d3d12_device_get_descriptor_handle_increment_size(device, desc->Type)))
{
@@ -3537,6 +3545,12 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
memset(object->descriptors, 0, descriptor_size * desc->NumDescriptors);
+ if ((rc = pthread_mutex_lock(&device->mutex)))
+ ERR("Failed to lock mutex, error %d.\n", rc);
+ d3d12_device_track_descriptor_heap(device, object);
+ if (!rc)
+ pthread_mutex_unlock(&device->mutex);
+
TRACE("Created descriptor heap %p.\n", object);
*descriptor_heap = object;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 02184c87..28742a8b 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1179,6 +1179,10 @@ struct d3d12_device
const struct vkd3d_format_compatibility_list *format_compatibility_lists;
struct vkd3d_null_resources null_resources;
struct vkd3d_uav_clear_state uav_clear_state;
+
+ size_t descriptor_heap_capacity;
+ size_t descriptor_heap_count;
+ const struct d3d12_descriptor_heap **descriptor_heaps;
};
HRESULT d3d12_device_create(struct vkd3d_instance *instance,
@@ -1190,6 +1194,11 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
const char *message, ...) VKD3D_PRINTF_FUNC(3, 4) DECLSPEC_HIDDEN;
struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) DECLSPEC_HIDDEN;
+void d3d12_device_track_descriptor_heap(struct d3d12_device *device, const struct d3d12_descriptor_heap *heap);
+void d3d12_device_untrack_descriptor_heap(struct d3d12_device *device, const struct d3d12_descriptor_heap *heap);
+uint32_t d3d12_device_descriptor_heap_size_from_descriptor(struct d3d12_device *device,
+ const struct d3d12_desc *desc);
+
static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object)
{
return ID3D12Device_QueryInterface(&device->ID3D12Device_iface, iid, object);
--
2.31.1
More information about the wine-devel
mailing list