diff --git a/external/Vulkan-Headers b/external/Vulkan-Headers index eaa319dade..577baa0503 160000 --- a/external/Vulkan-Headers +++ b/external/Vulkan-Headers @@ -1 +1 @@ -Subproject commit eaa319dade959cb61ed2229c8ea42e307cc8f8b3 +Subproject commit 577baa05033cf1d9236b3d078ca4b3269ed87a2b diff --git a/framework/decode/custom_vulkan_struct_handle_mappers.cpp b/framework/decode/custom_vulkan_struct_handle_mappers.cpp index c992cef57d..a6edf579c1 100644 --- a/framework/decode/custom_vulkan_struct_handle_mappers.cpp +++ b/framework/decode/custom_vulkan_struct_handle_mappers.cpp @@ -98,12 +98,11 @@ void MapStructHandles(Decoded_VkWriteDescriptorSet* wrapper, const VulkanObjectI value->pTexelBufferView = handle_mapping::MapHandleArray( &wrapper->pTexelBufferView, object_mapper, &VulkanObjectInfoTable::GetBufferViewInfo); break; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - // TODO - break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: // TODO break; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + // Handles are mapped in the VkWriteDescriptorSetInlineUniformBlock structure in the pNext chain case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: // Handles are mapped in the VkWriteDescriptorSetAccelerationStructureKHR structure in the pNext chain break; diff --git a/framework/decode/custom_vulkan_struct_to_json.cpp b/framework/decode/custom_vulkan_struct_to_json.cpp index c61a3a941f..6c1211a839 100644 --- a/framework/decode/custom_vulkan_struct_to_json.cpp +++ b/framework/decode/custom_vulkan_struct_to_json.cpp @@ -246,10 +246,10 @@ void FieldToJson(nlohmann::ordered_json& jdata, const Decoded_VkWriteDescriptorS HandleToJson(jdata["pTexelBufferView"], &meta_struct.pTexelBufferView, options); break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: - // Nothing to do here for acceleration structures as the rest of the data is stored - // in the pNext chain - break; case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + // Nothing to do here for acceleration-structures and inline-uniform-blocks, + // as the rest of the data is stored in the pNext chain + break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: case VK_DESCRIPTOR_TYPE_MUTABLE_EXT: GFXRECON_LOG_WARNING("Descriptor type not supported at " __FILE__ ", line: %d.", __LINE__); diff --git a/framework/decode/vulkan_cpp_consumer_base.cpp b/framework/decode/vulkan_cpp_consumer_base.cpp index 8f4b6e6ce0..c7df737589 100644 --- a/framework/decode/vulkan_cpp_consumer_base.cpp +++ b/framework/decode/vulkan_cpp_consumer_base.cpp @@ -2332,10 +2332,9 @@ void VulkanCppConsumerBase::GenerateDescriptorUpdateTemplateData(DescriptorUpdat struct_define_stream << "\t\t\tVkAccelerationStructureKHR descAccelInfo" << cur_count++ << "[" << var.count << "];\n"; break; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - // Not handled - assert(false); - struct_define_stream << "INLINE UNIFORM BLOCK not handled,"; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + struct_define_stream << "\t\t\tInlineUniformBlock descInlineUniformInfo" << cur_count++ << "[" + << var.count << "];\n"; break; default: assert(false); diff --git a/framework/decode/vulkan_cpp_structs.cpp b/framework/decode/vulkan_cpp_structs.cpp index c07ffcafc6..55365d27d0 100644 --- a/framework/decode/vulkan_cpp_structs.cpp +++ b/framework/decode/vulkan_cpp_structs.cpp @@ -169,7 +169,7 @@ std::string GenerateStruct_VkWriteDescriptorSet(std::ostream& ou break; } case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: case VK_DESCRIPTOR_TYPE_MAX_ENUM: { // Nothing to do. diff --git a/framework/decode/vulkan_cpp_utilities.cpp b/framework/decode/vulkan_cpp_utilities.cpp index 1331bce4db..4ca4058943 100644 --- a/framework/decode/vulkan_cpp_utilities.cpp +++ b/framework/decode/vulkan_cpp_utilities.cpp @@ -70,8 +70,8 @@ std::string DescriptorCreateInfoTypeToString(VkDescriptorType descriptorType) case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return "VkBufferView"; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - return "VkWriteDescriptorSetInlineUniformBlockEXT"; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + return "VkWriteDescriptorSetInlineUniformBlock"; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: return "VkWriteDescriptorSetAccelerationStructureKHR"; default: @@ -99,7 +99,7 @@ DescriptorBaseType GetDescriptorBaseType(VkDescriptorType descriptorType) case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return DESCRIPTOR_BASE_TYPE_TEXEL; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: return DESCRIPTOR_BASE_TYPE_INLINE_UNIFORM_BLOCK; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: return DESCRIPTOR_BASE_TYPE_ACCELERATION_STRUCTURE; diff --git a/framework/decode/vulkan_referenced_resource_consumer_base.cpp b/framework/decode/vulkan_referenced_resource_consumer_base.cpp index a9c961c657..da375e3d33 100644 --- a/framework/decode/vulkan_referenced_resource_consumer_base.cpp +++ b/framework/decode/vulkan_referenced_resource_consumer_base.cpp @@ -501,7 +501,7 @@ void VulkanReferencedResourceConsumerBase::Process_vkUpdateDescriptorSets( switch (writes[i].descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: // Descriptor types that do not need to be tracked. break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: diff --git a/framework/encode/custom_vulkan_api_call_encoders.cpp b/framework/encode/custom_vulkan_api_call_encoders.cpp index 0db16316cf..9180c29115 100644 --- a/framework/encode/custom_vulkan_api_call_encoders.cpp +++ b/framework/encode/custom_vulkan_api_call_encoders.cpp @@ -105,6 +105,11 @@ static const void* UnwrapDescriptorUpdateTemplateInfoHandles(const UpdateTemplat } } + // Process VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK data + for (const auto& entry_info : info->inline_uniform_block) + { + memcpy(unwrapped_data + entry_info.offset, bytes + entry_info.offset, entry_info.count); + } return unwrapped_data; } diff --git a/framework/encode/custom_vulkan_command_buffer_util.cpp b/framework/encode/custom_vulkan_command_buffer_util.cpp index d2cf8deb03..83cdbd2ae8 100644 --- a/framework/encode/custom_vulkan_command_buffer_util.cpp +++ b/framework/encode/custom_vulkan_command_buffer_util.cpp @@ -186,12 +186,7 @@ void TrackCmdPushDescriptorSetKHRHandles(vulkan_wrappers::CommandBufferWrapper* } } break; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - { - assert(false && "Maintentance required to support pushed inline uniform block descriptors when " - "creating trimmed captures"); - } - break; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: diff --git a/framework/encode/custom_vulkan_struct_encoders.cpp b/framework/encode/custom_vulkan_struct_encoders.cpp index b6b978ee38..c1b38b76e7 100644 --- a/framework/encode/custom_vulkan_struct_encoders.cpp +++ b/framework/encode/custom_vulkan_struct_encoders.cpp @@ -145,12 +145,11 @@ void EncodeStruct(ParameterEncoder* encoder, const VkWriteDescriptorSet& value) case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: omit_texel_buffer_data = false; break; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - // TODO - break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: // TODO break; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + // Handles are encoded in the VkWriteDescriptorSetInlineUniformBlock structure in the pNext chain case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: // Handles are encoded in the VkWriteDescriptorSetAccelerationStructureKHR structure in the pNext chain break; diff --git a/framework/encode/descriptor_update_template_info.h b/framework/encode/descriptor_update_template_info.h index 0a9de1680a..156c64cb24 100644 --- a/framework/encode/descriptor_update_template_info.h +++ b/framework/encode/descriptor_update_template_info.h @@ -46,8 +46,10 @@ struct UpdateTemplateInfo { // The counts are the sum of the total descriptorCount for each update template entry type. When written to the // capture file, the update template data will be written as tightly packed arrays of VkDescriptorImageInfo, - // VkDescriptorBufferInfo, VkBufferView, and VkAccelerationStructureKHR types. There will be one array per - // descriptor update entry, so the counts are pre-computed for the file encoding process to know the total number of + // VkDescriptorBufferInfo, VkBufferView, VkAccelerationStructureKHR or byte-arrays + // in case of VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK. + // There will be one array per descriptor update entry, + // so the counts are pre-computed for the file encoding process to know the total number of // items to encode prior to processing the individual UpdateTemplateEntry structures. size_t max_size{ 0 }; size_t image_info_count{ 0 }; @@ -58,6 +60,7 @@ struct UpdateTemplateInfo std::vector buffer_info; std::vector texel_buffer_view; std::vector acceleration_structure_khr; + std::vector inline_uniform_block; }; GFXRECON_END_NAMESPACE(encode) diff --git a/framework/encode/vulkan_state_info.h b/framework/encode/vulkan_state_info.h index 88d8cd1fdd..97f9af567b 100644 --- a/framework/encode/vulkan_state_info.h +++ b/framework/encode/vulkan_state_info.h @@ -76,6 +76,7 @@ struct DescriptorInfo std::unique_ptr buffers; std::unique_ptr texel_buffer_views; std::unique_ptr acceleration_structures; + std::unique_ptr inline_uniform_block; std::unique_ptr mutable_type; }; diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index f86dd9b0a9..022aa5c299 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -756,9 +756,21 @@ void VulkanStateTracker::TrackUpdateDescriptorSets(uint32_t w } break; } - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - // TODO - break; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + { + VkWriteDescriptorSetInlineUniformBlock* write_inline_uniform_struct = + graphics::GetPNextStruct( + write, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK); + + if (write_inline_uniform_struct != nullptr) + { + uint8_t* dst_inline_uniform_data = binding.inline_uniform_block.get(); + const uint8_t* src_inline_uniform_data = + reinterpret_cast(write_inline_uniform_struct->pData); + memcpy(dst_inline_uniform_data, src_inline_uniform_data, current_writes); + } + } + break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: // TODO break; @@ -865,6 +877,12 @@ void VulkanStateTracker::TrackUpdateDescriptorSets(uint32_t w &src_binding.acceleration_structures[current_src_array_element], (sizeof(VkWriteDescriptorSetAccelerationStructureKHR) * current_copies)); } + if (src_binding.inline_uniform_block != nullptr) + { + memcpy(&dst_binding.inline_uniform_block[current_dst_array_element], + &src_binding.inline_uniform_block[current_src_array_element], + current_copies); + } if (src_binding.texel_buffer_views != nullptr) { memcpy(&dst_binding.texel_buffer_views[current_dst_array_element], @@ -1136,6 +1154,44 @@ void VulkanStateTracker::TrackUpdateDescriptorSetWithTemplate(VkDescriptorSet } } } + for (const auto& entry : template_info->inline_uniform_block) + { + // Descriptor update rules specify that a write descriptorCount that is greater than the binding's count + // will result in updates to consecutive bindings. + uint32_t current_count = entry.count; + uint32_t current_binding = entry.binding; + uint32_t current_array_element = entry.array_element; + size_t current_offset = entry.offset; + + for (;;) + { + auto& binding = wrapper->bindings[entry.binding]; + GFXRECON_ASSERT(binding.inline_uniform_block != nullptr); + + // Check count for consecutive updates. + const uint32_t current_num_bytes = std::min(current_count, (binding.count - current_array_element)); + + bool* written_start = &binding.written[current_array_element]; + std::fill(written_start, written_start + current_num_bytes, true); + + const uint8_t* src_address = bytes + current_offset; + uint8_t* dst_address = binding.inline_uniform_block.get() + entry.array_element; + memcpy(dst_address, src_address, current_num_bytes); + + // Check for consecutive update. + if (current_count == current_num_bytes) + { + break; + } + else + { + current_count -= current_num_bytes; + current_binding += 1; + current_array_element = 0; + current_offset += (current_num_bytes * entry.stride); + } + } + } } } diff --git a/framework/encode/vulkan_state_tracker_initializers.h b/framework/encode/vulkan_state_tracker_initializers.h index 127a7a23a9..3dff184dc7 100644 --- a/framework/encode/vulkan_state_tracker_initializers.h +++ b/framework/encode/vulkan_state_tracker_initializers.h @@ -864,8 +864,8 @@ inline void InitializePoolObjectState(VkDevice par case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: descriptor_info.texel_buffer_views = std::make_unique(binding_info.count); break; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - // TODO + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + descriptor_info.inline_uniform_block = std::make_unique(binding_info.count); break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: // TODO diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index 109ac2961f..b3d97fab37 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -2344,10 +2344,14 @@ void VulkanStateWriter::WriteDescriptorUpdateCommand(format::HandleId const VkCopyDescriptorSet* copy = nullptr; // scratch-space for a potential pNext-struct - constexpr size_t max_num_bytes_p_next_data = std::max(sizeof(VkWriteDescriptorSetAccelerationStructureKHR), - sizeof(VkWriteDescriptorSetInlineUniformBlockEXT)); + constexpr size_t max_num_bytes_p_next_data = + std::max(sizeof(VkWriteDescriptorSetAccelerationStructureKHR), sizeof(VkWriteDescriptorSetInlineUniformBlock)); std::array p_next_data{}; + write->pBufferInfo = nullptr; + write->pImageInfo = nullptr; + write->pTexelBufferView = nullptr; + switch (write->descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: @@ -2355,36 +2359,34 @@ void VulkanStateWriter::WriteDescriptorUpdateCommand(format::HandleId case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - write->pBufferInfo = nullptr; - write->pImageInfo = &binding->images[write->dstArrayElement]; - write->pTexelBufferView = nullptr; + write->pImageInfo = &binding->images[write->dstArrayElement]; break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - write->pBufferInfo = &binding->buffers[write->dstArrayElement]; - write->pImageInfo = nullptr; - write->pTexelBufferView = nullptr; + write->pBufferInfo = &binding->buffers[write->dstArrayElement]; break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - write->pBufferInfo = nullptr; - write->pImageInfo = nullptr; write->pTexelBufferView = &binding->texel_buffer_views[write->dstArrayElement]; break; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - // TODO + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + if (binding->inline_uniform_block != nullptr) + { + auto& p_next = *reinterpret_cast(p_next_data.data()); + p_next.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK; + p_next.pNext = nullptr; + p_next.pData = binding->inline_uniform_block.get(); + p_next.dataSize = binding->count; + write->pNext = &p_next; + } break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: // TODO break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: { - write->pBufferInfo = nullptr; - write->pImageInfo = nullptr; - write->pTexelBufferView = nullptr; - if (binding->acceleration_structures != nullptr) { auto& p_next = *reinterpret_cast(p_next_data.data()); @@ -3155,9 +3157,11 @@ bool VulkanStateWriter::CheckDescriptorStatus(const vulkan_state_info::Descripto valid = true; } break; - case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: - // TODO - GFXRECON_LOG_WARNING("Descriptor type inline uniform block is not currently supported"); + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + if (descriptor->inline_uniform_block != nullptr) + { + valid = true; + } break; case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: // TODO