Add support for VK_EXT_inline_uniform_block

This commit is contained in:
baldurk
2020-05-22 14:03:47 +01:00
parent d71dadda9d
commit e265a1bfb4
23 changed files with 655 additions and 98 deletions
@@ -1440,7 +1440,8 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
// consider it filled if any array element is filled (or it's push constants)
bool filledSlot = cblock != NULL && !cblock->bufferBacked;
for(int idx = 0; slotBinds != NULL && idx < slotBinds->count(); idx++)
filledSlot |= (*slotBinds)[idx].resourceResourceId != ResourceId();
filledSlot |=
(*slotBinds)[idx].resourceResourceId != ResourceId() || (*slotBinds)[idx].inlineBlock;
// if it's masked out by stage bits, act as if it's not filled, so it's marked in red
if(!stageBitsIncluded)
@@ -1541,6 +1542,12 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
}
else
{
if(descriptorBind && descriptorBind->inlineBlock)
{
name = tr("Inline block");
vecrange = tr("%1 bytes").arg(length);
}
if(length == byteSize)
sizestr = tr("%1 Variables, %2 bytes").arg(numvars).arg(length);
else
+15 -9
View File
@@ -40,15 +40,16 @@ struct BindingElement
{
return dynamicallyUsed == o.dynamicallyUsed && viewResourceId == o.viewResourceId &&
resourceResourceId == o.resourceResourceId && samplerResourceId == o.samplerResourceId &&
immutableSampler == o.immutableSampler && viewFormat == o.viewFormat &&
swizzle == o.swizzle && firstMip == o.firstMip && firstSlice == o.firstSlice &&
numMips == o.numMips && numSlices == o.numSlices && byteOffset == o.byteOffset &&
byteSize == o.byteSize && filter == o.filter && addressU == o.addressU &&
addressV == o.addressV && addressW == o.addressW && mipBias == o.mipBias &&
maxAnisotropy == o.maxAnisotropy && compareFunction == o.compareFunction &&
minLOD == o.minLOD && maxLOD == o.maxLOD && borderColor[0] == o.borderColor[0] &&
borderColor[1] == o.borderColor[1] && borderColor[2] == o.borderColor[2] &&
borderColor[3] == o.borderColor[3] && unnormalized == o.unnormalized;
immutableSampler == o.immutableSampler && inlineBlock == o.inlineBlock &&
viewFormat == o.viewFormat && swizzle == o.swizzle && firstMip == o.firstMip &&
firstSlice == o.firstSlice && numMips == o.numMips && numSlices == o.numSlices &&
byteOffset == o.byteOffset && byteSize == o.byteSize && filter == o.filter &&
addressU == o.addressU && addressV == o.addressV && addressW == o.addressW &&
mipBias == o.mipBias && maxAnisotropy == o.maxAnisotropy &&
compareFunction == o.compareFunction && minLOD == o.minLOD && maxLOD == o.maxLOD &&
borderColor[0] == o.borderColor[0] && borderColor[1] == o.borderColor[1] &&
borderColor[2] == o.borderColor[2] && borderColor[3] == o.borderColor[3] &&
unnormalized == o.unnormalized;
}
bool operator<(const BindingElement &o) const
{
@@ -62,6 +63,8 @@ struct BindingElement
return samplerResourceId < o.samplerResourceId;
if(!(immutableSampler == o.immutableSampler))
return immutableSampler < o.immutableSampler;
if(!(inlineBlock == o.inlineBlock))
return inlineBlock < o.inlineBlock;
if(!(viewFormat == o.viewFormat))
return viewFormat < o.viewFormat;
if(!(swizzle == o.swizzle))
@@ -170,6 +173,9 @@ since single descriptors may only be dynamically skipped by control flow.
DOCUMENT("For samplers - ``True`` if unnormalized co-ordinates are used in this sampler.");
bool unnormalized = false;
DOCUMENT("``True`` if this is an inline uniform block binding.");
bool inlineBlock = false;
DOCUMENT(R"(For samplers - the :class:`ResourceId` of the ycbcr conversion object associated with
this sampler.
)");
@@ -597,7 +597,8 @@ void VulkanReplay::FetchShaderFeedback(uint32_t eventId)
continue;
// only process array bindings
if(bindData.descriptorCount > 1)
if(bindData.descriptorCount > 1 &&
bindData.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
key.binding = (uint32_t)binding;
+8
View File
@@ -321,6 +321,10 @@ bool VkInitParams::IsSupportedVersion(uint64_t ver)
if(ver == CurrentVersion)
return true;
// 0x11 -> 0x12 - added inline uniform block support
if(ver == 0x11)
return true;
// 0x10 -> 0x11 - non-breaking changes to image state serialization
if(ver == 0x10)
return true;
@@ -957,6 +961,7 @@ FrameRefType GetRefType(VkDescriptorType descType)
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
@@ -973,6 +978,9 @@ FrameRefType GetRefType(VkDescriptorType descType)
bool IsValid(const VkWriteDescriptorSet &write, uint32_t arrayElement)
{
if(write.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
return true;
// this makes assumptions that only hold within the context of Serialise_InitialState below,
// specifically that if pTexelBufferView/pBufferInfo is set then we are using them. In the general
// case they can be garbage and we must ignore them based on the descriptorType
+11
View File
@@ -441,6 +441,9 @@ struct DescriptorSetSlot
DescriptorSetSlotImageInfo imageInfo;
ResourceId texelBufferView;
// inline uniform block
uint32_t inlineOffset;
};
DECLARE_REFLECTION_STRUCT(DescriptorSetSlotBufferInfo);
@@ -694,6 +697,7 @@ DECLARE_REFLECTION_STRUCT(VkDedicatedAllocationBufferCreateInfoNV);
DECLARE_REFLECTION_STRUCT(VkDedicatedAllocationImageCreateInfoNV);
DECLARE_REFLECTION_STRUCT(VkDedicatedAllocationMemoryAllocateInfoNV);
DECLARE_REFLECTION_STRUCT(VkDescriptorPoolCreateInfo);
DECLARE_REFLECTION_STRUCT(VkDescriptorPoolInlineUniformBlockCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkDescriptorSetAllocateInfo);
DECLARE_REFLECTION_STRUCT(VkDescriptorSetLayoutBindingFlagsCreateInfo)
DECLARE_REFLECTION_STRUCT(VkDescriptorSetLayoutCreateInfo);
@@ -810,6 +814,8 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImageFormatInfo2);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImagelessFramebufferFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImageViewImageFormatInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceIndexTypeUint8FeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceInlineUniformBlockFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceInlineUniformBlockPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceLineRasterizationFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceLineRasterizationPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMaintenance3Properties);
@@ -942,6 +948,7 @@ DECLARE_REFLECTION_STRUCT(VkValidationCacheCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkValidationFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkValidationFlagsEXT);
DECLARE_REFLECTION_STRUCT(VkWriteDescriptorSet);
DECLARE_REFLECTION_STRUCT(VkWriteDescriptorSetInlineUniformBlockEXT);
DECLARE_DESERIALISE_TYPE(VkAcquireNextImageInfoKHR);
DECLARE_DESERIALISE_TYPE(VkAcquireProfilingLockInfoKHR);
@@ -985,6 +992,7 @@ DECLARE_DESERIALISE_TYPE(VkDedicatedAllocationBufferCreateInfoNV);
DECLARE_DESERIALISE_TYPE(VkDedicatedAllocationImageCreateInfoNV);
DECLARE_DESERIALISE_TYPE(VkDedicatedAllocationMemoryAllocateInfoNV);
DECLARE_DESERIALISE_TYPE(VkDescriptorPoolCreateInfo);
DECLARE_DESERIALISE_TYPE(VkDescriptorPoolInlineUniformBlockCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkDescriptorSetAllocateInfo);
DECLARE_DESERIALISE_TYPE(VkDescriptorSetLayoutBindingFlagsCreateInfo)
DECLARE_DESERIALISE_TYPE(VkDescriptorSetLayoutCreateInfo);
@@ -1097,6 +1105,8 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceImageFormatInfo2);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceImagelessFramebufferFeatures);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceImageViewImageFormatInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceIndexTypeUint8FeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceInlineUniformBlockFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceInlineUniformBlockPropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceLineRasterizationFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceLineRasterizationPropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMaintenance3Properties);
@@ -1226,6 +1236,7 @@ DECLARE_DESERIALISE_TYPE(VkValidationCacheCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkValidationFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkValidationFlagsEXT);
DECLARE_DESERIALISE_TYPE(VkWriteDescriptorSet);
DECLARE_DESERIALISE_TYPE(VkWriteDescriptorSetInlineUniformBlockEXT);
// plain structs with no next chain
DECLARE_REFLECTION_STRUCT(VkAllocationCallbacks);
+7
View File
@@ -826,6 +826,9 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION,
},
{
VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION,
},
{
VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, VK_EXT_LINE_RASTERIZATION_SPEC_VERSION,
},
@@ -3922,6 +3925,10 @@ void WrappedVulkan::AddUsage(VulkanDrawcallTreeNode &drawNode, rdcarray<DebugMes
if(layout.bindings[bind].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
continue;
// no object to mark for usage with inline blocks
if(layout.bindings[bind].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
continue;
ResourceUsage usage = ResourceUsage(uint32_t(types[t].usage) + shad);
if(bind >= (int32_t)descset.currentBindings.size())
+9 -3
View File
@@ -53,7 +53,7 @@ struct VkInitParams
uint64_t GetSerialiseSize();
// check if a frame capture section version is supported
static const uint64_t CurrentVersion = 0x11;
static const uint64_t CurrentVersion = 0x12;
static bool IsSupportedVersion(uint64_t ver);
};
@@ -691,11 +691,12 @@ private:
struct DescriptorSetInfo
{
DescriptorSetInfo(bool p = false) : push(p) {}
DescriptorSetInfo(const DescriptorSetInfo &) = default;
DescriptorSetInfo &operator=(const DescriptorSetInfo &) = default;
DescriptorSetInfo(const DescriptorSetInfo &) = delete;
DescriptorSetInfo &operator=(const DescriptorSetInfo &) = delete;
~DescriptorSetInfo() { clear(); }
ResourceId layout;
rdcarray<DescriptorSetSlot *> currentBindings;
bytebuf inlineData;
bool push;
void clear()
@@ -704,6 +705,7 @@ private:
for(size_t i = 0; i < currentBindings.size(); i++)
delete[] currentBindings[i];
inlineData.clear();
currentBindings.clear();
}
};
@@ -999,6 +1001,10 @@ public:
{
return m_DescriptorSetState[descSet].currentBindings;
}
const bytebuf &GetCurrentDescSetInlineData(ResourceId descSet)
{
return m_DescriptorSetState[descSet].inlineData;
}
uint32_t GetReadbackMemoryIndex(uint32_t resourceCompatibleBitmask);
uint32_t GetUploadMemoryIndex(uint32_t resourceCompatibleBitmask);
+84 -7
View File
@@ -1705,20 +1705,25 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
delete[] a;
for(VkBufferView *a : bufViewWrites)
delete[] a;
for(VkWriteDescriptorSetInlineUniformBlockEXT *a : inlineWrites)
delete a;
}
rdcarray<VkDescriptorImageInfo *> imgWrites;
rdcarray<VkDescriptorBufferInfo *> bufWrites;
rdcarray<VkBufferView *> bufViewWrites;
rdcarray<VkWriteDescriptorSetInlineUniformBlockEXT *> inlineWrites;
} alloced;
rdcarray<VkDescriptorImageInfo *> &allocImgWrites = alloced.imgWrites;
rdcarray<VkDescriptorBufferInfo *> &allocBufWrites = alloced.bufWrites;
rdcarray<VkBufferView *> &allocBufViewWrites = alloced.bufViewWrites;
rdcarray<VkWriteDescriptorSetInlineUniformBlockEXT *> &allocInlineWrites = alloced.inlineWrites;
// one for each descriptor type. 1 of each to start with, we then increment for each descriptor
// we need to allocate
VkDescriptorPoolSize poolSizes[11] = {
VkDescriptorPoolSize poolSizes[12] = {
{VK_DESCRIPTOR_TYPE_SAMPLER, 1},
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1},
{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1},
@@ -1730,11 +1735,23 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1},
{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1},
{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1},
{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, 0},
};
VkDescriptorPoolInlineUniformBlockCreateInfoEXT inlineCreateInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT,
};
static const uint32_t InlinePoolIndex = 11;
uint32_t poolSizeCount = InlinePoolIndex;
// count up our own
for(size_t i = 0; i < newBindingsCount; i++)
{
RDCASSERT(newBindings[i].descriptorType < ARRAY_COUNT(poolSizes), newBindings[i].descriptorType);
poolSizes[newBindings[i].descriptorType].descriptorCount += newBindings[i].descriptorCount;
}
const rdcarray<ResourceId> &pipeDescSetLayouts =
creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts;
@@ -1827,19 +1844,38 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
uint32_t maxDescriptorSetInputAttachments =
m_pDriver->GetDeviceProps().limits.maxDescriptorSetInputAttachments;
uint32_t maxDescriptorSetInlineUniformBlocks = 0;
uint32_t maxPerStageDescriptorInlineUniformBlocks[6] = {};
if(m_pDriver->GetExtensions(NULL).ext_EXT_inline_uniform_block)
{
VkPhysicalDeviceInlineUniformBlockPropertiesEXT inlineProps = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT,
};
VkPhysicalDeviceProperties2 availBase = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
availBase.pNext = &inlineProps;
m_pDriver->vkGetPhysicalDeviceProperties2(m_pDriver->GetPhysDev(), &availBase);
maxDescriptorSetInlineUniformBlocks = inlineProps.maxDescriptorSetInlineUniformBlocks;
for(size_t i = 0; i < ARRAY_COUNT(maxPerStageDescriptorInlineUniformBlocks); i++)
maxPerStageDescriptorInlineUniformBlocks[i] =
inlineProps.maxPerStageDescriptorInlineUniformBlocks;
}
bool error = false;
#define UPDATE_AND_CHECK_LIMIT(maxLimit) \
if(!error) \
{ \
if(bind.descriptorCount > maxLimit) \
if(descriptorCount > maxLimit) \
{ \
error = true; \
RDCWARN("Limit %s is exceeded. Cannot patch in required descriptor(s).", #maxLimit); \
} \
else \
{ \
maxLimit -= bind.descriptorCount; \
maxLimit -= descriptorCount; \
} \
}
@@ -1850,14 +1886,14 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
{ \
if(newBind.stageFlags & (1U << sbit)) \
{ \
if(bind.descriptorCount > maxLimit[sbit]) \
if(descriptorCount > maxLimit[sbit]) \
{ \
error = true; \
RDCWARN("Limit %s is exceeded. Cannot patch in required descriptor(s).", #maxLimit); \
} \
else \
{ \
maxLimit[sbit] -= bind.descriptorCount; \
maxLimit[sbit] -= descriptorCount; \
} \
} \
} \
@@ -1895,7 +1931,15 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
continue;
// make room in the pool
poolSizes[bind.descriptorType].descriptorCount += bind.descriptorCount;
if(bind.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
poolSizes[InlinePoolIndex].descriptorCount += bind.descriptorCount;
inlineCreateInfo.maxInlineUniformBlockBindings++;
}
else
{
poolSizes[bind.descriptorType].descriptorCount += bind.descriptorCount;
}
VkDescriptorSetLayoutBinding newBind;
// offset the binding. We offset all sets to make it easier for patching - don't need to
@@ -1917,6 +1961,8 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
else
newBind.stageFlags = bind.stageFlags;
uint32_t descriptorCount = bind.descriptorCount;
switch(bind.descriptorType)
{
case VK_DESCRIPTOR_TYPE_SAMPLER:
@@ -1965,6 +2011,11 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
UPDATE_AND_CHECK_LIMIT(maxDescriptorSetInputAttachments);
UPDATE_AND_CHECK_STAGE_LIMIT(maxPerStageDescriptorInputAttachments);
break;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
descriptorCount = 1;
UPDATE_AND_CHECK_LIMIT(maxDescriptorSetInlineUniformBlocks);
UPDATE_AND_CHECK_STAGE_LIMIT(maxPerStageDescriptorInlineUniformBlocks);
break;
default: break;
}
@@ -2017,9 +2068,15 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
// 1 set for each layout
poolCreateInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
poolCreateInfo.maxSets = (uint32_t)setLayouts.size();
poolCreateInfo.poolSizeCount = ARRAY_COUNT(poolSizes);
poolCreateInfo.poolSizeCount = poolSizeCount;
poolCreateInfo.pPoolSizes = poolSizes;
if(inlineCreateInfo.maxInlineUniformBlockBindings > 0)
{
poolCreateInfo.poolSizeCount++;
poolCreateInfo.pNext = &inlineCreateInfo;
}
// create descriptor pool with enough space for our descriptors
vkr = m_pDriver->vkCreateDescriptorPool(dev, &poolCreateInfo, NULL, &descpool);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
@@ -2126,9 +2183,29 @@ void VulkanReplay::PatchReservedDescriptors(const VulkanStatePipeline &pipe,
allocBufWrites.push_back(out);
break;
}
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
{
allocInlineWrites.push_back(new VkWriteDescriptorSetInlineUniformBlockEXT);
VkWriteDescriptorSetInlineUniformBlockEXT *inlineWrite = allocInlineWrites.back();
inlineWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
inlineWrite->pNext = NULL;
inlineWrite->dataSize = bind.descriptorCount;
inlineWrite->pData = setInfo.inlineData.data() + slot->inlineOffset;
write.pNext = inlineWrite;
break;
}
default: RDCERR("Unexpected descriptor type %d", write.descriptorType);
}
// skip validity check for inline uniform block as the descriptor count means something
// different
if(write.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
write.descriptorCount = bind.descriptorCount;
descWrites.push_back(write);
continue;
}
// start with no descriptors
write.descriptorCount = 0;
+4 -2
View File
@@ -489,7 +489,8 @@
DeclExt(KHR_performance_query); \
DeclExt(KHR_buffer_device_address); \
DeclExt(EXT_tooling_info); \
DeclExt(KHR_separate_depth_stencil_layouts);
DeclExt(KHR_separate_depth_stencil_layouts); \
DeclExt(EXT_inline_uniform_block);
// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
@@ -580,7 +581,8 @@
CheckExt(KHR_performance_query, VKXX); \
CheckExt(KHR_buffer_device_address, VK12); \
CheckExt(EXT_tooling_info, VKXX); \
CheckExt(KHR_separate_depth_stencil_layouts, VK12);
CheckExt(KHR_separate_depth_stencil_layouts, VK12); \
CheckExt(EXT_inline_uniform_block, VKXX);
#define HookInitVulkanInstanceExts_PhysDev() \
HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \
+88 -18
View File
@@ -88,6 +88,8 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
const VkDescriptorSetLayoutCreateInfo *pCreateInfo)
{
dynamicCount = 0;
inlineCount = 0;
inlineByteSize = 0;
flags = pCreateInfo->flags;
@@ -114,6 +116,12 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
dynamicCount++;
if(bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
inlineCount++;
inlineByteSize = AlignUp4(inlineByteSize + bindings[b].descriptorCount);
}
if((bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
pCreateInfo->pBindings[i].pImmutableSamplers)
@@ -126,42 +134,70 @@ void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo
}
}
void DescSetLayout::CreateBindingsArray(rdcarray<DescriptorSetSlot *> &descBindings) const
void DescSetLayout::CreateBindingsArray(bytebuf &inlineData,
rdcarray<DescriptorSetSlot *> &descBindings) const
{
uint32_t inlineOffset = 0;
descBindings.resize(bindings.size());
for(size_t i = 0; i < bindings.size(); i++)
{
descBindings[i] = new DescriptorSetSlot[bindings[i].descriptorCount];
memset(descBindings[i], 0, sizeof(DescriptorSetSlot) * bindings[i].descriptorCount);
if(bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
descBindings[i] = new DescriptorSetSlot[1];
memset(descBindings[i], 0, sizeof(DescriptorSetSlot));
descBindings[i]->inlineOffset = inlineOffset;
inlineOffset = AlignUp4(inlineOffset + bindings[i].descriptorCount);
}
else
{
descBindings[i] = new DescriptorSetSlot[bindings[i].descriptorCount];
memset(descBindings[i], 0, sizeof(DescriptorSetSlot) * bindings[i].descriptorCount);
}
}
inlineData.resize(inlineByteSize);
}
void DescSetLayout::UpdateBindingsArray(const DescSetLayout &prevLayout,
void DescSetLayout::UpdateBindingsArray(const DescSetLayout &prevLayout, bytebuf &inlineData,
rdcarray<DescriptorSetSlot *> &descBindings) const
{
// if we have fewer bindings now, delete the orphaned bindings arrays
for(size_t i = bindings.size(); i < prevLayout.bindings.size(); i++)
SAFE_DELETE_ARRAY(descBindings[i]);
inlineData.resize(inlineByteSize);
// resize to the new number of bindings
descBindings.resize(bindings.size());
uint32_t inlineOffset = 0;
// re-allocate slots and move any previous bindings that overlapped over.
for(size_t i = 0; i < bindings.size(); i++)
{
// allocate new slot array
DescriptorSetSlot *newSlots = new DescriptorSetSlot[bindings[i].descriptorCount];
memset(newSlots, 0, sizeof(DescriptorSetSlot) * bindings[i].descriptorCount);
if(bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
SAFE_DELETE_ARRAY(descBindings[i]);
descBindings[i] = new DescriptorSetSlot[1];
memset(descBindings[i], 0, sizeof(DescriptorSetSlot));
descBindings[i]->inlineOffset = inlineOffset;
inlineOffset = AlignUp4(inlineOffset + bindings[i].descriptorCount);
}
else
{
// allocate new slot array
DescriptorSetSlot *newSlots = new DescriptorSetSlot[bindings[i].descriptorCount];
memset(newSlots, 0, sizeof(DescriptorSetSlot) * bindings[i].descriptorCount);
// copy over any previous bindings that overlapped
if(i < prevLayout.bindings.size())
memcpy(newSlots, descBindings[i],
sizeof(DescriptorSetSlot) *
RDCMIN(prevLayout.bindings[i].descriptorCount, bindings[i].descriptorCount));
// copy over any previous bindings that overlapped
if(i < prevLayout.bindings.size())
memcpy(newSlots, descBindings[i],
sizeof(DescriptorSetSlot) *
RDCMIN(prevLayout.bindings[i].descriptorCount, bindings[i].descriptorCount));
// delete old array, and assign the new one
SAFE_DELETE_ARRAY(descBindings[i]);
descBindings[i] = newSlots;
// delete old array, and assign the new one
SAFE_DELETE_ARRAY(descBindings[i]);
descBindings[i] = newSlots;
}
}
}
@@ -1118,7 +1154,7 @@ void DescUpdateTemplate::Init(VulkanResourceManager *resourceMan, VulkanCreation
bindPoint = pCreateInfo->pipelineBindPoint;
dataByteSize = 0;
unwrapByteSize = 0;
texelBufferViewCount = 0;
bufferInfoCount = 0;
@@ -1128,6 +1164,8 @@ void DescUpdateTemplate::Init(VulkanResourceManager *resourceMan, VulkanCreation
{
uint32_t entrySize = 4;
size_t stride = entry.stride;
if(entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{
@@ -1145,6 +1183,19 @@ void DescUpdateTemplate::Init(VulkanResourceManager *resourceMan, VulkanCreation
imageInfoCount += entry.descriptorCount;
}
else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// a bit of magic handling. The calculation is stride * descriptorCount bytes for the data,
// plus the size of the 'base' structure. For inline uniform blocks there's no base structure
// and the data is in bytes, so stride 1.
stride = 1;
entrySize = 0;
inlineInfoCount++;
inlineByteSize += entry.descriptorCount;
inlineByteSize = AlignUp4(inlineByteSize);
}
else
{
entrySize = sizeof(VkDescriptorBufferInfo);
@@ -1152,8 +1203,8 @@ void DescUpdateTemplate::Init(VulkanResourceManager *resourceMan, VulkanCreation
bufferInfoCount += entry.descriptorCount;
}
dataByteSize =
RDCMAX(dataByteSize, entry.offset + entry.stride * entry.descriptorCount + entrySize);
unwrapByteSize =
RDCMAX(unwrapByteSize, entry.offset + stride * entry.descriptorCount + entrySize);
}
if(pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET)
@@ -1188,7 +1239,10 @@ void DescUpdateTemplate::Apply(const void *pData, DescUpdateTemplateApplication
application.bufView.reserve(texelBufferViewCount);
application.bufInfo.reserve(bufferInfoCount);
application.imgInfo.reserve(imageInfoCount);
application.inlineData.resize(inlineByteSize);
application.inlineUniform.reserve(inlineInfoCount);
uint32_t inlineOffset = 0;
for(const VkDescriptorUpdateTemplateEntry &entry : updates)
{
VkWriteDescriptorSet write = {};
@@ -1235,6 +1289,22 @@ void DescUpdateTemplate::Apply(const void *pData, DescUpdateTemplateApplication
write.pImageInfo = &application.imgInfo[idx];
}
else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
application.inlineUniform.push_back({});
VkWriteDescriptorSetInlineUniformBlockEXT &inlineWrite = application.inlineUniform.back();
inlineWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
inlineWrite.pNext = NULL;
inlineWrite.dataSize = entry.descriptorCount;
void *dst = application.inlineData.data() + inlineOffset;
memcpy(dst, src, inlineWrite.dataSize);
inlineWrite.pData = dst;
write.pNext = &inlineWrite;
write.descriptorCount = entry.descriptorCount;
}
else
{
size_t idx = application.bufInfo.size();
+10 -3
View File
@@ -60,8 +60,8 @@ struct DescSetLayout
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo);
void CreateBindingsArray(rdcarray<DescriptorSetSlot *> &descBindings) const;
void UpdateBindingsArray(const DescSetLayout &prevLayout,
void CreateBindingsArray(bytebuf &inlineData, rdcarray<DescriptorSetSlot *> &descBindings) const;
void UpdateBindingsArray(const DescSetLayout &prevLayout, bytebuf &inlineData,
rdcarray<DescriptorSetSlot *> &descBindings) const;
struct Binding
@@ -116,6 +116,9 @@ struct DescSetLayout
uint32_t dynamicCount;
VkDescriptorSetLayoutCreateFlags flags;
uint32_t inlineCount;
uint32_t inlineByteSize;
bool operator==(const DescSetLayout &other) const;
bool operator!=(const DescSetLayout &other) const { return !(*this == other); }
};
@@ -125,6 +128,8 @@ struct DescUpdateTemplateApplication
rdcarray<VkDescriptorBufferInfo> bufInfo;
rdcarray<VkDescriptorImageInfo> imgInfo;
rdcarray<VkBufferView> bufView;
rdcarray<VkWriteDescriptorSetInlineUniformBlockEXT> inlineUniform;
bytebuf inlineData;
rdcarray<VkWriteDescriptorSet> writes;
};
@@ -140,11 +145,13 @@ struct DescUpdateTemplate
VkPipelineBindPoint bindPoint;
size_t dataByteSize;
size_t unwrapByteSize;
uint32_t texelBufferViewCount;
uint32_t bufferInfoCount;
uint32_t imageInfoCount;
uint32_t inlineInfoCount;
uint32_t inlineByteSize;
rdcarray<VkDescriptorUpdateTemplateEntry> updates;
};
+98 -9
View File
@@ -52,7 +52,12 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
if((layout.flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) == 0)
{
for(size_t i = 0; i < layout.bindings.size(); i++)
initialContents.numDescriptors += layout.bindings[i].descriptorCount;
{
if(layout.bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
initialContents.numDescriptors++;
else
initialContents.numDescriptors += layout.bindings[i].descriptorCount;
}
initialContents.descriptorSlots = new DescriptorSetSlot[initialContents.numDescriptors];
RDCEraseMem(initialContents.descriptorSlots,
@@ -61,11 +66,22 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
uint32_t e = 0;
for(size_t i = 0; i < layout.bindings.size(); i++)
{
for(uint32_t b = 0; b < layout.bindings[i].descriptorCount; b++)
if(layout.bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
initialContents.descriptorSlots[e++] = record->descInfo->descBindings[i][b];
initialContents.descriptorSlots[e++] = record->descInfo->descBindings[i][0];
}
else
{
for(uint32_t b = 0; b < layout.bindings[i].descriptorCount; b++)
{
initialContents.descriptorSlots[e++] = record->descInfo->descBindings[i][b];
}
}
}
initialContents.inlineData = AllocAlignedBuffer(record->descInfo->inlineData.size());
memcpy(initialContents.inlineData, record->descInfo->inlineData.data(),
record->descInfo->inlineData.size());
}
else
{
@@ -548,9 +564,14 @@ uint64_t WrappedVulkan::GetSize_InitialState(ResourceId id, const VkInitialConte
uint32_t NumBindings = 0;
for(size_t i = 0; i < layout.bindings.size(); i++)
NumBindings += layout.bindings[i].descriptorCount;
{
if(layout.bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
NumBindings++;
else
NumBindings += layout.bindings[i].descriptorCount;
}
return 32 + NumBindings * sizeof(DescriptorSetSlot);
return 32 + NumBindings * sizeof(DescriptorSetSlot) + layout.inlineByteSize;
}
else if(initial.type == eResBuffer)
{
@@ -601,6 +622,7 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id,
{
DescriptorSetSlot *Bindings = NULL;
uint32_t NumBindings = 0;
bytebuf InlineData;
// while writing, fetching binding information from prepared initial contents
if(ser.IsWriting())
@@ -611,12 +633,24 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id,
Bindings = initial->descriptorSlots;
for(size_t i = 0; i < layout.bindings.size(); i++)
NumBindings += layout.bindings[i].descriptorCount;
{
if(layout.bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
NumBindings++;
else
NumBindings += layout.bindings[i].descriptorCount;
}
InlineData.assign(initial->inlineData, layout.inlineByteSize);
}
SERIALISE_ELEMENT_ARRAY(Bindings, NumBindings);
SERIALISE_ELEMENT(NumBindings);
if(ser.VersionAtLeast(0x12))
{
SERIALISE_ELEMENT(InlineData);
}
SERIALISE_CHECK_READ_ERRORS();
// while reading, fetch the binding information and allocate a VkWriteDescriptorSet array
@@ -638,6 +672,16 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id,
initialContents.numDescriptors = (uint32_t)layout.bindings.size();
initialContents.descriptorInfo = new VkDescriptorBufferInfo[NumBindings];
initialContents.inlineInfo = NULL;
if(layout.inlineCount > 0)
{
initialContents.inlineInfo =
new VkWriteDescriptorSetInlineUniformBlockEXT[layout.inlineCount];
initialContents.inlineData = AllocAlignedBuffer(InlineData.size());
RDCASSERTEQUAL(layout.inlineByteSize, InlineData.size());
memcpy(initialContents.inlineData, InlineData.data(), InlineData.size());
}
// if we have partially-valid arrays, we need to split up writes. The worst case will never be
// == number of bindings since that implies all arrays are valid, but it is an upper bound as
@@ -649,8 +693,11 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id,
VkWriteDescriptorSet *writes = initialContents.descriptorWrites;
VkDescriptorBufferInfo *dstData = initialContents.descriptorInfo;
VkWriteDescriptorSetInlineUniformBlockEXT *dstInline = initialContents.inlineInfo;
DescriptorSetSlot *srcData = Bindings;
byte *srcInlineData = initialContents.inlineData;
// validBinds counts up as we make a valid VkWriteDescriptorSet, so can be used to index into
// writes[] along the way as the 'latest' write.
uint32_t bind = 0;
@@ -662,6 +709,14 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id,
if(descriptorCount == 0)
continue;
uint32_t inlineSize = 0;
if(layout.bindings[j].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
inlineSize = descriptorCount;
descriptorCount = 1;
}
writes[bind].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[bind].pNext = NULL;
@@ -686,6 +741,13 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id,
VkBufferView *dstTexelBuffer = (VkBufferView *)dstData;
dstData += descriptorCount;
RDCCOMPILE_ASSERT(
sizeof(VkDescriptorImageInfo) <= sizeof(VkDescriptorBufferInfo),
"VkDescriptorBufferInfo should be large enough for all descriptor write types");
RDCCOMPILE_ASSERT(
sizeof(VkBufferView) <= sizeof(VkDescriptorBufferInfo),
"VkDescriptorBufferInfo should be large enough for all descriptor write types");
// the correct one will be set below
writes[bind].pBufferInfo = NULL;
writes[bind].pImageInfo = NULL;
@@ -700,10 +762,26 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id,
// For the array case we batch up updates as much as possible, iterating along the array and
// skipping any invalid descriptors.
if(writes[bind].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// handle inline uniform block specially because the descriptorCount doesn't mean what it
// normally means in the write.
dstInline->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
dstInline->pNext = NULL;
dstInline->pData = srcInlineData + src->inlineOffset;
dstInline->dataSize = inlineSize;
writes[bind].pNext = dstInline;
writes[bind].descriptorCount = inlineSize;
bind++;
dstInline++;
}
// quick check for slots that were completely uninitialised and so don't have valid data
if(descriptorCount == 1 && src->texelBufferView == ResourceId() &&
src->imageInfo.sampler == ResourceId() && src->imageInfo.imageView == ResourceId() &&
src->bufferInfo.buffer == ResourceId())
else if(descriptorCount == 1 && src->texelBufferView == ResourceId() &&
src->imageInfo.sampler == ResourceId() &&
src->imageInfo.imageView == ResourceId() && src->bufferInfo.buffer == ResourceId())
{
// do nothing - don't increment bind so that the same write descriptor is used next time.
continue;
@@ -1306,6 +1384,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
// need to blat over the current descriptor set contents, so these are available
// when we want to fetch pipeline state
rdcarray<DescriptorSetSlot *> &bindings = m_DescriptorSetState[id].currentBindings;
bytebuf &inlineData = m_DescriptorSetState[id].inlineData;
for(uint32_t i = 0; i < initial.numDescriptors; i++)
{
@@ -1313,6 +1392,16 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
DescriptorSetSlot *bind = bindings[writes[i].dstBinding];
if(writes[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
VkWriteDescriptorSetInlineUniformBlockEXT *inlineWrite =
(VkWriteDescriptorSetInlineUniformBlockEXT *)FindNextStruct(
&writes[i], VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT);
memcpy(inlineData.data() + bind->inlineOffset + writes[i].dstArrayElement,
inlineWrite->pData, inlineWrite->dataSize);
continue;
}
for(uint32_t d = 0; d < writes[i].descriptorCount; d++)
{
uint32_t idx = writes[i].dstArrayElement + d;
+4
View File
@@ -117,6 +117,8 @@ struct VkInitialContents
SAFE_DELETE_ARRAY(descriptorSlots);
SAFE_DELETE_ARRAY(descriptorWrites);
SAFE_DELETE_ARRAY(descriptorInfo);
SAFE_DELETE_ARRAY(inlineInfo);
FreeAlignedBuffer(inlineData);
rm->ResourceTypeRelease(GetWrapped(buf));
rm->ResourceTypeRelease(GetWrapped(img));
@@ -147,6 +149,8 @@ struct VkInitialContents
DescriptorSetSlot *descriptorSlots;
VkWriteDescriptorSet *descriptorWrites;
VkDescriptorBufferInfo *descriptorInfo;
VkWriteDescriptorSetInlineUniformBlockEXT *inlineInfo;
byte *inlineData;
uint32_t numDescriptors;
// for plain resources, we store the resource type and memory allocation details of the contents
+17 -5
View File
@@ -105,6 +105,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
COPY_STRUCT(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV, \
VkDedicatedAllocationImageCreateInfoNV); \
COPY_STRUCT(VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, VkDescriptorPoolCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT, \
VkDescriptorPoolInlineUniformBlockCreateInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, \
VkDescriptorSetLayoutBindingFlagsCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, VkDescriptorSetLayoutSupport); \
@@ -224,6 +226,10 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPhysicalDeviceImagelessFramebufferFeatures) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, \
VkPhysicalDeviceIndexTypeUint8FeaturesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, \
VkPhysicalDeviceInlineUniformBlockFeaturesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT, \
VkPhysicalDeviceInlineUniformBlockPropertiesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, \
VkPhysicalDeviceMaintenance3Properties); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT, \
@@ -415,6 +421,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
COPY_STRUCT(VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, VkTimelineSemaphoreSubmitInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT, VkValidationCacheCreateInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, VkValidationFeaturesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT, \
VkWriteDescriptorSetInlineUniformBlockEXT); \
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO, \
VkLayerInstanceCreateInfo); \
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, VkLayerDeviceCreateInfo); \
@@ -566,7 +574,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR: \
case VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR: \
case VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR: \
case VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT: \
case VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD: \
case VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT: \
@@ -617,8 +624,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX: \
@@ -664,8 +669,7 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT: \
case VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT: \
case VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD: \
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR: \
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT:
case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR:
size_t GetNextPatchSize(const void *pNext)
{
@@ -835,6 +839,9 @@ size_t GetNextPatchSize(const void *pNext)
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
memSize += info->descriptorCount * sizeof(VkDescriptorBufferInfo);
break;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
// nothing to unwrap for inline uniform blocks, it's on the next chain
break;
default: RDCERR("Unhandled descriptor type unwrapping VkWriteDescriptorSet"); break;
}
break;
@@ -1413,6 +1420,11 @@ void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem,
break;
}
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
{
// nothing to do/patch
break;
}
default: RDCERR("Unhandled descriptor type unwrapping VkWriteDescriptorSet"); break;
}
+56 -14
View File
@@ -1668,11 +1668,15 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
dst.bindings[b].type = BindType::InputAttachment;
break;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
dst.bindings[b].descriptorCount = 1;
dst.bindings[b].type = BindType::ConstantBuffer;
break;
default: dst.bindings[b].type = BindType::Unknown; RDCERR("Unexpected descriptor type");
}
dst.bindings[b].binds.resize(layoutBind.descriptorCount);
for(uint32_t a = 0; a < layoutBind.descriptorCount; a++)
dst.bindings[b].binds.resize(dst.bindings[b].descriptorCount);
for(uint32_t a = 0; a < dst.bindings[b].descriptorCount; a++)
{
VKPipe::BindingElement &dstel = dst.bindings[b].binds[a];
@@ -1680,7 +1684,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
// if we have a list of used binds, and this is an array descriptor (so would be
// expected to be in the list), check it for dynamic usage.
if(layoutBind.descriptorCount > 1 && hasUsedBinds)
if(dst.bindings[b].descriptorCount > 1 && hasUsedBinds)
{
// if we exhausted the list, all other elements are unused
if(usedBindsSize == 0)
@@ -1769,11 +1773,10 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
}
}
}
if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
else if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
{
ResourceId viewid = info[a].imageInfo.imageView;
@@ -1804,8 +1807,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
dst.bindings[b].binds[a].numSlices = 1;
}
}
if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
else if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
{
ResourceId viewid = info[a].texelBufferView;
@@ -1842,10 +1845,18 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
dst.bindings[b].binds[a].byteSize = 0;
}
}
if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
else if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
dst.bindings[b].binds[a].viewResourceId = ResourceId();
dst.bindings[b].binds[a].resourceResourceId = ResourceId();
dst.bindings[b].binds[a].inlineBlock = true;
dst.bindings[b].binds[a].byteOffset = 0;
dst.bindings[b].binds[a].byteSize = layoutBind.descriptorCount;
}
else if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
{
dst.bindings[b].binds[a].viewResourceId = ResourceId();
@@ -1963,6 +1974,37 @@ void VulkanReplay::FillCBufferVariables(ResourceId pipeline, ResourceId shader,
if(c.bufferBacked)
{
const rdcarray<VulkanStatePipeline::DescriptorAndOffsets> &descSets =
(refl.stage == ShaderStage::Compute) ? m_pDriver->m_RenderState.compute.descSets
: m_pDriver->m_RenderState.graphics.descSets;
Bindpoint bind = mapping.constantBlocks[c.bindPoint];
if(bind.bindset < descSets.count())
{
ResourceId set = descSets[bind.bindset].descSet;
const WrappedVulkan::DescriptorSetInfo &setData = m_pDriver->m_DescriptorSetState[set];
ResourceId layoutId = setData.layout;
if(bind.bind < m_pDriver->m_CreationInfo.m_DescSetLayout[layoutId].bindings.count())
{
const DescSetLayout::Binding &layoutBind =
m_pDriver->m_CreationInfo.m_DescSetLayout[layoutId].bindings[bind.bind];
if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
bytebuf inlineData;
inlineData.assign(
setData.inlineData.data() + setData.currentBindings[bind.bind]->inlineOffset,
layoutBind.descriptorCount);
StandardFillCBufferVariables(refl.resourceId, c.variables, outvars, inlineData);
return;
}
}
}
StandardFillCBufferVariables(refl.resourceId, c.variables, outvars, data);
}
else
+3
View File
@@ -1040,6 +1040,8 @@ struct DescSetLayout;
struct DescriptorSetData
{
DescriptorSetData() : layout(NULL) {}
DescriptorSetData(const DescriptorSetData &) = delete;
DescriptorSetData &operator=(const DescriptorSetData &) = delete;
~DescriptorSetData()
{
for(size_t i = 0; i < descBindings.size(); i++)
@@ -1052,6 +1054,7 @@ struct DescriptorSetData
// descriptor set bindings for this descriptor set. Filled out on
// create from the layout.
rdcarray<DescriptorSetSlot *> descBindings;
bytebuf inlineData;
// lock protecting bindFrameRefs and bindMemRefs
Threading::CriticalSection refLock;
+81 -6
View File
@@ -572,6 +572,16 @@ SERIALISE_VK_HANDLES();
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, \
VkPhysicalDeviceIndexTypeUint8FeaturesEXT) \
\
/* VK_EXT_inline_uniform_block */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, \
VkPhysicalDeviceInlineUniformBlockFeaturesEXT) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT, \
VkPhysicalDeviceInlineUniformBlockPropertiesEXT) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT, \
VkWriteDescriptorSetInlineUniformBlockEXT) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT, \
VkDescriptorPoolInlineUniformBlockCreateInfoEXT) \
\
/* VK_EXT_line_rasterization */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, \
VkPhysicalDeviceLineRasterizationFeaturesEXT) \
@@ -1048,12 +1058,6 @@ SERIALISE_VK_HANDLES();
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT) \
\
/* VK_EXT_inline_uniform_block */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT) \
\
/* VK_EXT_pipeline_creation_cache_control */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT) \
\
@@ -4015,6 +4019,7 @@ void DoSerialise(SerialiserType &ser, DescriptorSetSlot &el)
SERIALISE_MEMBER(bufferInfo).TypedAs("VkDescriptorBufferInfo"_lit);
SERIALISE_MEMBER(imageInfo).TypedAs("VkDescriptorImageInfo"_lit);
SERIALISE_MEMBER(texelBufferView).TypedAs("VkBufferView"_lit);
SERIALISE_MEMBER(inlineOffset).Named("InlineDataOffset"_lit);
}
template <typename SerialiserType>
@@ -6909,6 +6914,76 @@ void Deserialise(const VkPhysicalDeviceIndexTypeUint8FeaturesEXT &el)
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceInlineUniformBlockFeaturesEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(inlineUniformBlock);
SERIALISE_MEMBER(descriptorBindingInlineUniformBlockUpdateAfterBind);
}
template <>
void Deserialise(const VkPhysicalDeviceInlineUniformBlockFeaturesEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceInlineUniformBlockPropertiesEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(maxInlineUniformBlockSize);
SERIALISE_MEMBER(maxPerStageDescriptorInlineUniformBlocks);
SERIALISE_MEMBER(maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks);
SERIALISE_MEMBER(maxDescriptorSetInlineUniformBlocks);
SERIALISE_MEMBER(maxDescriptorSetUpdateAfterBindInlineUniformBlocks);
}
template <>
void Deserialise(const VkPhysicalDeviceInlineUniformBlockPropertiesEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkWriteDescriptorSetInlineUniformBlockEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(dataSize);
SERIALISE_MEMBER_ARRAY(pData, dataSize);
}
template <>
void Deserialise(const VkWriteDescriptorSetInlineUniformBlockEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDescriptorPoolInlineUniformBlockCreateInfoEXT &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(maxInlineUniformBlockBindings);
}
template <>
void Deserialise(const VkDescriptorPoolInlineUniformBlockCreateInfoEXT &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceLineRasterizationFeaturesEXT &el)
{
+13 -12
View File
@@ -186,6 +186,7 @@ public:
const rdcarray<DescriptorSetSlot *> &curBinds =
m_pDriver->GetCurrentDescSetBindings(descSets[set].descSet);
const bytebuf &curInline = m_pDriver->GetCurrentDescSetInlineData(descSets[set].descSet);
const DescSetLayout &setLayout = m_Creation.m_DescSetLayout[pipeLayout.descSetLayouts[set]];
for(size_t bind = 0; bind < setLayout.bindings.size(); bind++)
@@ -248,6 +249,17 @@ public:
}
break;
}
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
{
// push directly into the buffer cache from the inline data
BindpointIndex idx;
idx.bindset = (int32_t)set;
idx.bind = (int32_t)bind;
idx.arrayIndex = 0;
bufferCache[idx].assign(curInline.data() + curSlots->inlineOffset,
bindLayout.descriptorCount);
break;
}
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
{
@@ -315,18 +327,7 @@ public:
virtual uint64_t GetBufferLength(BindpointIndex bind) override
{
bool valid = true;
const VkDescriptorBufferInfo &bufData =
GetDescriptor<VkDescriptorBufferInfo>("reading buffer length", bind, valid);
if(valid)
{
if(bufData.range != VK_WHOLE_SIZE)
return bufData.range;
return m_Creation.m_Buffer[GetResID(bufData.buffer)].size - bufData.offset;
}
return 0;
return PopulateBuffer(bind).size();
}
virtual void ReadBufferValue(BindpointIndex bind, uint64_t offset, uint64_t byteSize,
+19
View File
@@ -391,6 +391,7 @@ void VulkanRenderState::BindDescriptorSet(WrappedVulkan *vk, const DescSetLayout
rdcarray<VkDescriptorImageInfo *> allocImgWrites;
rdcarray<VkDescriptorBufferInfo *> allocBufWrites;
rdcarray<VkBufferView *> allocBufViewWrites;
rdcarray<VkWriteDescriptorSetInlineUniformBlockEXT *> allocInlineWrites;
const WrappedVulkan::DescriptorSetInfo &setInfo = vk->GetDebugManager()->GetDescSetInfo(descSet);
@@ -445,6 +446,22 @@ void VulkanRenderState::BindDescriptorSet(WrappedVulkan *vk, const DescSetLayout
push.pImageInfo = dst;
allocImgWrites.push_back(dst);
}
else if(push.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
allocInlineWrites.push_back(new VkWriteDescriptorSetInlineUniformBlockEXT);
VkWriteDescriptorSetInlineUniformBlockEXT *inlineWrite = allocInlineWrites.back();
inlineWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
inlineWrite->pNext = NULL;
inlineWrite->dataSize = bind.descriptorCount;
inlineWrite->pData = setInfo.inlineData.data() + slots->inlineOffset;
push.pNext = inlineWrite;
push.descriptorCount = bind.descriptorCount;
writes.push_back(push);
// skip validity checks
continue;
}
else
{
VkDescriptorBufferInfo *dst = new VkDescriptorBufferInfo[push.descriptorCount];
@@ -514,6 +531,8 @@ void VulkanRenderState::BindDescriptorSet(WrappedVulkan *vk, const DescSetLayout
delete[] a;
for(VkBufferView *a : allocBufViewWrites)
delete[] a;
for(VkWriteDescriptorSetInlineUniformBlockEXT *a : allocInlineWrites)
delete a;
}
}
@@ -727,8 +727,10 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman
{
for(size_t i = 0; i < ARRAY_COUNT(BakedCmdBufferInfo::pushDescriptorID[p]); i++)
{
m_DescriptorSetState[m_BakedCmdBufferInfo[BakedCommandBuffer].pushDescriptorID[p][i]] =
DescriptorSetInfo(true);
DescriptorSetInfo &pushDesc =
m_DescriptorSetState[m_BakedCmdBufferInfo[BakedCommandBuffer].pushDescriptorID[p][i]];
pushDesc.clear();
pushDesc.push = true;
}
}
@@ -3946,15 +3948,16 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo
const DescSetLayout &desclayout = m_CreationInfo.m_DescSetLayout[descSetLayouts[set]];
rdcarray<DescriptorSetSlot *> &bindings = m_DescriptorSetState[setId].currentBindings;
bytebuf &inlineData = m_DescriptorSetState[setId].inlineData;
ResourceId prevLayout = m_DescriptorSetState[setId].layout;
if(prevLayout == ResourceId())
{
desclayout.CreateBindingsArray(bindings);
desclayout.CreateBindingsArray(inlineData, bindings);
}
else if(prevLayout != descSetLayouts[set])
{
desclayout.UpdateBindingsArray(m_CreationInfo.m_DescSetLayout[prevLayout], bindings);
desclayout.UpdateBindingsArray(m_CreationInfo.m_DescSetLayout[prevLayout], inlineData, bindings);
}
m_DescriptorSetState[setId].layout = descSetLayouts[set];
@@ -4019,6 +4022,14 @@ void WrappedVulkan::ApplyPushDescriptorWrites(VkPipelineBindPoint pipelineBindPo
(*bind)[curIdx].imageInfo.SetFrom(writeDesc.pImageInfo[d], sampler, imageView);
}
}
else if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
VkWriteDescriptorSetInlineUniformBlockEXT *inlineWrite =
(VkWriteDescriptorSetInlineUniformBlockEXT *)FindNextStruct(
&writeDesc, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT);
memcpy(inlineData.data() + (*bind)->inlineOffset + writeDesc.dstArrayElement,
inlineWrite->pData, inlineWrite->dataSize);
}
else
{
for(uint32_t d = 0; d < writeDesc.descriptorCount; d++, curIdx++)
@@ -4223,6 +4234,10 @@ void WrappedVulkan::vkCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
imInfos[j].imageLayout = pDescriptorWrites[i].pImageInfo[j].imageLayout;
}
}
else if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// nothing to unwrap, the next chain contains the data which we can leave as-is
}
else
{
unwrappedWrites[i].pBufferInfo = bufInfos;
@@ -4285,6 +4300,10 @@ void WrappedVulkan::vkCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
record->MarkResourceFrameReferenced(GetResID(write.pImageInfo[d].sampler),
eFrameRef_Read);
}
else if(write.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// no bindings in this type
}
else
{
record->MarkBufferFrameReferenced(GetRecord(write.pBufferInfo[d].buffer),
@@ -4437,7 +4456,7 @@ void WrappedVulkan::vkCmdPushDescriptorSetWithTemplateKHR(
DescUpdateTemplate *tempInfo = GetRecord(descriptorUpdateTemplate)->descTemplateInfo;
// allocate the whole blob of memory
byte *memory = GetTempMemory(tempInfo->dataByteSize);
byte *memory = GetTempMemory(tempInfo->unwrapByteSize);
// iterate the entries, copy the descriptor data and unwrap
for(const VkDescriptorUpdateTemplateEntry &entry : tempInfo->updates)
@@ -4495,6 +4514,11 @@ void WrappedVulkan::vkCmdPushDescriptorSetWithTemplateKHR(
}
}
}
else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// memcpy the data
memcpy(dst, src, entry.descriptorCount);
}
else
{
for(uint32_t d = 0; d < entry.descriptorCount; d++)
@@ -96,6 +96,10 @@ VkWriteDescriptorSet WrappedVulkan::UnwrapInfo(const VkWriteDescriptorSet *write
{
VkWriteDescriptorSet ret = *writeDesc;
// nothing to unwrap for inline uniform block
if(ret.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
return ret;
byte *memory = GetTempMemory(sizeof(VkDescriptorBufferInfo) * writeDesc->descriptorCount);
VkDescriptorBufferInfo *bufInfos = (VkDescriptorBufferInfo *)memory;
@@ -448,7 +452,7 @@ bool WrappedVulkan::Serialise_vkAllocateDescriptorSets(SerialiserType &ser, VkDe
// this is stored in the resource record on capture, we need to be able to look to up
m_DescriptorSetState[live].layout = layoutId;
m_CreationInfo.m_DescSetLayout[layoutId].CreateBindingsArray(
m_DescriptorSetState[live].currentBindings);
m_DescriptorSetState[live].inlineData, m_DescriptorSetState[live].currentBindings);
}
AddResource(DescriptorSet, ResourceType::ShaderBinding, "Descriptor Set");
@@ -521,7 +525,8 @@ VkResult WrappedVulkan::vkAllocateDescriptorSets(VkDevice device,
record->descInfo = new DescriptorSetData();
record->descInfo->layout = layoutRecord->descInfo->layout;
record->descInfo->layout->CreateBindingsArray(record->descInfo->descBindings);
record->descInfo->layout->CreateBindingsArray(record->descInfo->inlineData,
record->descInfo->descBindings);
}
else
{
@@ -644,6 +649,7 @@ void WrappedVulkan::ReplayDescriptorSetWrite(VkDevice device, const VkWriteDescr
valid &= (writeDesc.pBufferInfo[i].buffer != VK_NULL_HANDLE);
break;
}
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: break;
default: RDCERR("Unexpected descriptor type %d", writeDesc.descriptorType);
}
@@ -655,6 +661,7 @@ void WrappedVulkan::ReplayDescriptorSetWrite(VkDevice device, const VkWriteDescr
// update our local tracking
rdcarray<DescriptorSetSlot *> &bindings =
m_DescriptorSetState[GetResID(writeDesc.dstSet)].currentBindings;
bytebuf &inlineData = m_DescriptorSetState[GetResID(writeDesc.dstSet)].inlineData;
{
RDCASSERT(writeDesc.dstBinding < bindings.size());
@@ -712,6 +719,14 @@ void WrappedVulkan::ReplayDescriptorSetWrite(VkDevice device, const VkWriteDescr
(*bind)[curIdx].imageInfo.SetFrom(writeDesc.pImageInfo[d], sampler, imageView);
}
}
else if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
VkWriteDescriptorSetInlineUniformBlockEXT *inlineWrite =
(VkWriteDescriptorSetInlineUniformBlockEXT *)FindNextStruct(
&writeDesc, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT);
memcpy(inlineData.data() + (*bind)->inlineOffset + writeDesc.dstArrayElement,
inlineWrite->pData, inlineWrite->dataSize);
}
else
{
for(uint32_t d = 0; d < writeDesc.descriptorCount; d++, curIdx++)
@@ -768,6 +783,21 @@ void WrappedVulkan::ReplayDescriptorSetCopy(VkDevice device, const VkCopyDescrip
for(uint32_t d = 0; d < copyDesc.descriptorCount; d++, curSrcIdx++, curDstIdx++)
{
if(layoutSrcBinding->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// inline uniform blocks are special, the descriptor count is a byte count. The layouts may
// not match so inline offsets might not match, so we just copy the data and break.
bytebuf &dstInlineData = m_DescriptorSetState[dstSetId].inlineData;
bytebuf &srcInlineData = m_DescriptorSetState[srcSetId].inlineData;
memcpy(dstInlineData.data() + (*dstbind)->inlineOffset + copyDesc.dstArrayElement,
srcInlineData.data() + (*srcbind)->inlineOffset + copyDesc.srcArrayElement,
copyDesc.descriptorCount);
break;
}
// allow consecutive descriptor bind updates. See vkUpdateDescriptorSets for more
// explanation
if(curSrcIdx >= layoutSrcBinding->descriptorCount)
@@ -921,6 +951,10 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount,
imInfos[j].imageLayout = pDescriptorWrites[i].pImageInfo[j].imageLayout;
}
}
else if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// nothing to unwrap, the next chain contains the data which we can leave as-is
}
else
{
unwrappedWrites[i].pBufferInfo = bufInfos;
@@ -1026,6 +1060,7 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount,
RDCASSERT(descWrite.dstBinding < record->descInfo->descBindings.size());
DescriptorSetSlot **binding = &record->descInfo->descBindings[descWrite.dstBinding];
bytebuf &inlineData = record->descInfo->inlineData;
const DescSetLayout::Binding *layoutBinding = &layout.bindings[descWrite.dstBinding];
@@ -1098,6 +1133,17 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount,
bind.imageInfo.SetFrom(descWrite.pImageInfo[d], sampler, imageView);
}
else if(descWrite.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
VkWriteDescriptorSetInlineUniformBlockEXT *inlineWrite =
(VkWriteDescriptorSetInlineUniformBlockEXT *)FindNextStruct(
&descWrite, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT);
memcpy(inlineData.data() + bind.inlineOffset + descWrite.dstArrayElement,
inlineWrite->pData, inlineWrite->dataSize);
// break now because the descriptorCount is not the number of descriptors
break;
}
else
{
bind.bufferInfo.SetFrom(descWrite.pBufferInfo[d]);
@@ -1143,6 +1189,23 @@ void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount,
for(uint32_t d = 0; d < pDescriptorCopies[i].descriptorCount; d++, curSrcIdx++, curDstIdx++)
{
if(srclayoutBinding->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// inline uniform blocks are special, the descriptor count is a byte count. The layouts
// may not match so inline offsets might not match, so we just copy the data and break.
bytebuf &dstInlineData = dstrecord->descInfo->inlineData;
bytebuf &srcInlineData = srcrecord->descInfo->inlineData;
memcpy(dstInlineData.data() + (*dstbinding)->inlineOffset +
pDescriptorCopies[i].dstArrayElement,
srcInlineData.data() + (*srcbinding)->inlineOffset +
pDescriptorCopies[i].srcArrayElement,
pDescriptorCopies[i].descriptorCount);
break;
}
if(curDstIdx >= dstlayoutBinding->descriptorCount)
{
dstlayoutBinding++;
@@ -1307,7 +1370,7 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate(
{
// allocate the whole blob of memory
byte *memory = GetTempMemory(tempInfo->dataByteSize);
byte *memory = GetTempMemory(tempInfo->unwrapByteSize);
// iterate the entries, copy the descriptor data and unwrap
for(const VkDescriptorUpdateTemplateEntry &entry : tempInfo->updates)
@@ -1358,6 +1421,11 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate(
src += entry.stride;
}
}
else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
// memcpy the data
memcpy(dst, src, entry.descriptorCount);
}
else
{
for(uint32_t d = 0; d < entry.descriptorCount; d++)
@@ -1411,6 +1479,7 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate(
RDCASSERT(entry.dstBinding < record->descInfo->descBindings.size());
DescriptorSetSlot **binding = &record->descInfo->descBindings[entry.dstBinding];
bytebuf &inlineData = record->descInfo->inlineData;
const DescSetLayout::Binding *layoutBinding = &layout.bindings[entry.dstBinding];
@@ -1472,6 +1541,14 @@ void WrappedVulkan::vkUpdateDescriptorSetWithTemplate(
bind.imageInfo.SetFrom(srcInfo, sampler, imageView);
}
else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
{
memcpy(inlineData.data() + bind.inlineOffset + entry.dstArrayElement, src,
entry.descriptorCount);
// break now because the descriptorCount is not the number of descriptors
break;
}
else
{
bind.bufferInfo.SetFrom(*(const VkDescriptorBufferInfo *)src);
@@ -2523,6 +2523,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
CHECK_PHYS_EXT_FEATURE(performanceCounterMultipleQueryPools);
}
END_PHYS_EXT_CHECK();
BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceInlineUniformBlockFeaturesEXT,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT);
{
CHECK_PHYS_EXT_FEATURE(inlineUniformBlock);
CHECK_PHYS_EXT_FEATURE(descriptorBindingInlineUniformBlockUpdateAfterBind);
}
END_PHYS_EXT_CHECK();
}
if(availFeatures.depthClamp)
+1
View File
@@ -1868,6 +1868,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::BindingElement &el)
SERIALISE_MEMBER(maxLOD);
SERIALISE_MEMBER(borderColor);
SERIALISE_MEMBER(unnormalized);
SERIALISE_MEMBER(inlineBlock);
SERIALISE_MEMBER(ycbcrSampler);