mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
Report vulkan dynamic offsets separately for manual application
* Baking these into descriptors when we get arbitrary 'GetDescriptor' queries independent of the bound descriptor sets is not possible - a descriptor set could be in theory bound twice to two places with different dynamic offsets. * Instead we report these as part of the pipeline states and the abstraction & replay API consumer will need to manually apply them to get the true buffer offset. * The offsets are indexed by descriptor storage byte offset for easier processing (the dynamic offset struct can be turned into a pair and used to initialise a dict)
This commit is contained in:
@@ -419,6 +419,7 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, DescriptorAccess)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, Attachment)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, BindingElement)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, DescriptorBinding)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, DynamicOffset)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, DescriptorSet)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, ImageData)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, ImageLayout)
|
||||
|
||||
@@ -314,6 +314,39 @@ If :data:`descriptorCount` is 1 then this list has only one element and the bind
|
||||
rdcarray<BindingElement> binds;
|
||||
};
|
||||
|
||||
DOCUMENT("A dynamic offset applied to a single descriptor access.");
|
||||
struct DynamicOffset
|
||||
{
|
||||
DOCUMENT("");
|
||||
DynamicOffset() = default;
|
||||
DynamicOffset(const DynamicOffset &) = default;
|
||||
DynamicOffset &operator=(const DynamicOffset &) = default;
|
||||
|
||||
bool operator==(const DynamicOffset &o) const
|
||||
{
|
||||
return descriptorByteOffset == o.descriptorByteOffset &&
|
||||
dynamicBufferByteOffset == o.dynamicBufferByteOffset;
|
||||
}
|
||||
bool operator<(const DynamicOffset &o) const
|
||||
{
|
||||
if(!(descriptorByteOffset == o.descriptorByteOffset))
|
||||
return descriptorByteOffset < o.descriptorByteOffset;
|
||||
if(!(dynamicBufferByteOffset == o.dynamicBufferByteOffset))
|
||||
return dynamicBufferByteOffset < o.dynamicBufferByteOffset;
|
||||
return false;
|
||||
}
|
||||
DOCUMENT(R"(The offset in bytes to the descriptor in the storage.
|
||||
|
||||
:type: int
|
||||
)");
|
||||
uint64_t descriptorByteOffset = 0;
|
||||
DOCUMENT(R"(The dynamic offset to apply to the buffer in bytes.
|
||||
|
||||
:type: int
|
||||
)");
|
||||
uint64_t dynamicBufferByteOffset = 0;
|
||||
};
|
||||
|
||||
DOCUMENT("The contents of a descriptor set.");
|
||||
struct DescriptorSet
|
||||
{
|
||||
@@ -363,6 +396,16 @@ offset and size into this buffer.
|
||||
:type: bytes
|
||||
)");
|
||||
bytebuf inlineData;
|
||||
|
||||
DOCUMENT(R"(A list of dynamic offsets to be applied to specific bindings, on top of the contents
|
||||
of their descriptors.
|
||||
|
||||
.. note::
|
||||
The returned values from :meth:`PipeState.GetConstantBuffer` already have these offsets applied.
|
||||
|
||||
:type: List[VKDynamicOffset]
|
||||
)");
|
||||
rdcarray<DynamicOffset> dynamicOffsets;
|
||||
};
|
||||
|
||||
DOCUMENT("Describes the object and descriptor set bindings of a Vulkan pipeline object.");
|
||||
@@ -1477,6 +1520,7 @@ struct State
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(VKPipe::BindingElement);
|
||||
DECLARE_REFLECTION_STRUCT(VKPipe::DescriptorBinding);
|
||||
DECLARE_REFLECTION_STRUCT(VKPipe::DynamicOffset);
|
||||
DECLARE_REFLECTION_STRUCT(VKPipe::DescriptorSet);
|
||||
DECLARE_REFLECTION_STRUCT(VKPipe::Pipeline);
|
||||
DECLARE_REFLECTION_STRUCT(VKPipe::IndexBuffer);
|
||||
|
||||
@@ -2006,6 +2006,65 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
|
||||
ret.graphics.descriptorSets.resize(state.graphics.descSets.size());
|
||||
ret.compute.descriptorSets.resize(state.compute.descSets.size());
|
||||
|
||||
// store dynamic offsets
|
||||
{
|
||||
rdcarray<VKPipe::DescriptorSet> *dsts[] = {
|
||||
&ret.graphics.descriptorSets,
|
||||
&ret.compute.descriptorSets,
|
||||
};
|
||||
|
||||
const rdcarray<VulkanStatePipeline::DescriptorAndOffsets> *srcs[] = {
|
||||
&state.graphics.descSets,
|
||||
&state.compute.descSets,
|
||||
};
|
||||
|
||||
for(size_t p = 0; p < ARRAY_COUNT(srcs); p++)
|
||||
{
|
||||
for(size_t i = 0; i < srcs[p]->size(); i++)
|
||||
{
|
||||
const VulkanStatePipeline::DescriptorAndOffsets &srcData = srcs[p]->at(i);
|
||||
ResourceId sourceSet = srcData.descSet;
|
||||
const uint32_t *srcOffset = srcData.offsets.begin();
|
||||
VKPipe::DescriptorSet &destSet = dsts[p]->at(i);
|
||||
|
||||
destSet.dynamicOffsets.clear();
|
||||
|
||||
if(sourceSet == ResourceId())
|
||||
continue;
|
||||
|
||||
destSet.dynamicOffsets.reserve(srcData.offsets.size());
|
||||
|
||||
VKPipe::DynamicOffset dynOffset;
|
||||
|
||||
const WrappedVulkan::DescriptorSetInfo &descSetState =
|
||||
m_pDriver->m_DescriptorSetState[sourceSet];
|
||||
const DescriptorSetSlot *first = descSetState.data.binds[0];
|
||||
for(size_t b = 0; b < descSetState.data.binds.size(); b++)
|
||||
{
|
||||
const DescSetLayout::Binding &layoutBind =
|
||||
c.m_DescSetLayout[descSetState.layout].bindings[b];
|
||||
|
||||
if(layoutBind.layoutDescType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC &&
|
||||
layoutBind.layoutDescType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
|
||||
continue;
|
||||
|
||||
uint64_t descriptorByteOffset = descSetState.data.binds[b] - first;
|
||||
|
||||
// inline UBOs aren't dynamic and variable size can't be used with dynamic buffers, so the
|
||||
// count is what it is at definition time
|
||||
for(uint32_t a = 0; a < layoutBind.descriptorCount; a++)
|
||||
{
|
||||
dynOffset.descriptorByteOffset = descriptorByteOffset + a;
|
||||
dynOffset.dynamicBufferByteOffset = *srcOffset;
|
||||
srcOffset++;
|
||||
|
||||
destSet.dynamicOffsets.push_back(dynOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
rdcarray<VKPipe::DescriptorSet> *dsts[] = {
|
||||
&ret.graphics.descriptorSets,
|
||||
|
||||
@@ -2138,6 +2138,15 @@ void DoSerialise(SerialiserType &ser, VKPipe::DescriptorBinding &el)
|
||||
SIZE_CHECK(48);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VKPipe::DynamicOffset &el)
|
||||
{
|
||||
SERIALISE_MEMBER(descriptorByteOffset);
|
||||
SERIALISE_MEMBER(dynamicBufferByteOffset);
|
||||
|
||||
SIZE_CHECK(16);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VKPipe::DescriptorSet &el)
|
||||
{
|
||||
@@ -2149,7 +2158,9 @@ void DoSerialise(SerialiserType &ser, VKPipe::DescriptorSet &el)
|
||||
|
||||
SERIALISE_MEMBER(inlineData);
|
||||
|
||||
SIZE_CHECK(72);
|
||||
SERIALISE_MEMBER(dynamicOffsets);
|
||||
|
||||
SIZE_CHECK(96);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
|
||||
Reference in New Issue
Block a user