mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 10:00:40 +00:00
Reduce reported limits to allow us to expand all descriptor buffers
This commit is contained in:
@@ -917,6 +917,9 @@ DECLARE_REFLECTION_STRUCT(DescriptorSetSlot);
|
||||
|
||||
constexpr uint64_t FixedOpaqueDescriptorCaptureSize = 16;
|
||||
constexpr uint64_t MaxDescriptorSize = 256;
|
||||
// used for calculating how much address space to reserve if it's small and we're worried about
|
||||
// expanding descriptor buffers
|
||||
constexpr uint32_t ExpectedMaxNumDescriptorBuffers = 100;
|
||||
|
||||
uint32_t DescriptorDataSize(const VkPhysicalDeviceDescriptorBufferPropertiesEXT &descSizes,
|
||||
VkDescriptorType type);
|
||||
|
||||
@@ -2187,8 +2187,9 @@ VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev
|
||||
CHECK_PROP_SIZE(inputAttachmentDescriptorSize, MaxDescriptorSize);
|
||||
CHECK_PROP_SIZE(accelerationStructureDescriptorSize, MaxDescriptorSize);
|
||||
|
||||
// we don't expect any world where descriptor buffer is available but descriptor indexing
|
||||
// doesn't support robust update after bind, but require it anyway as we force robustness on
|
||||
// we don't expect any world where descriptor buffer is available but descriptor
|
||||
// indexing doesn't support robust update after bind, but require it anyway as we
|
||||
// force robustness on
|
||||
VkPhysicalDeviceDescriptorIndexingProperties descIndexingProps = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
|
||||
};
|
||||
@@ -2206,6 +2207,75 @@ VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev
|
||||
return true;
|
||||
}
|
||||
|
||||
// calculate the maximum descriptor size according to the spec
|
||||
size_t maxResourceDescriptorSize = 0;
|
||||
#define CALC_MAX_SIZE(prop) \
|
||||
maxResourceDescriptorSize = RDCMAX(maxResourceDescriptorSize, descProps.prop);
|
||||
|
||||
CALC_MAX_SIZE(storageImageDescriptorSize);
|
||||
CALC_MAX_SIZE(sampledImageDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(inputAttachmentDescriptorSize);
|
||||
CALC_MAX_SIZE(accelerationStructureDescriptorSize);
|
||||
|
||||
// guess worst-case size of a descriptor set with 2 descriptors
|
||||
VkDeviceSize reservedDescriptorSize =
|
||||
AlignUp(maxResourceDescriptorSize * 2, descProps.descriptorBufferOffsetAlignment);
|
||||
|
||||
// finally we need to ensure we have enough room to hopefully expand every resource
|
||||
// descriptor buffer a bit without blowing up available address space. we assume that
|
||||
// making room for a certain number of buffers is more than enough - anyone making more
|
||||
// than that is hopefully making buffers that are a much smaller fraction of the address space
|
||||
|
||||
// if the range is so small that we can't shrink the limit to give ourselves room and
|
||||
// remain legal, that's a problem. We need to be able to expand each buffer by a bit
|
||||
if(descProps.maxResourceDescriptorBufferRange - reservedDescriptorSize <
|
||||
((1 << 20) - (1 << 15)) * maxResourceDescriptorSize)
|
||||
{
|
||||
if(!filterWarned)
|
||||
{
|
||||
RDCWARN(
|
||||
"VkPhysicalDeviceDescriptorIndexingProperties buffer range of %llx is too "
|
||||
"small for maxResourceDescriptorSize %zu, can't support capture of "
|
||||
"VK_EXT_descriptor_buffer",
|
||||
descProps.maxResourceDescriptorBufferRange, maxResourceDescriptorSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const VkDeviceSize addrSpaceSize =
|
||||
RDCMIN(descProps.descriptorBufferAddressSpaceSize,
|
||||
descProps.resourceDescriptorBufferAddressSpaceSize);
|
||||
|
||||
// an example set of close-to-problem limits here would be: 128MB (0x8000000) addr space
|
||||
// with 64MB resource buffer range (0x4000000)
|
||||
|
||||
// the spec requires that the resource buffer range must be at least enough for ~1
|
||||
// million (2^20-2^15 = 1015808) descriptors so as long as that's still satisfied if we
|
||||
// reduce the max range by a bit, we're fine. In practice most implementations have
|
||||
// plenty of address space and those that are more constrained have a max range that's
|
||||
// power-of-two rather than the minimum ~1 million so we have plenty scope to remove.
|
||||
|
||||
// if the address space can't be shrunk by enough for 100 buffers to each have a couple
|
||||
// of descriptors that's also a problem - this is a heuristic, and it could break if the
|
||||
// user perfectly subdivided a shrunken address space into 101 buffers as then our
|
||||
// expansion would cause things to explode. We don't expect that to be a problem though.
|
||||
if(addrSpaceSize - ExpectedMaxNumDescriptorBuffers * reservedDescriptorSize < (1 << 27))
|
||||
{
|
||||
if(!filterWarned)
|
||||
{
|
||||
RDCWARN(
|
||||
"VkPhysicalDeviceDescriptorIndexingProperties resource address space size of "
|
||||
"%llx is too small for maxResourceDescriptorSize %zu, can't support capture of "
|
||||
"VK_EXT_descriptor_buffer",
|
||||
addrSpaceSize, maxResourceDescriptorSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// supported and all descriptor sizes are sensible
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -528,6 +528,7 @@ private:
|
||||
|
||||
bool m_NULLDescriptorPatternSaved = false;
|
||||
bool m_IgnoreLayoutForDescriptors = false;
|
||||
uint32_t m_ResourceDescriptorBufferReserveSize = 0;
|
||||
std::unordered_map<ResourceId, ResourceId> m_InlineBuffers;
|
||||
|
||||
bool m_SeparateDepthStencil = false;
|
||||
|
||||
@@ -4341,6 +4341,24 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
RDCASSERT(m_DescriptorBufferProperties.samplerCaptureReplayDescriptorDataSize <=
|
||||
FixedOpaqueDescriptorCaptureSize);
|
||||
|
||||
uint32_t maxResourceDescriptorSize = 0;
|
||||
#define CALC_MAX_SIZE(prop) \
|
||||
maxResourceDescriptorSize = \
|
||||
RDCMAX(maxResourceDescriptorSize, (uint32_t)m_DescriptorBufferProperties.prop);
|
||||
|
||||
CALC_MAX_SIZE(storageImageDescriptorSize);
|
||||
CALC_MAX_SIZE(sampledImageDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(inputAttachmentDescriptorSize);
|
||||
CALC_MAX_SIZE(accelerationStructureDescriptorSize);
|
||||
|
||||
m_ResourceDescriptorBufferReserveSize =
|
||||
AlignUp(maxResourceDescriptorSize * 2,
|
||||
(uint32_t)m_DescriptorBufferProperties.descriptorBufferOffsetAlignment);
|
||||
|
||||
m_IgnoreLayoutForDescriptors = descBufFeats->descriptorBufferImageLayoutIgnored != VK_FALSE;
|
||||
}
|
||||
|
||||
@@ -5008,6 +5026,24 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice,
|
||||
RDCASSERT(m_DescriptorBufferProperties.samplerCaptureReplayDescriptorDataSize <=
|
||||
FixedOpaqueDescriptorCaptureSize);
|
||||
|
||||
uint32_t maxResourceDescriptorSize = 0;
|
||||
#define CALC_MAX_SIZE(prop) \
|
||||
maxResourceDescriptorSize = \
|
||||
RDCMAX(maxResourceDescriptorSize, (uint32_t)m_DescriptorBufferProperties.prop);
|
||||
|
||||
CALC_MAX_SIZE(storageImageDescriptorSize);
|
||||
CALC_MAX_SIZE(sampledImageDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(inputAttachmentDescriptorSize);
|
||||
CALC_MAX_SIZE(accelerationStructureDescriptorSize);
|
||||
|
||||
m_ResourceDescriptorBufferReserveSize =
|
||||
AlignUp(maxResourceDescriptorSize * 2,
|
||||
(uint32_t)m_DescriptorBufferProperties.descriptorBufferOffsetAlignment);
|
||||
|
||||
m_IgnoreLayoutForDescriptors = descBufFeatures->descriptorBufferImageLayoutIgnored != VK_FALSE;
|
||||
|
||||
VkPhysicalDeviceRobustness2FeaturesKHR *robustness2 =
|
||||
|
||||
@@ -897,6 +897,33 @@ void WrappedVulkan::vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevi
|
||||
descBufferProperties->robustUniformTexelBufferDescriptorSize;
|
||||
descBufferProperties->storageTexelBufferDescriptorSize =
|
||||
descBufferProperties->robustStorageTexelBufferDescriptorSize;
|
||||
|
||||
// we also may need to shrink some range/address space limits to allow us to expand buffers. We
|
||||
// checked that this should be valid at extension filter time
|
||||
|
||||
// calculate the maximum descriptor size according to the spec
|
||||
size_t maxResourceDescriptorSize = 0;
|
||||
#define CALC_MAX_SIZE(prop) \
|
||||
maxResourceDescriptorSize = RDCMAX(maxResourceDescriptorSize, descBufferProperties->prop);
|
||||
|
||||
CALC_MAX_SIZE(storageImageDescriptorSize);
|
||||
CALC_MAX_SIZE(sampledImageDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageTexelBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustUniformBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(robustStorageBufferDescriptorSize);
|
||||
CALC_MAX_SIZE(inputAttachmentDescriptorSize);
|
||||
CALC_MAX_SIZE(accelerationStructureDescriptorSize);
|
||||
|
||||
VkDeviceSize reservedDescriptorSize = AlignUp(
|
||||
maxResourceDescriptorSize * 2, descBufferProperties->descriptorBufferOffsetAlignment);
|
||||
|
||||
descBufferProperties->maxResourceDescriptorBufferRange -= reservedDescriptorSize;
|
||||
|
||||
descBufferProperties->descriptorBufferAddressSpaceSize -=
|
||||
ExpectedMaxNumDescriptorBuffers * reservedDescriptorSize;
|
||||
descBufferProperties->resourceDescriptorBufferAddressSpaceSize -=
|
||||
ExpectedMaxNumDescriptorBuffers * reservedDescriptorSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1893,6 +1893,13 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic
|
||||
|
||||
VkBufferCreateInfo patched = CreateInfo;
|
||||
|
||||
// inflate all resource descriptor buffers by 2 descriptors, so that we have room for internal
|
||||
// descriptors wherever they are bound
|
||||
if(CreateInfo.usage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT)
|
||||
{
|
||||
patched.size += m_ResourceDescriptorBufferReserveSize;
|
||||
}
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
|
||||
|
||||
UnwrapNextChain(m_State, "VkBufferCreateInfo", tempMem, (VkBaseInStructure *)&patched);
|
||||
@@ -1977,6 +1984,13 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo
|
||||
if(IsCaptureMode(m_State))
|
||||
adjusted_info.flags |= DefaultBufferCreateFlags();
|
||||
|
||||
// inflate all resource descriptor buffers by 2 descriptors, so that we have room for internal
|
||||
// descriptors wherever they are bound
|
||||
if(adjusted_info.usage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT)
|
||||
{
|
||||
adjusted_info.size += m_ResourceDescriptorBufferReserveSize;
|
||||
}
|
||||
|
||||
SetBufferUsageFlags(&adjusted_info, adjusted_usage);
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(adjusted_info.pNext));
|
||||
|
||||
Reference in New Issue
Block a user