Skip to content

Commit

Permalink
Add support for VK_EXT_inline_uniform_block
Browse files Browse the repository at this point in the history
adding into existing infrastructure:
- tracking of a binary blob 'inline_uniform_data' in DescriptorInfo
- support VkUpdateDescriptorSets and vkUpdateDescriptorSetWithTemplate
- add-hoc (re-)creation of pNext-structures for VkWriteDescriptorSet
  • Loading branch information
fabian-lunarg committed Apr 25, 2024
1 parent 0388ea8 commit 59bb2e9
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 50 deletions.
5 changes: 2 additions & 3 deletions framework/decode/custom_vulkan_struct_handle_mappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,11 @@ void MapStructHandles(Decoded_VkWriteDescriptorSet* wrapper, const VulkanObjectI
value->pTexelBufferView = handle_mapping::MapHandleArray<BufferViewInfo>(
&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;
Expand Down
6 changes: 3 additions & 3 deletions framework/decode/custom_vulkan_struct_to_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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__);
Expand Down
7 changes: 3 additions & 4 deletions framework/decode/vulkan_cpp_consumer_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion framework/decode/vulkan_cpp_structs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions framework/decode/vulkan_cpp_utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 5 additions & 0 deletions framework/encode/custom_vulkan_api_call_encoders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
7 changes: 1 addition & 6 deletions framework/encode/custom_vulkan_command_buffer_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 2 additions & 3 deletions framework/encode/custom_vulkan_struct_encoders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions framework/encode/descriptor_update_template_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand All @@ -58,6 +60,7 @@ struct UpdateTemplateInfo
std::vector<UpdateTemplateEntryInfo> buffer_info;
std::vector<UpdateTemplateEntryInfo> texel_buffer_view;
std::vector<UpdateTemplateEntryInfo> acceleration_structure_khr;
std::vector<UpdateTemplateEntryInfo> inline_uniform_block;
};

GFXRECON_END_NAMESPACE(encode)
Expand Down
1 change: 1 addition & 0 deletions framework/encode/vulkan_state_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ struct DescriptorInfo
std::unique_ptr<VkDescriptorBufferInfo[]> buffers;
std::unique_ptr<VkBufferView[]> texel_buffer_views;
std::unique_ptr<VkAccelerationStructureKHR[]> acceleration_structures;
std::unique_ptr<uint8_t[]> inline_uniform_block;
std::unique_ptr<VkDescriptorType[]> mutable_type;
};

Expand Down
62 changes: 59 additions & 3 deletions framework/encode/vulkan_state_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<VkWriteDescriptorSetInlineUniformBlock>(
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<const uint8_t*>(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;
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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);
}
}
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions framework/encode/vulkan_state_tracker_initializers.h
Original file line number Diff line number Diff line change
Expand Up @@ -864,8 +864,8 @@ inline void InitializePoolObjectState(VkDevice par
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
descriptor_info.texel_buffer_views = std::make_unique<VkBufferView[]>(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<uint8_t[]>(binding_info.count);
break;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
// TODO
Expand Down
42 changes: 23 additions & 19 deletions framework/encode/vulkan_state_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2344,47 +2344,49 @@ 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<uint8_t, max_num_bytes_p_next_data> p_next_data{};

write->pBufferInfo = nullptr;
write->pImageInfo = nullptr;
write->pTexelBufferView = nullptr;

switch (write->descriptorType)
{
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
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<VkWriteDescriptorSetInlineUniformBlock*>(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<VkWriteDescriptorSetAccelerationStructureKHR*>(p_next_data.data());
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 59bb2e9

Please sign in to comment.