mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Use nonCoherentAtomSize as an additional alignment for Vulkan buffers
* This isn't technically true but it makes the code much simpler to align offsets and sizes to it, so that then map flushes and invalidates all happen on multiples of the atom size.
This commit is contained in:
@@ -134,10 +134,13 @@ void GPUBuffer::Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, u
|
||||
|
||||
align = (VkDeviceSize)driver->GetDeviceProps().limits.minUniformBufferOffsetAlignment;
|
||||
|
||||
// for simplicity, consider the non-coherent atom size also an alignment requirement
|
||||
align = AlignUp(align, driver->GetDeviceProps().limits.nonCoherentAtomSize);
|
||||
|
||||
sz = size;
|
||||
// offset must be aligned, so ensure we have at least ringSize
|
||||
// copies accounting for that
|
||||
totalsize = ringSize == 1 ? size : AlignUp(size, align) * ringSize;
|
||||
totalsize = AlignUp(size, align) * RDCMAX(1U, ringSize);
|
||||
curoffset = 0;
|
||||
|
||||
ringCount = ringSize;
|
||||
@@ -208,11 +211,16 @@ void *GPUBuffer::Map(uint32_t *bindoffset, VkDeviceSize usedsize)
|
||||
VkDeviceSize offset = bindoffset ? curoffset : 0;
|
||||
VkDeviceSize size = usedsize > 0 ? usedsize : sz;
|
||||
|
||||
// wrap around the ring, assuming the ring is large enough
|
||||
// that this memory is now free
|
||||
// align the size so we always consume coherent atoms
|
||||
size = AlignUp(size, align);
|
||||
|
||||
// wrap around the ring as soon as the 'sz' would overflow. This is because if we're using dynamic
|
||||
// offsets in the descriptor the range is still set to that fixed size and the validation
|
||||
// complains if we go off the end (even if it's unused). Rather than constantly update the
|
||||
// descriptor, we just conservatively wrap and waste the last bit of space.
|
||||
if(offset + sz > totalsize)
|
||||
offset = 0;
|
||||
RDCASSERT(offset + sz <= totalsize);
|
||||
RDCASSERT(offset + size <= totalsize);
|
||||
|
||||
// offset must be aligned
|
||||
curoffset = AlignUp(offset + size, align);
|
||||
|
||||
@@ -178,11 +178,16 @@ void WrappedVulkan::RemapMemoryIndices(VkPhysicalDeviceMemoryProperties *memProp
|
||||
MemoryAllocation WrappedVulkan::AllocateMemoryForResource(bool buffer, VkMemoryRequirements mrq,
|
||||
MemoryScope scope, MemoryType type)
|
||||
{
|
||||
const VkDeviceSize nonCoherentAtomSize = GetDeviceProps().limits.nonCoherentAtomSize;
|
||||
|
||||
MemoryAllocation ret;
|
||||
ret.scope = scope;
|
||||
ret.type = type;
|
||||
ret.buffer = buffer;
|
||||
ret.size = AlignUp(mrq.size, mrq.alignment);
|
||||
// for ease, ensure all allocations are multiples of the non-coherent atom size, so we can
|
||||
// invalidate/flush safely. This is at most 256 bytes which is likely already satisfied.
|
||||
ret.size = AlignUp(ret.size, nonCoherentAtomSize);
|
||||
|
||||
RDCDEBUG("Allocating 0x%llx with alignment 0x%llx in 0x%x for a %s (%s in %s)", ret.size,
|
||||
mrq.alignment, mrq.memoryTypeBits, buffer ? "buffer" : "image", ToStr(type).c_str(),
|
||||
|
||||
@@ -721,7 +721,7 @@ void VulkanReplay::GetOutputWindowData(uint64_t id, bytebuf &retData)
|
||||
RDCASSERT(pData != NULL);
|
||||
|
||||
VkMappedMemoryRange range = {
|
||||
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, NULL, readbackMem, 0, bufInfo.size,
|
||||
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, NULL, readbackMem, 0, VK_WHOLE_SIZE,
|
||||
};
|
||||
|
||||
vkr = vt->InvalidateMappedMemoryRanges(Unwrap(device), 1, &range);
|
||||
|
||||
@@ -263,7 +263,7 @@ VulkanTextRenderer::VulkanTextRenderer(WrappedVulkan *driver)
|
||||
|
||||
// we only use a subset of the [MAX_SINGLE_LINE_LENGTH] array needed for each line, so this ring
|
||||
// can be smaller
|
||||
m_TextStringUBO.Create(driver, dev, 4096, 10, 0);
|
||||
m_TextStringUBO.Create(driver, dev, 4096, 20, 0);
|
||||
RDCCOMPILE_ASSERT(sizeof(StringUBOData) <= 4096, "font uniforms size");
|
||||
|
||||
rm->SetInternalResource(GetResID(m_TextStringUBO.buf));
|
||||
|
||||
Reference in New Issue
Block a user