mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Add support for VK_EXT_inline_uniform_block
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,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();
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user