diff options
-rw-r--r-- | libs/vkd3d/command.c | 97 | ||||
-rw-r--r-- | libs/vkd3d/device.c | 15 | ||||
-rw-r--r-- | libs/vkd3d/state.c | 63 | ||||
-rw-r--r-- | libs/vkd3d/vkd3d_private.h | 12 |
4 files changed, 77 insertions, 110 deletions
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 548ee121..bb784453 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1797,13 +1797,10 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1024}, {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1024}, {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1024}, - /* must be last in the array */ - {VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, 65536} }; struct d3d12_descriptor_pool_cache *cache = &allocator->descriptor_pool_caches[pool_type]; struct d3d12_device *device = allocator->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - VkDescriptorPoolInlineUniformBlockCreateInfoEXT inline_uniform_desc; VkDescriptorPoolCreateInfo pool_desc; VkDevice vk_device = device->vk_device; VkDescriptorPool vk_pool; @@ -1817,24 +1814,13 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( } else { - inline_uniform_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT; - inline_uniform_desc.pNext = NULL; - inline_uniform_desc.maxInlineUniformBlockBindings = 256; - pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_desc.pNext = &inline_uniform_desc; + pool_desc.pNext = NULL; pool_desc.flags = 0; pool_desc.maxSets = 512; pool_desc.poolSizeCount = ARRAY_SIZE(pool_sizes); pool_desc.pPoolSizes = pool_sizes; - if (!device->vk_info.EXT_inline_uniform_block || - device->vk_info.device_limits.maxPushConstantsSize >= (D3D12_MAX_ROOT_COST * sizeof(uint32_t))) - { - pool_desc.pNext = NULL; - pool_desc.poolSizeCount -= 1; - } - if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0) { ERR("Failed to create descriptor pool, vr %d.\n", vr); @@ -5293,27 +5279,25 @@ static void vk_write_descriptor_set_from_root_descriptor(struct d3d12_command_li vk_descriptor_write->pTexelBufferView = &descriptor->info.buffer_view; } -static bool vk_write_descriptor_set_and_inline_uniform_block(VkWriteDescriptorSet *vk_descriptor_write, - VkWriteDescriptorSetInlineUniformBlockEXT *vk_inline_uniform_block_write, - VkDescriptorSet vk_descriptor_set, const struct d3d12_root_signature *root_signature, - const void* data) +static void vk_write_descriptor_set_from_scratch_push_ubo(VkWriteDescriptorSet *vk_descriptor_write, + VkDescriptorBufferInfo *vk_buffer_info, + const struct vkd3d_scratch_allocation *alloc, + VkDeviceSize size, uint32_t vk_binding) { - vk_inline_uniform_block_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT; - vk_inline_uniform_block_write->pNext = NULL; - vk_inline_uniform_block_write->dataSize = root_signature->push_constant_range.size; - vk_inline_uniform_block_write->pData = data; - vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - vk_descriptor_write->pNext = vk_inline_uniform_block_write; - vk_descriptor_write->dstSet = vk_descriptor_set; - vk_descriptor_write->dstBinding = root_signature->push_constant_ubo_binding.binding; + vk_descriptor_write->pNext = NULL; + vk_descriptor_write->dstSet = VK_NULL_HANDLE; + vk_descriptor_write->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; vk_descriptor_write->dstArrayElement = 0; - vk_descriptor_write->descriptorCount = root_signature->push_constant_range.size; - vk_descriptor_write->descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT; + vk_descriptor_write->dstBinding = vk_binding; + vk_descriptor_write->descriptorCount = 1; + vk_descriptor_write->pBufferInfo = vk_buffer_info; vk_descriptor_write->pImageInfo = NULL; - vk_descriptor_write->pBufferInfo = NULL; vk_descriptor_write->pTexelBufferView = NULL; - return true; + + vk_buffer_info->buffer = alloc->buffer; + vk_buffer_info->offset = alloc->offset; + vk_buffer_info->range = size; } static void d3d12_command_list_update_descriptor_heaps(struct d3d12_command_list *list, @@ -5449,32 +5433,32 @@ static void d3d12_command_list_update_root_descriptors(struct d3d12_command_list { const struct d3d12_root_signature *root_signature = bindings->root_signature; const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; - VkWriteDescriptorSetInlineUniformBlockEXT inline_uniform_block_write; - VkWriteDescriptorSet descriptor_writes[D3D12_MAX_ROOT_COST / 2 + 2]; + VkWriteDescriptorSet descriptor_writes[D3D12_MAX_ROOT_COST / 2]; const struct vkd3d_shader_root_parameter *root_parameter; - VkDescriptorSet descriptor_set = VK_NULL_HANDLE; + union root_parameter_data *ptr_root_parameter_data; union root_parameter_data root_parameter_data; unsigned int descriptor_write_count = 0; + struct vkd3d_scratch_allocation alloc; + VkDescriptorBufferInfo buffer_info; unsigned int root_parameter_index; unsigned int va_count = 0; uint64_t dirty_push_mask; - if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_ROOT_DESCRIPTOR_SET) + if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK) { - /* Ensure that we populate all descriptors if push descriptors cannot be used */ - bindings->root_descriptor_dirty_mask |= - bindings->root_descriptor_active_mask & - (root_signature->root_descriptor_raw_va_mask | root_signature->root_descriptor_push_mask); - - descriptor_set = d3d12_command_allocator_allocate_descriptor_set( - list->allocator, root_signature->vk_root_descriptor_layout, VKD3D_DESCRIPTOR_POOL_TYPE_STATIC); + d3d12_command_allocator_allocate_scratch_memory(list->allocator, + VKD3D_SCRATCH_POOL_KIND_UNIFORM_UPLOAD, sizeof(root_parameter_data), + D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, ~0u, &alloc); + ptr_root_parameter_data = alloc.host_ptr; } + else + ptr_root_parameter_data = &root_parameter_data; if (bindings->root_descriptor_dirty_mask) { /* If any raw VA descriptor is dirty, we need to update all of them. */ if (root_signature->root_descriptor_raw_va_mask & bindings->root_descriptor_dirty_mask) - va_count = d3d12_command_list_fetch_root_descriptor_vas(list, bindings, &root_parameter_data); + va_count = d3d12_command_list_fetch_root_descriptor_vas(list, bindings, ptr_root_parameter_data); /* TODO bind null descriptors for inactive root descriptors. */ dirty_push_mask = @@ -5489,7 +5473,7 @@ static void d3d12_command_list_update_root_descriptors(struct d3d12_command_list vk_write_descriptor_set_from_root_descriptor(list, &descriptor_writes[descriptor_write_count], root_parameter, - descriptor_set, &bindings->root_descriptors[root_parameter_index]); + VK_NULL_HANDLE, &bindings->root_descriptors[root_parameter_index]); descriptor_write_count += 1; } @@ -5497,12 +5481,12 @@ static void d3d12_command_list_update_root_descriptors(struct d3d12_command_list bindings->root_descriptor_dirty_mask = 0; } - if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK) + if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK) { - d3d12_command_list_fetch_inline_uniform_block_data(list, bindings, &root_parameter_data); - - vk_write_descriptor_set_and_inline_uniform_block(&descriptor_writes[descriptor_write_count], - &inline_uniform_block_write, descriptor_set, root_signature, &root_parameter_data); + d3d12_command_list_fetch_inline_uniform_block_data(list, bindings, ptr_root_parameter_data); + vk_write_descriptor_set_from_scratch_push_ubo(&descriptor_writes[descriptor_write_count], + &buffer_info, &alloc, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, + root_signature->push_constant_ubo_binding.binding); descriptor_write_count += 1; } @@ -5514,18 +5498,7 @@ static void d3d12_command_list_update_root_descriptors(struct d3d12_command_list root_parameter_data.root_descriptor_vas)); } - if (!descriptor_write_count) - return; - - if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_ROOT_DESCRIPTOR_SET) - { - VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, - descriptor_write_count, descriptor_writes, 0, NULL)); - VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, vk_bind_point, - layout, root_signature->root_descriptor_set, - 1, &descriptor_set, 0, NULL)); - } - else + if (descriptor_write_count) { VK_CALL(vkCmdPushDescriptorSetKHR(list->vk_command_buffer, vk_bind_point, layout, root_signature->root_descriptor_set, @@ -5609,7 +5582,7 @@ static void d3d12_command_list_update_descriptors(struct d3d12_command_list *lis if (bindings->dirty_flags & VKD3D_PIPELINE_DIRTY_HOISTED_DESCRIPTORS) d3d12_command_list_update_hoisted_descriptors(list, bindings); - if (rs->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK) + if (rs->flags & VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK) { /* Root constants and descriptor table offsets are part of the root descriptor set */ if (bindings->root_descriptor_dirty_mask || bindings->root_constant_dirty_mask diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index e12699f5..05f2c092 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -102,7 +102,6 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = VK_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable), VK_EXTENSION(EXT_DESCRIPTOR_INDEXING, EXT_descriptor_indexing), VK_EXTENSION(EXT_IMAGE_VIEW_MIN_LOD, EXT_image_view_min_lod), - VK_EXTENSION(EXT_INLINE_UNIFORM_BLOCK, EXT_inline_uniform_block), VK_EXTENSION(EXT_ROBUSTNESS_2, EXT_robustness2), VK_EXTENSION(EXT_SAMPLER_FILTER_MINMAX, EXT_sampler_filter_minmax), VK_EXTENSION(EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION, EXT_shader_demote_to_helper_invocation), @@ -1294,14 +1293,6 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i vk_prepend_struct(&info->properties2, &info->descriptor_indexing_properties); } - if (vulkan_info->EXT_inline_uniform_block) - { - info->inline_uniform_block_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT; - vk_prepend_struct(&info->features2, &info->inline_uniform_block_features); - info->inline_uniform_block_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT; - vk_prepend_struct(&info->properties2, &info->inline_uniform_block_properties); - } - if (vulkan_info->EXT_robustness2) { info->robustness2_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; @@ -2187,6 +2178,12 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, return E_INVALIDARG; } + if (!vulkan_info->KHR_push_descriptor) + { + ERR("Push descriptors are not supported by this implementation. This is required for correct operation.\n"); + return E_INVALIDARG; + } + return S_OK; } diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index fb73e5b2..301a2982 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -526,9 +526,16 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i if (!local_root_signature) { - info->push_descriptor_count += info->hoist_descriptor_count; + /* Make sure that we won't exceed device limits. + * Minimum spec for push descriptors is 32 descriptors, which fits exactly what we need for D3D12. + * Worst case scenarios: + * - 32 root CBVs -> all 32 push descriptors are used. No push constants. + * - Root constants > 128 bytes, 15 root CBVs. 1 push descriptor for push UBO. Can hoist 16 other descriptors. + * Just base the amount of descriptors we can hoist on the root signature cost. This is simple and is trivially correct. */ info->hoist_descriptor_count = min(info->hoist_descriptor_count, VKD3D_MAX_HOISTED_DESCRIPTORS); - info->hoist_descriptor_count = min(info->hoist_descriptor_count, D3D12_MAX_ROOT_COST - desc->NumParameters); + info->hoist_descriptor_count = min(info->hoist_descriptor_count, (D3D12_MAX_ROOT_COST - info->cost) / 2); + + info->push_descriptor_count += info->hoist_descriptor_count; info->binding_count += info->hoist_descriptor_count; info->binding_count += desc->NumStaticSamplers; } @@ -952,7 +959,6 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign VkDescriptorSetLayoutBinding *vk_binding, *vk_binding_info = NULL; struct vkd3d_descriptor_hoist_desc *hoist_desc; struct vkd3d_shader_resource_binding *binding; - VkDescriptorSetLayoutCreateFlags vk_flags; struct vkd3d_shader_root_parameter *param; uint32_t raw_va_root_descriptor_count = 0; unsigned int hoisted_parameter_index; @@ -960,7 +966,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign unsigned int i, j, k; HRESULT hr = S_OK; - if (info->push_descriptor_count || (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK)) + if (info->push_descriptor_count || (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK)) { if (!(vk_binding_info = vkd3d_malloc(sizeof(*vk_binding_info) * (info->push_descriptor_count + 1)))) return E_OUTOFMEMORY; @@ -1081,12 +1087,12 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign context->vk_binding += 1; } - if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK) + if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK) { vk_binding = &vk_binding_info[j++]; vk_binding->binding = context->vk_binding; - vk_binding->descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT; - vk_binding->descriptorCount = push_constant_range->size; + vk_binding->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + vk_binding->descriptorCount = 1; vk_binding->stageFlags = VK_SHADER_STAGE_ALL; vk_binding->pImmutableSamplers = NULL; @@ -1096,12 +1102,19 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign context->vk_binding += 1; } - if (j) + /* This should never happen. Min requirement for push descriptors is 32 and we can always fit into that limit. */ + if (j > root_signature->device->device_info.push_descriptor_properties.maxPushDescriptors) { - vk_flags = root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_ROOT_DESCRIPTOR_SET - ? 0 : VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR; + ERR("Number of descriptors %u exceeds push descriptor limit of %u.\n", + j, root_signature->device->device_info.push_descriptor_properties.maxPushDescriptors); + vkd3d_free(vk_binding_info); + return E_OUTOFMEMORY; + } - hr = vkd3d_create_descriptor_set_layout(root_signature->device, vk_flags, + if (j) + { + hr = vkd3d_create_descriptor_set_layout(root_signature->device, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, j, vk_binding_info, vk_set_layout); } @@ -1333,24 +1346,9 @@ static HRESULT d3d12_root_signature_init_global(struct d3d12_root_signature *roo &root_signature->push_constant_range))) return hr; - if (root_signature->push_constant_range.size <= vk_device_properties->limits.maxPushConstantsSize) - { - if (info.push_descriptor_count > device->device_info.push_descriptor_properties.maxPushDescriptors) - root_signature->flags |= VKD3D_ROOT_SIGNATURE_USE_ROOT_DESCRIPTOR_SET; - } - else if (device->device_info.inline_uniform_block_features.inlineUniformBlock) - { - /* Stores push constant data with the root descriptor set, - * so we can't use push descriptors in this case. */ - root_signature->flags |= VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK | - VKD3D_ROOT_SIGNATURE_USE_ROOT_DESCRIPTOR_SET; - } - else - { - ERR("Root signature requires %d bytes of push constant space, but device only supports %d bytes.\n", - root_signature->push_constant_range.size, vk_device_properties->limits.maxPushConstantsSize); - return hr; - } + /* If we cannot contain the push constants, fall back to push UBO. */ + if (root_signature->push_constant_range.size > vk_device_properties->limits.maxPushConstantsSize) + root_signature->flags |= VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK; d3d12_root_signature_init_extra_bindings(root_signature, &info); @@ -1372,8 +1370,11 @@ static HRESULT d3d12_root_signature_init_global(struct d3d12_root_signature *roo if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &info, &context))) return hr; - if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK) + if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK) + { root_signature->push_constant_range.stageFlags = 0; + root_signature->push_constant_range.size = 0; + } /* If we need to use restricted entry_points in vkCmdPushConstants, * we are unfortunately required to do it like this @@ -1599,7 +1600,7 @@ unsigned int d3d12_root_signature_get_shader_interface_flags(const struct d3d12_ { unsigned int flags = 0; - if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK) + if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK) flags |= VKD3D_SHADER_INTERFACE_PUSH_CONSTANTS_AS_UNIFORM_BUFFER; if (root_signature->flags & VKD3D_ROOT_SIGNATURE_USE_SSBO_OFFSET_BUFFER) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 3fac5f43..e622339b 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -145,7 +145,6 @@ struct vkd3d_vulkan_info bool EXT_depth_clip_enable; bool EXT_descriptor_indexing; bool EXT_image_view_min_lod; - bool EXT_inline_uniform_block; bool EXT_robustness2; bool EXT_sampler_filter_minmax; bool EXT_shader_demote_to_helper_invocation; @@ -1355,11 +1354,10 @@ static inline bool d3d12_query_heap_type_is_inline(D3D12_QUERY_HEAP_TYPE heap_ty enum vkd3d_root_signature_flag { - VKD3D_ROOT_SIGNATURE_USE_ROOT_DESCRIPTOR_SET = 0x00000001u, - VKD3D_ROOT_SIGNATURE_USE_INLINE_UNIFORM_BLOCK = 0x00000002u, - VKD3D_ROOT_SIGNATURE_USE_RAW_VA_AUX_BUFFER = 0x00000004u, - VKD3D_ROOT_SIGNATURE_USE_SSBO_OFFSET_BUFFER = 0x00000008u, - VKD3D_ROOT_SIGNATURE_USE_TYPED_OFFSET_BUFFER = 0x00000010u, + VKD3D_ROOT_SIGNATURE_USE_PUSH_CONSTANT_UNIFORM_BLOCK = 0x00000001u, + VKD3D_ROOT_SIGNATURE_USE_RAW_VA_AUX_BUFFER = 0x00000002u, + VKD3D_ROOT_SIGNATURE_USE_SSBO_OFFSET_BUFFER = 0x00000004u, + VKD3D_ROOT_SIGNATURE_USE_TYPED_OFFSET_BUFFER = 0x00000008u, }; enum vkd3d_pipeline_type @@ -3316,7 +3314,6 @@ struct vkd3d_physical_device_info { /* properties */ VkPhysicalDeviceDescriptorIndexingPropertiesEXT descriptor_indexing_properties; - VkPhysicalDeviceInlineUniformBlockPropertiesEXT inline_uniform_block_properties; VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor_properties; VkPhysicalDeviceMaintenance3Properties maintenance3_properties; VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties; @@ -3352,7 +3349,6 @@ struct vkd3d_physical_device_info VkPhysicalDeviceDepthClipEnableFeaturesEXT depth_clip_features; VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing_features; VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT demote_features; - VkPhysicalDeviceInlineUniformBlockFeaturesEXT inline_uniform_block_features; VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT texel_buffer_alignment_features; VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features; |