mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d: Create and write descriptor sets for root signature unbounded ranges.
Signed-off-by: Conor McCarthy <cmccarthy@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d3090699c5
commit
104626cc1d
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 2016 Józef Kucia for CodeWeavers
|
||||
* Copyright 2016 Henri Verbeet for CodeWeavers
|
||||
* Copyright 2021 Conor McCarthy for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -1363,10 +1364,12 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
|
||||
}
|
||||
|
||||
static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(
|
||||
struct d3d12_command_allocator *allocator, VkDescriptorSetLayout vk_set_layout)
|
||||
struct d3d12_command_allocator *allocator, VkDescriptorSetLayout vk_set_layout,
|
||||
unsigned int variable_binding_size, bool unbounded)
|
||||
{
|
||||
struct d3d12_device *device = allocator->device;
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
VkDescriptorSetVariableDescriptorCountAllocateInfoEXT set_size;
|
||||
struct VkDescriptorSetAllocateInfo set_desc;
|
||||
VkDevice vk_device = device->vk_device;
|
||||
VkDescriptorSet vk_descriptor_set;
|
||||
@ -1382,6 +1385,14 @@ static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(
|
||||
set_desc.descriptorPool = allocator->vk_descriptor_pool;
|
||||
set_desc.descriptorSetCount = 1;
|
||||
set_desc.pSetLayouts = &vk_set_layout;
|
||||
if (unbounded)
|
||||
{
|
||||
set_desc.pNext = &set_size;
|
||||
set_size.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT;
|
||||
set_size.pNext = NULL;
|
||||
set_size.descriptorSetCount = 1;
|
||||
set_size.pDescriptorCounts = &variable_binding_size;
|
||||
}
|
||||
if ((vr = VK_CALL(vkAllocateDescriptorSets(vk_device, &set_desc, &vk_descriptor_set))) >= 0)
|
||||
return vk_descriptor_set;
|
||||
|
||||
@ -2562,7 +2573,12 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li
|
||||
enum vkd3d_pipeline_bind_point bind_point)
|
||||
{
|
||||
struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
|
||||
unsigned int variable_binding_size, unbounded_offset, table_index, heap_size, i;
|
||||
const struct d3d12_root_signature *root_signature = bindings->root_signature;
|
||||
const struct d3d12_descriptor_set_layout *layout;
|
||||
struct d3d12_device *device = list->device;
|
||||
const struct d3d12_desc *base_descriptor;
|
||||
VkDescriptorSet vk_descriptor_set;
|
||||
|
||||
if (bindings->descriptor_set_count && !bindings->in_use)
|
||||
return;
|
||||
@ -2579,9 +2595,33 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li
|
||||
* by an update command, or freed) between when the command is recorded
|
||||
* and when the command completes executing on the queue."
|
||||
*/
|
||||
bindings->descriptor_sets[0] = d3d12_command_allocator_allocate_descriptor_set(list->allocator,
|
||||
root_signature->vk_set_layouts[root_signature->main_set]);
|
||||
bindings->descriptor_set_count = 1;
|
||||
bindings->descriptor_set_count = 0;
|
||||
for (i = root_signature->main_set; i < root_signature->vk_set_count; ++i)
|
||||
{
|
||||
layout = &root_signature->descriptor_set_layouts[i];
|
||||
unbounded_offset = layout->unbounded_offset;
|
||||
table_index = layout->table_index;
|
||||
variable_binding_size = 0;
|
||||
|
||||
if (unbounded_offset != UINT_MAX
|
||||
/* Descriptors may not be set, eg. WoW. */
|
||||
&& (base_descriptor = d3d12_desc_from_gpu_handle(bindings->descriptor_tables[table_index])))
|
||||
{
|
||||
heap_size = vkd3d_gpu_descriptor_allocator_range_size_from_descriptor(
|
||||
&device->gpu_descriptor_allocator, base_descriptor);
|
||||
|
||||
if (heap_size < unbounded_offset)
|
||||
WARN("Descriptor heap size %u is less than the offset %u of an unbounded range in table %u, "
|
||||
"vk set %u.\n", heap_size, unbounded_offset, table_index, i);
|
||||
else
|
||||
variable_binding_size = heap_size - unbounded_offset;
|
||||
}
|
||||
|
||||
vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator,
|
||||
layout->vk_layout, variable_binding_size, unbounded_offset != UINT_MAX);
|
||||
bindings->descriptor_sets[bindings->descriptor_set_count++] = vk_descriptor_set;
|
||||
}
|
||||
|
||||
bindings->in_use = false;
|
||||
|
||||
bindings->descriptor_table_dirty_mask |= bindings->descriptor_table_active_mask & root_signature->descriptor_table_mask;
|
||||
@ -2596,13 +2636,14 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des
|
||||
uint32_t descriptor_range_magic = range->descriptor_magic;
|
||||
const struct vkd3d_view *view = descriptor->u.view;
|
||||
uint32_t vk_binding = range->binding;
|
||||
uint32_t set = range->set;
|
||||
|
||||
if (descriptor->magic != descriptor_range_magic)
|
||||
return false;
|
||||
|
||||
vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
vk_descriptor_write->pNext = NULL;
|
||||
vk_descriptor_write->dstSet = vk_descriptor_sets[0];
|
||||
vk_descriptor_write->dstSet = vk_descriptor_sets[set];
|
||||
vk_descriptor_write->dstBinding = use_array ? vk_binding : vk_binding + index;
|
||||
vk_descriptor_write->dstArrayElement = use_array ? index : 0;
|
||||
vk_descriptor_write->descriptorCount = 1;
|
||||
@ -2620,12 +2661,26 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des
|
||||
case VKD3D_DESCRIPTOR_MAGIC_SRV:
|
||||
case VKD3D_DESCRIPTOR_MAGIC_UAV:
|
||||
/* We use separate bindings for buffer and texture SRVs/UAVs.
|
||||
* See d3d12_root_signature_init(). */
|
||||
if (!use_array)
|
||||
vk_descriptor_write->dstBinding = vk_binding + 2 * index;
|
||||
if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|
||||
&& descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
||||
++vk_descriptor_write->dstBinding;
|
||||
* See d3d12_root_signature_init(). For unbounded ranges the
|
||||
* descriptors exist in two consecutive sets, otherwise they occur
|
||||
* in pairs in one set. */
|
||||
if (range->descriptor_count == UINT_MAX)
|
||||
{
|
||||
if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|
||||
&& descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
||||
{
|
||||
vk_descriptor_write->dstSet = vk_descriptor_sets[set + 1];
|
||||
vk_descriptor_write->dstBinding = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use_array)
|
||||
vk_descriptor_write->dstBinding = vk_binding + 2 * index;
|
||||
if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|
||||
&& descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
||||
++vk_descriptor_write->dstBinding;
|
||||
}
|
||||
|
||||
if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|
||||
|| descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
||||
@ -2673,19 +2728,38 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
|
||||
VkDevice vk_device = list->device->vk_device;
|
||||
unsigned int i, j, k, descriptor_count;
|
||||
struct d3d12_desc *descriptor;
|
||||
unsigned int write_count = 0;
|
||||
bool unbounded = false;
|
||||
|
||||
descriptor_table = root_signature_get_descriptor_table(root_signature, index);
|
||||
|
||||
descriptor_count = 0;
|
||||
current_descriptor_write = descriptor_writes;
|
||||
current_image_info = image_infos;
|
||||
for (i = 0; i < descriptor_table->range_count; ++i)
|
||||
{
|
||||
range = &descriptor_table->ranges[i];
|
||||
|
||||
/* The first unbounded range of each type is written until the heap end is reached. Do not repeat. */
|
||||
if (unbounded && i && range->type == descriptor_table->ranges[i - 1].type)
|
||||
continue;
|
||||
|
||||
descriptor = base_descriptor + range->offset;
|
||||
|
||||
for (j = 0; j < range->descriptor_count; ++j, ++descriptor)
|
||||
descriptor_count = range->descriptor_count;
|
||||
if ((unbounded = descriptor_count == UINT_MAX))
|
||||
{
|
||||
descriptor_count = vkd3d_gpu_descriptor_allocator_range_size_from_descriptor(
|
||||
&list->device->gpu_descriptor_allocator, descriptor);
|
||||
|
||||
if (descriptor_count > range->vk_binding_count)
|
||||
{
|
||||
ERR("Heap descriptor count %u exceeds maximum Vulkan count %u. Reducing to the Vulkan maximum.\n",
|
||||
descriptor_count, range->vk_binding_count);
|
||||
descriptor_count = range->vk_binding_count;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < descriptor_count; ++j, ++descriptor)
|
||||
{
|
||||
unsigned int register_idx = range->base_register_idx + j;
|
||||
|
||||
@ -2707,25 +2781,29 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
|
||||
}
|
||||
}
|
||||
|
||||
/* Not all descriptors are necessarily populated if the range is unbounded. */
|
||||
if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_FREE)
|
||||
continue;
|
||||
|
||||
if (!vk_write_descriptor_set_from_d3d12_desc(current_descriptor_write, current_image_info,
|
||||
descriptor, range, bindings->descriptor_sets, j, root_signature->use_descriptor_arrays))
|
||||
continue;
|
||||
|
||||
++descriptor_count;
|
||||
++write_count;
|
||||
++current_descriptor_write;
|
||||
++current_image_info;
|
||||
|
||||
if (descriptor_count == ARRAY_SIZE(descriptor_writes))
|
||||
if (write_count == ARRAY_SIZE(descriptor_writes))
|
||||
{
|
||||
VK_CALL(vkUpdateDescriptorSets(vk_device, descriptor_count, descriptor_writes, 0, NULL));
|
||||
descriptor_count = 0;
|
||||
VK_CALL(vkUpdateDescriptorSets(vk_device, write_count, descriptor_writes, 0, NULL));
|
||||
write_count = 0;
|
||||
current_descriptor_write = descriptor_writes;
|
||||
current_image_info = image_infos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VK_CALL(vkUpdateDescriptorSets(vk_device, descriptor_count, descriptor_writes, 0, NULL));
|
||||
VK_CALL(vkUpdateDescriptorSets(vk_device, write_count, descriptor_writes, 0, NULL));
|
||||
}
|
||||
|
||||
static bool vk_write_descriptor_set_from_root_descriptor(VkWriteDescriptorSet *vk_descriptor_write,
|
||||
@ -2850,8 +2928,8 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
|
||||
uav_counter_count = state->uav_counters.binding_count;
|
||||
if (!(vk_descriptor_writes = vkd3d_calloc(uav_counter_count, sizeof(*vk_descriptor_writes))))
|
||||
return;
|
||||
if (!(vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator,
|
||||
state->uav_counters.vk_set_layout)))
|
||||
if (!(vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(
|
||||
list->allocator, state->uav_counters.vk_set_layout, 0, false)))
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < uav_counter_count; ++i)
|
||||
@ -4946,7 +5024,7 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list,
|
||||
}
|
||||
|
||||
if (!(write_set.dstSet = d3d12_command_allocator_allocate_descriptor_set(
|
||||
list->allocator, pipeline.vk_set_layout)))
|
||||
list->allocator, pipeline.vk_set_layout, 0, false)))
|
||||
{
|
||||
ERR("Failed to allocate descriptor set.\n");
|
||||
return;
|
||||
|
@ -2173,6 +2173,118 @@ static void vkd3d_gpu_va_allocator_cleanup(struct vkd3d_gpu_va_allocator *alloca
|
||||
pthread_mutex_destroy(&allocator->mutex);
|
||||
}
|
||||
|
||||
bool vkd3d_gpu_descriptor_allocator_register_range(struct vkd3d_gpu_descriptor_allocator *allocator,
|
||||
const struct d3d12_desc *base, size_t count)
|
||||
{
|
||||
struct vkd3d_gpu_descriptor_allocation *allocation;
|
||||
int rc;
|
||||
|
||||
if ((rc = pthread_mutex_lock(&allocator->mutex)))
|
||||
{
|
||||
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vkd3d_array_reserve((void **)&allocator->allocations, &allocator->allocations_size,
|
||||
allocator->allocation_count + 1, sizeof(*allocator->allocations)))
|
||||
{
|
||||
pthread_mutex_unlock(&allocator->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
allocation = &allocator->allocations[allocator->allocation_count++];
|
||||
allocation->base = base;
|
||||
allocation->count = count;
|
||||
|
||||
pthread_mutex_unlock(&allocator->mutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vkd3d_gpu_descriptor_allocator_unregister_range(
|
||||
struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *base)
|
||||
{
|
||||
bool found;
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
if ((rc = pthread_mutex_lock(&allocator->mutex)))
|
||||
{
|
||||
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0, found = false; i < allocator->allocation_count; ++i)
|
||||
{
|
||||
if (allocator->allocations[i].base != base)
|
||||
continue;
|
||||
|
||||
if (i != --allocator->allocation_count)
|
||||
allocator->allocations[i] = allocator->allocations[allocator->allocation_count];
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&allocator->mutex);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/* Return the available size from the specified descriptor to the heap end. */
|
||||
size_t vkd3d_gpu_descriptor_allocator_range_size_from_descriptor(
|
||||
struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc)
|
||||
{
|
||||
struct vkd3d_gpu_descriptor_allocation *allocation;
|
||||
size_t remaining, offset, i;
|
||||
int rc;
|
||||
|
||||
if ((rc = pthread_mutex_lock(&allocator->mutex)))
|
||||
{
|
||||
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0, remaining = 0; i < allocator->allocation_count; ++i)
|
||||
{
|
||||
allocation = &allocator->allocations[i];
|
||||
|
||||
if (desc < allocation->base)
|
||||
continue;
|
||||
|
||||
offset = desc - allocation->base;
|
||||
if (offset >= allocation->count)
|
||||
continue;
|
||||
|
||||
remaining = allocation->count - offset;
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&allocator->mutex);
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
static bool vkd3d_gpu_descriptor_allocator_init(struct vkd3d_gpu_descriptor_allocator *allocator)
|
||||
{
|
||||
int rc;
|
||||
|
||||
memset(allocator, 0, sizeof(*allocator));
|
||||
if ((rc = pthread_mutex_init(&allocator->mutex, NULL)))
|
||||
{
|
||||
ERR("Failed to initialise mutex, error %d.\n", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void vkd3d_gpu_descriptor_allocator_cleanup(struct vkd3d_gpu_descriptor_allocator *allocator)
|
||||
{
|
||||
vkd3d_free(allocator->allocations);
|
||||
pthread_mutex_destroy(&allocator->mutex);
|
||||
}
|
||||
|
||||
/* ID3D12Device */
|
||||
static inline struct d3d12_device *impl_from_ID3D12Device(ID3D12Device *iface)
|
||||
{
|
||||
@ -2227,6 +2339,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
|
||||
vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device);
|
||||
vkd3d_destroy_null_resources(&device->null_resources, device);
|
||||
vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator);
|
||||
vkd3d_gpu_descriptor_allocator_cleanup(&device->gpu_descriptor_allocator);
|
||||
vkd3d_render_pass_cache_cleanup(&device->render_pass_cache, device);
|
||||
vkd3d_fence_worker_stop(&device->fence_worker, device);
|
||||
d3d12_device_destroy_pipeline_cache(device);
|
||||
@ -3729,6 +3842,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
|
||||
goto out_destroy_null_resources;
|
||||
|
||||
vkd3d_render_pass_cache_init(&device->render_pass_cache);
|
||||
vkd3d_gpu_descriptor_allocator_init(&device->gpu_descriptor_allocator);
|
||||
vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(device->desc_mutex); ++i)
|
||||
|
@ -3351,6 +3351,10 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea
|
||||
{
|
||||
d3d12_desc_destroy(&descriptors[i], device);
|
||||
}
|
||||
|
||||
if (device->vk_info.EXT_descriptor_indexing && !vkd3d_gpu_descriptor_allocator_unregister_range(
|
||||
&device->gpu_descriptor_allocator, descriptors))
|
||||
ERR("Failed to unregister descriptor range.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3547,6 +3551,11 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
|
||||
|
||||
memset(object->descriptors, 0, descriptor_size * desc->NumDescriptors);
|
||||
|
||||
if ((desc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || desc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)
|
||||
&& device->vk_info.EXT_descriptor_indexing && !vkd3d_gpu_descriptor_allocator_register_range(
|
||||
&device->gpu_descriptor_allocator, (struct d3d12_desc *)object->descriptors, desc->NumDescriptors))
|
||||
ERR("Failed to register descriptor range.\n");
|
||||
|
||||
TRACE("Created descriptor heap %p.\n", object);
|
||||
|
||||
*descriptor_heap = object;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 2016 Józef Kucia for CodeWeavers
|
||||
* Copyright 2016 Henri Verbeet for CodeWeavers
|
||||
* Copyright 2021 Conor McCarthy for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -57,6 +58,14 @@ static ULONG STDMETHODCALLTYPE d3d12_root_signature_AddRef(ID3D12RootSignature *
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static void d3d12_descriptor_set_layout_cleanup(
|
||||
struct d3d12_descriptor_set_layout *layout, struct d3d12_device *device)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
|
||||
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, layout->vk_layout, NULL));
|
||||
}
|
||||
|
||||
static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signature,
|
||||
struct d3d12_device *device)
|
||||
{
|
||||
@ -66,7 +75,9 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa
|
||||
if (root_signature->vk_pipeline_layout)
|
||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, root_signature->vk_pipeline_layout, NULL));
|
||||
for (i = 0; i < root_signature->vk_set_count; ++i)
|
||||
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layouts[i], NULL));
|
||||
{
|
||||
d3d12_descriptor_set_layout_cleanup(&root_signature->descriptor_set_layouts[i], device);
|
||||
}
|
||||
|
||||
if (root_signature->parameters)
|
||||
{
|
||||
@ -370,10 +381,10 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig
|
||||
info->binding_count += binding_count;
|
||||
}
|
||||
|
||||
if (unbounded)
|
||||
if (unbounded && !use_array)
|
||||
{
|
||||
FIXME("Unhandled unbounded descriptor range.\n");
|
||||
return E_NOTIMPL;
|
||||
FIXME("The device does not support unbounded descriptor ranges.\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@ -526,6 +537,8 @@ struct vkd3d_descriptor_set_context
|
||||
{
|
||||
VkDescriptorSetLayoutBinding *current_binding;
|
||||
VkDescriptorSetLayoutBinding *first_binding;
|
||||
unsigned int table_index;
|
||||
unsigned int unbounded_offset;
|
||||
unsigned int descriptor_index;
|
||||
uint32_t descriptor_binding;
|
||||
};
|
||||
@ -544,24 +557,30 @@ static bool vkd3d_validate_descriptor_set_count(struct d3d12_device *device, uns
|
||||
}
|
||||
|
||||
static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
|
||||
VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count,
|
||||
VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count, bool unbounded,
|
||||
const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout);
|
||||
|
||||
static HRESULT d3d12_root_signature_append_descriptor_set_layout(struct d3d12_root_signature *root_signature,
|
||||
struct vkd3d_descriptor_set_context *context, VkDescriptorSetLayoutCreateFlags flags)
|
||||
{
|
||||
struct d3d12_descriptor_set_layout *layout;
|
||||
unsigned int index;
|
||||
HRESULT hr;
|
||||
|
||||
if (!context->descriptor_binding)
|
||||
return S_OK;
|
||||
|
||||
if (!vkd3d_validate_descriptor_set_count(root_signature->device, root_signature->vk_set_count + 1))
|
||||
index = root_signature->vk_set_count;
|
||||
layout = &root_signature->descriptor_set_layouts[index];
|
||||
|
||||
if (!vkd3d_validate_descriptor_set_count(root_signature->device, index + 1))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (FAILED(hr = vkd3d_create_descriptor_set_layout(root_signature->device,
|
||||
flags, context->descriptor_binding, context->first_binding,
|
||||
&root_signature->vk_set_layouts[root_signature->vk_set_count])))
|
||||
if (FAILED(hr = vkd3d_create_descriptor_set_layout(root_signature->device, flags, context->descriptor_binding,
|
||||
context->unbounded_offset != UINT_MAX, context->first_binding, &layout->vk_layout)))
|
||||
return hr;
|
||||
layout->table_index = context->table_index;
|
||||
layout->unbounded_offset = context->unbounded_offset;
|
||||
++root_signature->vk_set_count;
|
||||
|
||||
context->current_binding = context->first_binding;
|
||||
@ -586,6 +605,9 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
|
||||
mapping->binding.set = root_signature->vk_set_count;
|
||||
mapping->binding.binding = context->descriptor_binding++;
|
||||
mapping->binding.count = descriptor_count;
|
||||
|
||||
if (context->unbounded_offset != UINT_MAX)
|
||||
d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0);
|
||||
}
|
||||
|
||||
static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature,
|
||||
@ -632,6 +654,16 @@ static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE ty
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int vk_binding_count_from_descriptor_range(const struct d3d12_root_descriptor_table_range *range)
|
||||
{
|
||||
if (range->descriptor_count != UINT_MAX)
|
||||
return range->descriptor_count;
|
||||
|
||||
/* TODO: Calculate an upper bound from unbounded set counts and Vulkan
|
||||
* device limits. */
|
||||
return 1024;
|
||||
}
|
||||
|
||||
static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_root_signature *root_signature,
|
||||
const struct d3d12_root_descriptor_table_range *range, D3D12_SHADER_VISIBILITY visibility,
|
||||
struct vkd3d_descriptor_set_context *context)
|
||||
@ -640,28 +672,62 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r
|
||||
bool is_buffer = range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
|
||||
enum vkd3d_shader_descriptor_type descriptor_type = range->type;
|
||||
|
||||
if (range->descriptor_count == UINT_MAX)
|
||||
context->unbounded_offset = range->offset;
|
||||
|
||||
if (descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
|
||||
{
|
||||
if (!vk_binding_from_d3d12_descriptor_range(context->current_binding,
|
||||
descriptor_type, visibility, true, context->descriptor_binding, range->descriptor_count))
|
||||
descriptor_type, visibility, true, context->descriptor_binding, range->vk_binding_count))
|
||||
return E_NOTIMPL;
|
||||
++context->current_binding;
|
||||
|
||||
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space,
|
||||
range->base_register_idx, true, shader_visibility, range->descriptor_count, context);
|
||||
range->base_register_idx, true, shader_visibility, range->vk_binding_count, context);
|
||||
}
|
||||
|
||||
if (!vk_binding_from_d3d12_descriptor_range(context->current_binding,
|
||||
descriptor_type, visibility, is_buffer, context->descriptor_binding, range->descriptor_count))
|
||||
descriptor_type, visibility, is_buffer, context->descriptor_binding, range->vk_binding_count))
|
||||
return E_NOTIMPL;
|
||||
++context->current_binding;
|
||||
|
||||
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space,
|
||||
range->base_register_idx, is_buffer, shader_visibility, range->descriptor_count, context);
|
||||
range->base_register_idx, is_buffer, shader_visibility, range->vk_binding_count, context);
|
||||
|
||||
context->unbounded_offset = UINT_MAX;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void d3d12_root_signature_map_vk_unbounded_binding(struct d3d12_root_signature *root_signature,
|
||||
const struct d3d12_root_descriptor_table_range *range, bool buffer_descriptor,
|
||||
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context)
|
||||
{
|
||||
struct vkd3d_shader_resource_binding *mapping = &root_signature->descriptor_mapping[context->descriptor_index++];
|
||||
|
||||
mapping->type = range->type;
|
||||
mapping->register_space = range->register_space;
|
||||
mapping->register_index = range->base_register_idx;
|
||||
mapping->shader_visibility = shader_visibility;
|
||||
mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
|
||||
mapping->binding.set = root_signature->main_set + range->set + ((range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
|
||||
|| range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) && !buffer_descriptor);
|
||||
mapping->binding.binding = range->binding;
|
||||
mapping->binding.count = range->vk_binding_count;
|
||||
}
|
||||
|
||||
static void d3d12_root_signature_map_descriptor_unbounded_binding(struct d3d12_root_signature *root_signature,
|
||||
const struct d3d12_root_descriptor_table_range *range,
|
||||
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context)
|
||||
{
|
||||
bool is_buffer = range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
|
||||
|
||||
if (range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
|
||||
d3d12_root_signature_map_vk_unbounded_binding(root_signature, range, true, shader_visibility, context);
|
||||
|
||||
d3d12_root_signature_map_vk_unbounded_binding(root_signature, range, is_buffer, shader_visibility, context);
|
||||
}
|
||||
|
||||
static int compare_register_range(const void *a, const void *b)
|
||||
{
|
||||
const struct d3d12_root_descriptor_table_range *range_a = a, *range_b = b;
|
||||
@ -676,6 +742,20 @@ static int compare_register_range(const void *a, const void *b)
|
||||
return range_a->base_register_idx - range_b->base_register_idx;
|
||||
}
|
||||
|
||||
static int compare_descriptor_range(const void *a, const void *b)
|
||||
{
|
||||
const struct d3d12_root_descriptor_table_range *range_a = a, *range_b = b;
|
||||
int ret;
|
||||
|
||||
if ((ret = range_a->type - range_b->type))
|
||||
return ret;
|
||||
|
||||
if ((ret = range_a->offset - range_b->offset))
|
||||
return ret;
|
||||
|
||||
return (range_a->descriptor_count == UINT_MAX) - (range_b->descriptor_count == UINT_MAX);
|
||||
}
|
||||
|
||||
static HRESULT validate_descriptor_register_ranges(const struct d3d12_root_descriptor_table_range *ranges,
|
||||
unsigned int count)
|
||||
{
|
||||
@ -707,6 +787,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
|
||||
|
||||
for (i = 0; i < desc->NumParameters; ++i)
|
||||
{
|
||||
const struct d3d12_root_descriptor_table_range *base_range = NULL;
|
||||
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
|
||||
enum vkd3d_shader_visibility shader_visibility;
|
||||
unsigned int offset = 0;
|
||||
@ -725,6 +806,8 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
|
||||
if (!(table->ranges = vkd3d_calloc(table->range_count, sizeof(*table->ranges))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
context->table_index = i;
|
||||
|
||||
for (j = 0; j < range_count; ++j)
|
||||
{
|
||||
const D3D12_DESCRIPTOR_RANGE *range = &p->u.DescriptorTable.pDescriptorRanges[j];
|
||||
@ -732,7 +815,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
|
||||
if (range->OffsetInDescriptorsFromTableStart != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
|
||||
offset = range->OffsetInDescriptorsFromTableStart;
|
||||
|
||||
if (!vkd3d_bound_range(offset, range->NumDescriptors, UINT_MAX))
|
||||
if (range->NumDescriptors != UINT_MAX && !vkd3d_bound_range(offset, range->NumDescriptors, UINT_MAX))
|
||||
return E_INVALIDARG;
|
||||
|
||||
table->ranges[j].offset = offset;
|
||||
@ -745,6 +828,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
|
||||
TRACE("Descriptor table %u, range %u, offset %u, type %#x, count %u.\n", i, j,
|
||||
offset, range->RangeType, range->NumDescriptors);
|
||||
|
||||
/* If NumDescriptors == UINT_MAX, validation during counting ensures this offset is not used. */
|
||||
offset += range->NumDescriptors;
|
||||
}
|
||||
|
||||
@ -752,15 +836,49 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
|
||||
if (FAILED(hr = validate_descriptor_register_ranges(table->ranges, range_count)))
|
||||
return hr;
|
||||
|
||||
qsort(table->ranges, range_count, sizeof(*table->ranges), compare_descriptor_range);
|
||||
|
||||
for (j = 0; j < range_count; ++j)
|
||||
{
|
||||
struct d3d12_root_descriptor_table_range *range;
|
||||
VkDescriptorSetLayoutBinding *cur_binding;
|
||||
|
||||
range = &table->ranges[j];
|
||||
|
||||
range->set = root_signature->vk_set_count - root_signature->main_set;
|
||||
|
||||
if (root_signature->use_descriptor_arrays)
|
||||
{
|
||||
if (j && range->type != table->ranges[j - 1].type)
|
||||
base_range = NULL;
|
||||
|
||||
/* Bounded and unbounded ranges can follow unbounded ones,
|
||||
* so map them all into the first unbounded range. */
|
||||
if (base_range)
|
||||
{
|
||||
unsigned int rel_offset = range->offset - base_range->offset;
|
||||
|
||||
if (rel_offset >= base_range->vk_binding_count)
|
||||
{
|
||||
ERR("Available binding size of %u is insufficient for an offset of %u.\n",
|
||||
base_range->vk_binding_count, rel_offset);
|
||||
continue;
|
||||
}
|
||||
|
||||
range->set = base_range->set;
|
||||
range->binding = base_range->binding;
|
||||
range->vk_binding_count = base_range->vk_binding_count - rel_offset;
|
||||
d3d12_root_signature_map_descriptor_unbounded_binding(root_signature, range,
|
||||
shader_visibility, context);
|
||||
continue;
|
||||
}
|
||||
else if (range->descriptor_count == UINT_MAX)
|
||||
{
|
||||
base_range = range;
|
||||
}
|
||||
|
||||
range->binding = context->descriptor_binding;
|
||||
range->vk_binding_count = vk_binding_count_from_descriptor_range(range);
|
||||
|
||||
if (FAILED(hr = d3d12_root_signature_init_descriptor_array_binding(root_signature,
|
||||
range, p->ShaderVisibility, context)))
|
||||
@ -800,6 +918,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
|
||||
++cur_binding;
|
||||
}
|
||||
|
||||
table->ranges[j].vk_binding_count = table->ranges[j].descriptor_count;
|
||||
table->ranges[j].binding = vk_binding;
|
||||
|
||||
context->current_binding = cur_binding;
|
||||
@ -897,7 +1016,7 @@ static bool vk_binding_uses_partial_binding(const VkDescriptorSetLayoutBinding *
|
||||
}
|
||||
|
||||
static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
|
||||
VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count,
|
||||
VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count, bool unbounded,
|
||||
const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
@ -916,7 +1035,7 @@ static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < binding_count; ++i)
|
||||
if (vk_binding_uses_partial_binding(&bindings[i]))
|
||||
if (unbounded || vk_binding_uses_partial_binding(&bindings[i]))
|
||||
break;
|
||||
|
||||
if (i < binding_count)
|
||||
@ -928,6 +1047,10 @@ static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
|
||||
set_flags[i] = vk_binding_uses_partial_binding(&bindings[i])
|
||||
? VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT : 0;
|
||||
|
||||
if (unbounded)
|
||||
set_flags[binding_count - 1] = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT
|
||||
| VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT;
|
||||
|
||||
flags_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
|
||||
flags_info.pNext = NULL;
|
||||
flags_info.bindingCount = binding_count;
|
||||
@ -957,6 +1080,9 @@ static HRESULT vkd3d_create_pipeline_layout(struct d3d12_device *device,
|
||||
struct VkPipelineLayoutCreateInfo pipeline_layout_info;
|
||||
VkResult vr;
|
||||
|
||||
if (!vkd3d_validate_descriptor_set_count(device, set_layout_count))
|
||||
return E_INVALIDARG;
|
||||
|
||||
pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
pipeline_layout_info.pNext = NULL;
|
||||
pipeline_layout_info.flags = 0;
|
||||
@ -977,13 +1103,16 @@ static HRESULT vkd3d_create_pipeline_layout(struct d3d12_device *device,
|
||||
static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signature,
|
||||
struct d3d12_device *device, const D3D12_ROOT_SIGNATURE_DESC *desc)
|
||||
{
|
||||
VkDescriptorSetLayout vk_layouts[VKD3D_MAX_DESCRIPTOR_SETS];
|
||||
const struct vkd3d_vulkan_info *vk_info = &device->vk_info;
|
||||
struct vkd3d_descriptor_set_context context;
|
||||
VkDescriptorSetLayoutBinding *binding_desc;
|
||||
struct d3d12_root_signature_info info;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.unbounded_offset = UINT_MAX;
|
||||
binding_desc = NULL;
|
||||
|
||||
root_signature->ID3D12RootSignature_iface.lpVtbl = &d3d12_root_signature_vtbl;
|
||||
@ -1047,6 +1176,8 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
goto fail;
|
||||
}
|
||||
|
||||
root_signature->main_set = root_signature->vk_set_count;
|
||||
|
||||
if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc,
|
||||
root_signature->push_constant_ranges, &root_signature->push_constant_range_count)))
|
||||
goto fail;
|
||||
@ -1055,16 +1186,19 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &context)))
|
||||
goto fail;
|
||||
|
||||
root_signature->main_set = root_signature->vk_set_count;
|
||||
|
||||
if (FAILED(hr = d3d12_root_signature_append_descriptor_set_layout(root_signature, &context, 0)))
|
||||
goto fail;
|
||||
|
||||
vkd3d_free(binding_desc);
|
||||
binding_desc = NULL;
|
||||
|
||||
for (i = 0; i < root_signature->vk_set_count; ++i)
|
||||
{
|
||||
vk_layouts[i] = root_signature->descriptor_set_layouts[i].vk_layout;
|
||||
}
|
||||
|
||||
if (FAILED(hr = vkd3d_create_pipeline_layout(device, root_signature->vk_set_count,
|
||||
root_signature->vk_set_layouts, root_signature->push_constant_range_count,
|
||||
vk_layouts, root_signature->push_constant_range_count,
|
||||
root_signature->push_constant_ranges, &root_signature->vk_pipeline_layout)))
|
||||
goto fail;
|
||||
|
||||
@ -1670,7 +1804,7 @@ static HRESULT d3d12_pipeline_state_init_uav_counters(struct d3d12_pipeline_stat
|
||||
|
||||
descriptor_binding = 0;
|
||||
for (set_index = 0; set_index < root_signature->vk_set_count; ++set_index)
|
||||
set_layouts[set_index] = root_signature->vk_set_layouts[set_index];
|
||||
set_layouts[set_index] = root_signature->descriptor_set_layouts[set_index].vk_layout;
|
||||
|
||||
for (i = 0, j = 0; i < shader_info->descriptor_count; ++i)
|
||||
{
|
||||
@ -1699,8 +1833,8 @@ static HRESULT d3d12_pipeline_state_init_uav_counters(struct d3d12_pipeline_stat
|
||||
}
|
||||
|
||||
/* Create a descriptor set layout for UAV counters. */
|
||||
hr = vkd3d_create_descriptor_set_layout(device,
|
||||
0, descriptor_binding, binding_desc, &state->uav_counters.vk_set_layout);
|
||||
hr = vkd3d_create_descriptor_set_layout(device, 0, descriptor_binding,
|
||||
false, binding_desc, &state->uav_counters.vk_set_layout);
|
||||
vkd3d_free(binding_desc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@ -3196,7 +3330,8 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
|
||||
{
|
||||
set_binding.descriptorType = set_layouts[i].descriptor_type;
|
||||
|
||||
if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, 0, 1, &set_binding, set_layouts[i].set_layout)))
|
||||
if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, 0,
|
||||
1, false, &set_binding, set_layouts[i].set_layout)))
|
||||
{
|
||||
ERR("Failed to create descriptor set layout %u, hr %#x.\n", i, hr);
|
||||
goto fail;
|
||||
|
@ -54,7 +54,7 @@
|
||||
#define VKD3D_MAX_SHADER_EXTENSIONS 2u
|
||||
#define VKD3D_MAX_SHADER_STAGES 5u
|
||||
#define VKD3D_MAX_VK_SYNC_OBJECTS 4u
|
||||
#define VKD3D_MAX_DESCRIPTOR_SETS 2u
|
||||
#define VKD3D_MAX_DESCRIPTOR_SETS 64u
|
||||
|
||||
struct d3d12_command_list;
|
||||
struct d3d12_device;
|
||||
@ -234,6 +234,28 @@ D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_al
|
||||
void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address);
|
||||
void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address);
|
||||
|
||||
struct vkd3d_gpu_descriptor_allocation
|
||||
{
|
||||
const struct d3d12_desc *base;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
struct vkd3d_gpu_descriptor_allocator
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
struct vkd3d_gpu_descriptor_allocation *allocations;
|
||||
size_t allocations_size;
|
||||
size_t allocation_count;
|
||||
};
|
||||
|
||||
size_t vkd3d_gpu_descriptor_allocator_range_size_from_descriptor(
|
||||
struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc);
|
||||
bool vkd3d_gpu_descriptor_allocator_register_range(struct vkd3d_gpu_descriptor_allocator *allocator,
|
||||
const struct d3d12_desc *base, size_t count);
|
||||
bool vkd3d_gpu_descriptor_allocator_unregister_range(
|
||||
struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *base);
|
||||
|
||||
struct vkd3d_render_pass_key
|
||||
{
|
||||
unsigned int attachment_count;
|
||||
@ -647,6 +669,8 @@ struct d3d12_root_descriptor_table_range
|
||||
{
|
||||
unsigned int offset;
|
||||
unsigned int descriptor_count;
|
||||
unsigned int vk_binding_count;
|
||||
uint32_t set;
|
||||
uint32_t binding;
|
||||
|
||||
enum vkd3d_shader_descriptor_type type;
|
||||
@ -683,6 +707,13 @@ struct d3d12_root_parameter
|
||||
} u;
|
||||
};
|
||||
|
||||
struct d3d12_descriptor_set_layout
|
||||
{
|
||||
VkDescriptorSetLayout vk_layout;
|
||||
unsigned int unbounded_offset;
|
||||
unsigned int table_index;
|
||||
};
|
||||
|
||||
/* ID3D12RootSignature */
|
||||
struct d3d12_root_signature
|
||||
{
|
||||
@ -690,8 +721,8 @@ struct d3d12_root_signature
|
||||
LONG refcount;
|
||||
|
||||
VkPipelineLayout vk_pipeline_layout;
|
||||
struct d3d12_descriptor_set_layout descriptor_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS];
|
||||
uint32_t vk_set_count;
|
||||
VkDescriptorSetLayout vk_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS];
|
||||
bool use_descriptor_arrays;
|
||||
|
||||
struct d3d12_root_parameter *parameters;
|
||||
@ -912,8 +943,10 @@ struct vkd3d_pipeline_bindings
|
||||
const struct d3d12_root_signature *root_signature;
|
||||
|
||||
VkPipelineBindPoint vk_bind_point;
|
||||
/* All descriptor sets at index > 1 are for unbounded d3d12 ranges. Set
|
||||
* 0 or 1 may be unbounded too. */
|
||||
size_t descriptor_set_count;
|
||||
VkDescriptorSet descriptor_sets[VKD3D_MAX_DESCRIPTOR_SETS - 1];
|
||||
VkDescriptorSet descriptor_sets[VKD3D_MAX_DESCRIPTOR_SETS];
|
||||
bool in_use;
|
||||
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE descriptor_tables[D3D12_MAX_ROOT_COST];
|
||||
@ -1126,6 +1159,7 @@ struct d3d12_device
|
||||
PFN_vkd3d_signal_event signal_event;
|
||||
size_t wchar_size;
|
||||
|
||||
struct vkd3d_gpu_descriptor_allocator gpu_descriptor_allocator;
|
||||
struct vkd3d_gpu_va_allocator gpu_va_allocator;
|
||||
struct vkd3d_fence_worker fence_worker;
|
||||
|
||||
|
@ -2799,7 +2799,7 @@ static void test_create_root_signature(void)
|
||||
root_signature_desc.pStaticSamplers = NULL;
|
||||
root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
|
||||
hr = create_root_signature(device, &root_signature_desc, &root_signature);
|
||||
todo ok(hr == S_OK || (binding_tier == D3D12_RESOURCE_BINDING_TIER_1 && (hr == E_FAIL || hr == E_INVALIDARG)),
|
||||
ok(hr == S_OK || (binding_tier == D3D12_RESOURCE_BINDING_TIER_1 && (hr == E_FAIL || hr == E_INVALIDARG)),
|
||||
"Got unexpected hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
@ -2819,13 +2819,13 @@ static void test_create_root_signature(void)
|
||||
descriptor_ranges[1].RegisterSpace = 0;
|
||||
descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 16;
|
||||
hr = create_root_signature(device, &root_signature_desc, &root_signature);
|
||||
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
/* A bounded range overlapping an unbounded one, mapped to the same
|
||||
* register space, but a different type. */
|
||||
descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
|
||||
hr = create_root_signature(device, &root_signature_desc, &root_signature);
|
||||
todo ok(hr == S_OK || (binding_tier <= D3D12_RESOURCE_BINDING_TIER_2 && (hr == E_FAIL || hr == E_INVALIDARG)),
|
||||
ok(hr == S_OK || (binding_tier <= D3D12_RESOURCE_BINDING_TIER_2 && (hr == E_FAIL || hr == E_INVALIDARG)),
|
||||
"Got unexpected hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
@ -2838,9 +2838,7 @@ static void test_create_root_signature(void)
|
||||
descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
||||
descriptor_ranges[1].NumDescriptors = UINT_MAX;
|
||||
hr = create_root_signature(device, &root_signature_desc, &root_signature);
|
||||
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D12RootSignature_Release(root_signature);
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
/* And unbounded range overlapping a bounded one, mapped to the same
|
||||
* register space and type. */
|
||||
@ -2848,9 +2846,7 @@ static void test_create_root_signature(void)
|
||||
descriptor_ranges[1].BaseShaderRegister = 0;
|
||||
descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 15;
|
||||
hr = create_root_signature(device, &root_signature_desc, &root_signature);
|
||||
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D12RootSignature_Release(root_signature);
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
refcount = ID3D12Device_Release(device);
|
||||
ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
|
||||
@ -34925,7 +34921,6 @@ static void test_unbounded_resource_arrays(void)
|
||||
root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
|
||||
root_signature_desc.pParameters = root_parameters;
|
||||
hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
|
||||
todo
|
||||
ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto done;
|
||||
@ -34999,6 +34994,7 @@ static void test_unbounded_resource_arrays(void)
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(output_buffers[i], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
|
||||
/* Buffers at index >= 64 are aliased. */
|
||||
todo_if(i != 10 && i != 74)
|
||||
check_readback_data_uint(&rb, NULL, (i < 64 ? 63 - i : 127 - i) ^ 0x35, 0);
|
||||
release_resource_readback(&rb);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
@ -35088,7 +35084,6 @@ static void test_unbounded_samplers(void)
|
||||
root_signature_desc.pParameters = root_parameters;
|
||||
|
||||
hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
|
||||
todo
|
||||
ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto done;
|
||||
@ -35146,6 +35141,7 @@ static void test_unbounded_samplers(void)
|
||||
{
|
||||
unsigned int value = get_readback_uint(&rb, i, 0, 0);
|
||||
unsigned int expected = (i & 1) ? 100 : 10;
|
||||
todo_if(i & 1)
|
||||
ok(value == expected, "Got %u, expected %u at %u.\n", value, expected, i);
|
||||
}
|
||||
release_resource_readback(&rb);
|
||||
|
Loading…
Reference in New Issue
Block a user