Handle descriptor buffers when processing descriptor accesses

This commit is contained in:
baldurk
2025-06-13 11:22:25 +01:00
parent 3d23227dd4
commit ccd99a5a91
12 changed files with 301 additions and 90 deletions
+31
View File
@@ -1645,6 +1645,37 @@ void DescriptorSetSlot::AccumulateBindRefs(DescriptorBindRefs &refs, VulkanResou
}
}
uint32_t DescriptorDataSize(const VkPhysicalDeviceDescriptorBufferPropertiesEXT &descSizes,
VkDescriptorType type)
{
size_t ret = 0;
switch(type)
{
case VK_DESCRIPTOR_TYPE_SAMPLER: ret = descSizes.samplerDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
ret = descSizes.combinedImageSamplerDescriptorSize;
break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: ret = descSizes.inputAttachmentDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: ret = descSizes.sampledImageDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: ret = descSizes.storageImageDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
ret = descSizes.uniformTexelBufferDescriptorSize;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
ret = descSizes.storageTexelBufferDescriptorSize;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: ret = descSizes.uniformBufferDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: ret = descSizes.storageBufferDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
ret = descSizes.accelerationStructureDescriptorSize;
break;
default: break;
}
return (uint32_t)ret;
}
void DynamicRenderingLocalRead::Init(const VkBaseInStructure *infoStruct)
{
const VkRenderingAttachmentLocationInfo *attachmentLocationInfo =
+3
View File
@@ -918,6 +918,9 @@ DECLARE_REFLECTION_STRUCT(DescriptorSetSlot);
constexpr uint64_t FixedOpaqueDescriptorCaptureSize = 16;
constexpr uint64_t MaxDescriptorSize = 256;
uint32_t DescriptorDataSize(const VkPhysicalDeviceDescriptorBufferPropertiesEXT &descSizes,
VkDescriptorType type);
struct OpaqueDataForSerialising : VkOpaqueCaptureDescriptorDataCreateInfoEXT
{
OpaqueDataForSerialising()
+2 -30
View File
@@ -209,8 +209,6 @@ WrappedVulkan::WrappedVulkan()
m_FrameCaptureRecord = NULL;
ResourceIDGen::SetReplayResourceIDs();
m_CreationInfo.pushConstantDescriptorStorage = ResourceIDGen::GetNewUniqueID();
}
}
@@ -5427,35 +5425,9 @@ ResourceId WrappedVulkan::GetASFromAddr(VkDeviceAddress addr)
return m_ASLookupByAddr[addr];
}
size_t WrappedVulkan::DescriptorDataSize(VkDescriptorType type)
uint32_t WrappedVulkan::DescriptorDataSize(VkDescriptorType type)
{
size_t ret = 0;
const VkPhysicalDeviceDescriptorBufferPropertiesEXT &descSizes = m_DescriptorBufferProperties;
switch(type)
{
case VK_DESCRIPTOR_TYPE_SAMPLER: ret = descSizes.samplerDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
ret = descSizes.combinedImageSamplerDescriptorSize;
break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: ret = descSizes.inputAttachmentDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: ret = descSizes.sampledImageDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: ret = descSizes.storageImageDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
ret = descSizes.uniformTexelBufferDescriptorSize;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
ret = descSizes.storageTexelBufferDescriptorSize;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: ret = descSizes.uniformBufferDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: ret = descSizes.storageBufferDescriptorSize; break;
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
ret = descSizes.accelerationStructureDescriptorSize;
break;
default: break;
}
return ret;
return ::DescriptorDataSize(m_DescriptorBufferProperties, type);
}
void WrappedVulkan::EstimateDescriptorFormats()
+3 -1
View File
@@ -463,7 +463,6 @@ private:
};
VkPhysicalDeviceDescriptorBufferPropertiesEXT m_DescriptorBufferProperties;
size_t DescriptorDataSize(VkDescriptorType type);
Threading::CriticalSection m_ASLookupByAddrLock;
rdcflatmap<VkDeviceAddress, ResourceId> m_ASLookupByAddr;
@@ -529,6 +528,7 @@ private:
bool m_NULLDescriptorPatternSaved = false;
bool m_IgnoreLayoutForDescriptors = false;
std::unordered_map<ResourceId, ResourceId> m_InlineBuffers;
bool m_SeparateDepthStencil = false;
bool m_NULLDescriptorsAllowed = false;
@@ -1494,6 +1494,8 @@ public:
static VkResult GetProvidedInstanceExtensionProperties(uint32_t *pPropertyCount,
VkExtensionProperties *pProperties);
uint32_t DescriptorDataSize(VkDescriptorType type);
VkBufferCreateFlags DefaultBufferCreateFlags()
{
return DescriptorBuffers() ? VK_BUFFER_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT : 0;
+143 -39
View File
@@ -30,6 +30,11 @@
// for compatibility we use the same DXBC name since it's now configured by the UI
RDOC_EXTERN_CONFIG(rdcarray<rdcstr>, DXBC_Debug_SearchDirPaths);
ResourceId VulkanCreationInfo::pushConstantDescriptorStorage;
rdcarray<ResourceId> VulkanCreationInfo::descriptorSetStorage;
rdcarray<ResourceId> VulkanCreationInfo::descriptorBufferStorage;
rdcarray<ResourceId> VulkanCreationInfo::inlineBufferStorage;
VkDynamicState ConvertDynamicState(VulkanDynamicStateIndex idx)
{
switch(idx)
@@ -316,8 +321,10 @@ static VkGraphicsPipelineLibraryFlagsEXT DynamicStateValidState(VkDynamicState s
}
void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo)
ResourceId id, const VkDescriptorSetLayoutCreateInfo *pCreateInfo)
{
resourceId = id;
dynamicCount = 0;
inlineCount = 0;
inlineByteSize = 0;
@@ -825,9 +832,10 @@ bool CreateDescriptorWritesForSlotData(WrappedVulkan *vk, rdcarray<VkWriteDescri
return ret;
}
void VulkanCreationInfo::ShaderEntry::ProcessStaticDescriptorAccess(
ResourceId pushStorage, ResourceId specStorage, rdcarray<DescriptorAccess> &descriptorAccess,
rdcarray<const DescSetLayout *> setLayoutInfos) const
void ProcessStaticDescriptorAccess(VulkanResourceManager *resourceMan, ShaderReflection *refl,
ResourceId specStorage,
rdcarray<DescriptorAccess> &descriptorAccess,
rdcarray<const DescSetLayout *> setLayoutInfos)
{
if(!refl)
return;
@@ -837,8 +845,7 @@ void VulkanCreationInfo::ShaderEntry::ProcessStaticDescriptorAccess(
DescriptorAccess access;
access.stage = refl->stage;
// we will store the descriptor set in byteSize to be decoded into descriptorStore later
access.byteSize = 0;
// desciptor set storage is fake, so byteSize is just 1
descriptorAccess.reserve(descriptorAccess.size() + refl->constantBlocks.size() +
refl->samplers.size() + refl->readOnlyResources.size() +
@@ -857,19 +864,19 @@ void VulkanCreationInfo::ShaderEntry::ProcessStaticDescriptorAccess(
if(!bind.bufferBacked)
{
access.byteSize = 1;
if(bind.compileConstants)
{
// spec constants
access.descriptorStore = specStorage;
access.byteSize = 1;
access.byteOffset = 0;
descriptorAccess.push_back(access);
}
else
{
// push constants
access.descriptorStore = pushStorage;
access.byteSize = 1;
access.descriptorStore = VulkanCreationInfo::pushConstantDescriptorStorage;
access.byteOffset = 0;
descriptorAccess.push_back(access);
}
@@ -881,19 +888,44 @@ void VulkanCreationInfo::ShaderEntry::ProcessStaticDescriptorAccess(
bind.fixedBindNumber >= setLayoutInfos[bind.fixedBindSetOrSpace]->bindings.size())
continue;
access.descriptorStore = ResourceId();
const DescSetLayout *setLayout = setLayoutInfos[bind.fixedBindSetOrSpace];
// VkShaderStageFlagBits and ShaderStageMask are identical bit-for-bit.
// this might be deliberate if the binding is never actually used dynamically, only
// statically used bindings must be declared
if((setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].stageFlags &
if((setLayout->bindings[bind.fixedBindNumber].stageFlags &
(VkShaderStageFlags)MaskForStage(refl->stage)) == 0)
continue;
access.byteSize = bind.fixedBindSetOrSpace;
access.byteOffset =
setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].elemOffset +
setLayoutInfos[bind.fixedBindSetOrSpace]->inlineByteSize;
if((setLayout->flags & (VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT)) ==
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT)
{
if(setLayout->bindings[bind.fixedBindNumber].layoutDescType ==
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK)
{
access.descriptorStore = VulkanCreationInfo::inlineBufferStorage[bind.fixedBindSetOrSpace];
access.byteSize = setLayout->bindings[bind.fixedBindNumber].descriptorCount;
}
else
{
access.descriptorStore =
VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace];
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
}
// we are only handling non-arrays here
access.byteOffset = setLayout->bindings[bind.fixedBindNumber].elemOffset;
}
else
{
access.descriptorStore = VulkanCreationInfo::descriptorSetStorage[bind.fixedBindSetOrSpace];
access.byteSize = 1;
access.byteOffset =
setLayout->bindings[bind.fixedBindNumber].elemOffset + setLayout->inlineByteSize;
}
descriptorAccess.push_back(access);
}
}
@@ -913,19 +945,43 @@ void VulkanCreationInfo::ShaderEntry::ProcessStaticDescriptorAccess(
bind.fixedBindNumber >= setLayoutInfos[bind.fixedBindSetOrSpace]->bindings.size())
continue;
const DescSetLayout *setLayout = setLayoutInfos[bind.fixedBindSetOrSpace];
// VkShaderStageFlagBits and ShaderStageMask are identical bit-for-bit.
// this might be deliberate if the binding is never actually used dynamically, only
// statically used bindings must be declared
if((setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].stageFlags &
if((setLayout->bindings[bind.fixedBindNumber].stageFlags &
(VkShaderStageFlags)MaskForStage(refl->stage)) == 0)
continue;
access.type = DescriptorType::Sampler;
access.index = i;
access.byteSize = bind.fixedBindSetOrSpace;
access.byteOffset =
setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].elemOffset +
setLayoutInfos[bind.fixedBindSetOrSpace]->inlineByteSize;
if((setLayout->flags & (VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT)) ==
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT)
{
access.descriptorStore = VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace];
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_SAMPLER);
// we are only handling non-arrays here
access.byteOffset = setLayout->bindings[bind.fixedBindNumber].elemOffset;
}
else if(setLayout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT)
{
access.descriptorStore = resourceMan->GetOriginalID(setLayout->resourceId);
access.byteSize = 1;
access.byteOffset = bind.fixedBindNumber;
}
else
{
access.descriptorStore = VulkanCreationInfo::descriptorSetStorage[bind.fixedBindSetOrSpace];
access.byteSize = 1;
access.byteOffset =
setLayout->bindings[bind.fixedBindNumber].elemOffset + setLayout->inlineByteSize;
}
descriptorAccess.push_back(access);
}
@@ -942,19 +998,47 @@ void VulkanCreationInfo::ShaderEntry::ProcessStaticDescriptorAccess(
bind.fixedBindNumber >= setLayoutInfos[bind.fixedBindSetOrSpace]->bindings.size())
continue;
const DescSetLayout *setLayout = setLayoutInfos[bind.fixedBindSetOrSpace];
// VkShaderStageFlagBits and ShaderStageMask are identical bit-for-bit.
// this might be deliberate if the binding is never actually used dynamically, only
// statically used bindings must be declared
if((setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].stageFlags &
if((setLayout->bindings[bind.fixedBindNumber].stageFlags &
(VkShaderStageFlags)MaskForStage(refl->stage)) == 0)
continue;
access.type = refl->readOnlyResources[i].descriptorType;
access.index = i;
access.byteSize = bind.fixedBindSetOrSpace;
access.byteOffset =
setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].elemOffset +
setLayoutInfos[bind.fixedBindSetOrSpace]->inlineByteSize;
if((setLayout->flags & (VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT)) ==
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT)
{
access.descriptorStore = VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace];
if(bind.isInputAttachment)
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
else if(bind.hasSampler)
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
else if(bind.isTexture)
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
else if(bind.descriptorType == DescriptorType::AccelerationStructure)
access.byteSize =
resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
else
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
// we are only handling non-arrays here
access.byteOffset = setLayout->bindings[bind.fixedBindNumber].elemOffset;
}
else
{
access.descriptorStore = VulkanCreationInfo::descriptorSetStorage[bind.fixedBindSetOrSpace];
access.byteSize = 1;
access.byteOffset =
setLayout->bindings[bind.fixedBindNumber].elemOffset + setLayout->inlineByteSize;
}
descriptorAccess.push_back(access);
}
@@ -971,19 +1055,42 @@ void VulkanCreationInfo::ShaderEntry::ProcessStaticDescriptorAccess(
bind.fixedBindNumber >= setLayoutInfos[bind.fixedBindSetOrSpace]->bindings.size())
continue;
const DescSetLayout *setLayout = setLayoutInfos[bind.fixedBindSetOrSpace];
// VkShaderStageFlagBits and ShaderStageMask are identical bit-for-bit.
// this might be deliberate if the binding is never actually used dynamically, only
// statically used bindings must be declared
if((setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].stageFlags &
if((setLayout->bindings[bind.fixedBindNumber].stageFlags &
(VkShaderStageFlags)MaskForStage(refl->stage)) == 0)
continue;
access.type = refl->readWriteResources[i].descriptorType;
access.index = i;
access.byteSize = bind.fixedBindSetOrSpace;
access.byteOffset =
setLayoutInfos[bind.fixedBindSetOrSpace]->bindings[bind.fixedBindNumber].elemOffset +
setLayoutInfos[bind.fixedBindSetOrSpace]->inlineByteSize;
if((setLayout->flags & (VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT)) ==
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT)
{
access.descriptorStore = VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace];
if(bind.isTexture)
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
else if(bind.descriptorType == DescriptorType::ReadWriteTypedBuffer)
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
else
access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
// we are only handling non-arrays here
access.byteOffset = setLayout->bindings[bind.fixedBindNumber].elemOffset;
}
else
{
access.descriptorStore = VulkanCreationInfo::descriptorSetStorage[bind.fixedBindSetOrSpace];
access.byteSize = 1;
access.byteOffset =
setLayout->bindings[bind.fixedBindNumber].elemOffset + setLayout->inlineByteSize;
}
descriptorAccess.push_back(access);
}
}
@@ -1066,9 +1173,8 @@ void VulkanCreationInfo::ShaderObject::Init(VulkanResourceManager *resourceMan,
for(ResourceId setLayout : descSetLayouts)
setLayoutInfos.push_back(&info.m_DescSetLayout[setLayout]);
shad.ProcessStaticDescriptorAccess(info.pushConstantDescriptorStorage,
resourceMan->GetOriginalID(id), staticDescriptorAccess,
setLayoutInfos);
ProcessStaticDescriptorAccess(resourceMan, shad.refl, resourceMan->GetOriginalID(id),
staticDescriptorAccess, setLayoutInfos);
}
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
@@ -1765,9 +1871,8 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
setLayoutInfos.push_back(&info.m_DescSetLayout[setLayout]);
for(const ShaderEntry &shad : shaders)
shad.ProcessStaticDescriptorAccess(info.pushConstantDescriptorStorage,
resourceMan->GetOriginalID(id), staticDescriptorAccess,
setLayoutInfos);
ProcessStaticDescriptorAccess(resourceMan, shad.refl, resourceMan->GetOriginalID(id),
staticDescriptorAccess, setLayoutInfos);
}
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
@@ -1881,9 +1986,8 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
setLayoutInfos.push_back(&info.m_DescSetLayout[setLayout]);
for(const ShaderEntry &shad : shaders)
shad.ProcessStaticDescriptorAccess(info.pushConstantDescriptorStorage,
resourceMan->GetOriginalID(id), staticDescriptorAccess,
setLayoutInfos);
ProcessStaticDescriptorAccess(resourceMan, shad.refl, resourceMan->GetOriginalID(id),
staticDescriptorAccess, setLayoutInfos);
}
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
+10 -6
View File
@@ -36,7 +36,7 @@ VulkanDynamicStateIndex ConvertDynamicState(VkDynamicState state);
struct DescSetLayout
{
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, ResourceId id,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo);
void CreateBindingsArray(BindingStorage &bindingStorage, uint32_t variableAllocSize) const;
@@ -121,6 +121,8 @@ struct DescSetLayout
};
rdcarray<Binding> bindings;
ResourceId resourceId;
// parallel array to bindings, with a bitmask of mutable types
rdcarray<uint64_t> mutableBitmasks;
@@ -246,10 +248,6 @@ struct VulkanCreationInfo
// VkPipelineShaderStageRequiredSubgroupSizeCreateInfo
uint32_t requiredSubgroupSize = 0;
void ProcessStaticDescriptorAccess(ResourceId pushStorage, ResourceId specStorage,
rdcarray<DescriptorAccess> &staticDescriptorAccess,
rdcarray<const DescSetLayout *> setLayoutInfos) const;
};
struct Pipeline
@@ -612,6 +610,8 @@ struct VulkanCreationInfo
bool external;
VkMemoryRequirements mrq;
ResourceId inlineDescriptorId;
};
std::unordered_map<ResourceId, Buffer> m_Buffer;
@@ -814,7 +814,11 @@ struct VulkanCreationInfo
std::unordered_map<ResourceId, uint32_t> m_Queue;
// the fake ID of the 'command buffer' descriptor store for push constants
ResourceId pushConstantDescriptorStorage;
static ResourceId pushConstantDescriptorStorage;
// fake IDs for each set/buffer
static rdcarray<ResourceId> descriptorSetStorage;
static rdcarray<ResourceId> descriptorBufferStorage;
static rdcarray<ResourceId> inlineBufferStorage;
void erase(ResourceId id)
{
+5
View File
@@ -908,6 +908,11 @@ ResourceId VulkanResourceManager::GetFirstIDForHandle(uint64_t handle)
return ResourceId();
}
uint32_t VulkanResourceManager::DescriptorDataSize(VkDescriptorType type)
{
return m_Core->DescriptorDataSize(type);
}
void VulkanResourceManager::MarkMemoryFrameReferenced(ResourceId mem, VkDeviceSize offset,
VkDeviceSize size, FrameRefType refType)
{
+2
View File
@@ -213,6 +213,8 @@ public:
ResourceId GetFirstIDForHandle(uint64_t handle);
uint32_t DescriptorDataSize(VkDescriptorType type);
// easy path for getting the wrapped handle cast to the correct type
template <typename realtype>
realtype GetLiveHandle(ResourceId origid)
+54 -11
View File
@@ -275,6 +275,8 @@ rdcarray<uint32_t> VulkanReplay::GetPassEvents(uint32_t eventId)
ResourceId VulkanReplay::GetLiveID(ResourceId id)
{
if(m_pDriver->m_InlineBuffers.find(id) != m_pDriver->m_InlineBuffers.end())
return id;
if(!m_pDriver->GetResourceManager()->HasLiveResource(id))
return ResourceId();
return m_pDriver->GetResourceManager()->GetLiveID(id);
@@ -2656,24 +2658,65 @@ rdcarray<DescriptorAccess> VulkanReplay::GetDescriptorAccess(uint32_t eventId)
for(DescriptorAccess &access : ret)
{
uint32_t bindset = (uint32_t)access.byteSize;
access.byteSize = 1;
if(access.descriptorStore == m_pDriver->m_CreationInfo.pushConstantDescriptorStorage)
if(access.descriptorStore == VulkanCreationInfo::pushConstantDescriptorStorage)
{
access.descriptorStore = m_pDriver->GetPushConstantCommandBuffer();
}
else if(access.descriptorStore == ResourceId())
else
{
const rdcarray<VulkanStatePipeline::DescriptorAndOffsets> &descSets =
access.stage == ShaderStage::Compute ? state.compute.descSets : state.graphics.descSets;
int setIdx = VulkanCreationInfo::descriptorSetStorage.indexOf(access.descriptorStore);
int bufSetIdx = VulkanCreationInfo::descriptorBufferStorage.indexOf(access.descriptorStore);
int inlinebufSetIdx = VulkanCreationInfo::inlineBufferStorage.indexOf(access.descriptorStore);
if(setIdx >= 0)
{
const rdcarray<VulkanStatePipeline::DescriptorAndOffsets> &descSets =
access.stage == ShaderStage::Compute ? state.compute.descSets : state.graphics.descSets;
if(bindset >= descSets.size())
{
RDCERR("Unbound descriptor set referenced in static usage");
access.byteSize = 1;
if(setIdx >= descSets.count())
{
RDCERR("Unbound descriptor set referenced in static usage");
}
else
{
access.descriptorStore = rm->GetOriginalID(descSets[setIdx].descSet);
}
}
else
else if(bufSetIdx >= 0 || inlinebufSetIdx >= 0)
{
access.descriptorStore = rm->GetOriginalID(descSets[bindset].descSet);
const rdcarray<VulkanStatePipeline::DescriptorAndOffsets> &descSets =
access.stage == ShaderStage::Compute ? state.compute.descSets : state.graphics.descSets;
// one will be -1
int i = RDCMAX(bufSetIdx, inlinebufSetIdx);
if(i >= descSets.count())
{
RDCERR("Unbound descriptor set referenced in static usage");
}
else
{
const VulkanStatePipeline::DescriptorAndOffsets &bufSet = descSets[i];
if(bufSet.descBufferEmbeddedSamplers)
{
access.descriptorStore = rm->GetOriginalID(
m_pDriver->m_CreationInfo.m_PipelineLayout[bufSet.pipeLayout].descSetLayouts[i]);
access.byteOffset = 0;
}
else
{
ResourceId id;
uint64_t offs = 0;
m_pDriver->GetResIDFromAddr(state.descBufs[bufSet.descBufferIdx].address, id, offs);
if(inlinebufSetIdx >= 0)
access.descriptorStore = m_pDriver->m_CreationInfo.m_Buffer[id].inlineDescriptorId;
else
access.descriptorStore = rm->GetOriginalID(id);
access.byteOffset += uint32_t(offs + bufSet.descBufferOffset);
}
}
}
}
@@ -429,7 +429,27 @@ bool WrappedVulkan::Serialise_vkCreateDescriptorSetLayout(
live = GetResourceManager()->WrapResource(Unwrap(device), layout);
GetResourceManager()->AddLiveResource(SetLayout, layout);
m_CreationInfo.m_DescSetLayout[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo);
m_CreationInfo.m_DescSetLayout[live].Init(GetResourceManager(), m_CreationInfo, live,
&CreateInfo);
if((CreateInfo.flags & (VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT |
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)) ==
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT)
{
// fetch actual offsets. Sizes we defer due to possible mutable descriptors
rdcarray<DescSetLayout::Binding> &bindings = m_CreationInfo.m_DescSetLayout[live].bindings;
for(uint32_t b = 0; b < bindings.size(); b++)
{
if(bindings[b].layoutDescType == VK_DESCRIPTOR_TYPE_MAX_ENUM)
continue;
VkDeviceSize offs = 0;
ObjDisp(device)->GetDescriptorSetLayoutBindingOffsetEXT(Unwrap(device), Unwrap(layout),
b, &offs);
bindings[b].elemOffset = offs & 0xffffffffU;
RDCASSERTEQUAL(bindings[b].elemOffset, offs);
}
}
}
AddResource(SetLayout, ResourceType::ShaderBinding, "Descriptor Layout");
@@ -485,7 +505,7 @@ VkResult WrappedVulkan::vkCreateDescriptorSetLayout(VkDevice device,
record->descInfo = new DescriptorSetData();
record->descInfo->layout = new DescSetLayout();
record->descInfo->layout->Init(GetResourceManager(), m_CreationInfo, pCreateInfo);
record->descInfo->layout->Init(GetResourceManager(), m_CreationInfo, id, pCreateInfo);
for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++)
{
@@ -504,7 +524,7 @@ VkResult WrappedVulkan::vkCreateDescriptorSetLayout(VkDevice device,
{
GetResourceManager()->AddLiveResource(id, *pSetLayout);
m_CreationInfo.m_DescSetLayout[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo);
m_CreationInfo.m_DescSetLayout[id].Init(GetResourceManager(), m_CreationInfo, id, pCreateInfo);
}
}
@@ -4370,10 +4370,28 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
m_PhysicalDeviceData.maxMemoryAllocationSize = 0x80000000U;
}
VulkanCreationInfo::pushConstantDescriptorStorage = ResourceIDGen::GetNewUniqueID();
VulkanCreationInfo::descriptorSetStorage.resize(
m_PhysicalDeviceData.props.limits.maxBoundDescriptorSets);
for(size_t i = 0; i < VulkanCreationInfo::descriptorSetStorage.size(); i++)
VulkanCreationInfo::descriptorSetStorage[i] = ResourceIDGen::GetNewUniqueID();
ChooseMemoryIndices();
if(DescriptorBuffers())
{
VulkanCreationInfo::descriptorBufferStorage.resize(
m_DescriptorBufferProperties.maxDescriptorBufferBindings);
VulkanCreationInfo::inlineBufferStorage.resize(
m_DescriptorBufferProperties.maxDescriptorBufferBindings);
for(size_t i = 0; i < VulkanCreationInfo::descriptorBufferStorage.size(); i++)
{
VulkanCreationInfo::descriptorBufferStorage[i] = ResourceIDGen::GetNewUniqueID();
VulkanCreationInfo::inlineBufferStorage[i] = ResourceIDGen::GetNewUniqueID();
}
EstimateDescriptorFormats();
}
APIProps.vendor = GetDriverInfo().Vendor();
@@ -1914,6 +1914,13 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic
m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo,
memoryRequirements);
if(patchedusage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT)
{
ResourceId inlineDescriptorId = m_CreationInfo.m_Buffer[live].inlineDescriptorId =
ResourceIDGen::GetNewUniqueID();
m_InlineBuffers[inlineDescriptorId] = live;
}
}
if(patchedusage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)