summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-09-03 17:34:30 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-09-03 17:34:30 +0000
commit4950bd2d60d9dbaf37f47cfd7bd76e00462b3057 (patch)
treeb025f495431852506ad76f7247b22740e96203ff /Graphics/GraphicsEngineVulkan
parentReworked DeviceContextVkImpl::UpdateTextureRegion() to use upload heap instea... (diff)
downloadDiligentCore-4950bd2d60d9dbaf37f47cfd7bd76e00462b3057.tar.gz
DiligentCore-4950bd2d60d9dbaf37f47cfd7bd76e00462b3057.zip
Added alignment parameter to VulkanUploadHeap::Allocate()
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h20
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp11
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp34
3 files changed, 39 insertions, 26 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h b/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h
index 006ccf4a..3e29b87b 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h
@@ -34,21 +34,21 @@ class RenderDeviceVkImpl;
struct VulkanUploadAllocation
{
VulkanUploadAllocation(){}
- VulkanUploadAllocation(void* _CPUAddress, VkDeviceSize _Size, VkDeviceSize _Offset, VkBuffer _vkBuffer) :
- CPUAddress(_CPUAddress),
- Size (_Size),
- Offset (_Offset),
- vkBuffer (_vkBuffer)
+ VulkanUploadAllocation(void* _CPUAddress, VkDeviceSize _Size, VkDeviceSize _AlignedOffset, VkBuffer _vkBuffer) :
+ CPUAddress (_CPUAddress),
+ Size (_Size),
+ AlignedOffset(_AlignedOffset),
+ vkBuffer (_vkBuffer)
{}
VulkanUploadAllocation (const VulkanUploadAllocation&) = delete;
VulkanUploadAllocation& operator = (const VulkanUploadAllocation&) = delete;
VulkanUploadAllocation (VulkanUploadAllocation&&) = default;
VulkanUploadAllocation& operator = (VulkanUploadAllocation&&) = default;
- VkBuffer vkBuffer = VK_NULL_HANDLE; // Vulkan buffer associated with this memory.
- void* CPUAddress = nullptr;
- VkDeviceSize Size = 0;
- VkDeviceSize Offset = 0;
+ VkBuffer vkBuffer = VK_NULL_HANDLE; // Vulkan buffer associated with this memory.
+ void* CPUAddress = nullptr;
+ VkDeviceSize Size = 0;
+ VkDeviceSize AlignedOffset = 0;
};
class VulkanUploadHeap
@@ -65,7 +65,7 @@ public:
~VulkanUploadHeap();
- VulkanUploadAllocation Allocate(size_t SizeInBytes);
+ VulkanUploadAllocation Allocate(size_t SizeInBytes, size_t Alignment);
void DiscardAllocations(uint64_t FenceValue);
size_t GetStaleAllocationsCount()const
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 647e210c..1a0a3d41 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -1074,9 +1074,9 @@ namespace Diligent
#endif
VERIFY_EXPR( static_cast<size_t>(NumBytes) == NumBytes );
- auto TmpSpace = m_UploadHeap.Allocate(static_cast<size_t>(NumBytes));
+ auto TmpSpace = m_UploadHeap.Allocate(static_cast<size_t>(NumBytes), 0);
memcpy(TmpSpace.CPUAddress, pData, static_cast<size_t>(NumBytes));
- UpdateBufferRegion(pBuffVk, DstOffset, NumBytes, TmpSpace.vkBuffer, TmpSpace.Offset);
+ UpdateBufferRegion(pBuffVk, DstOffset, NumBytes, TmpSpace.vkBuffer, TmpSpace.AlignedOffset);
// The allocation will stay in the upload heap until the end of the frame at which point all upload
// pages will be discarded
}
@@ -1183,10 +1183,11 @@ namespace Diligent
const auto UpdateRegionDepth = CopyInfo.Region.MaxZ - CopyInfo.Region.MinZ;
// For UpdateTextureRegion(), use UploadHeap, not dynamic heap
- auto Allocation = m_UploadHeap.Allocate(CopyInfo.MemorySize);
+ static constexpr const size_t BufferOffsetAlignment = 4; // bufferOffset of VkBufferImageCopy must be a multiple of 4 (18.4)
+ auto Allocation = m_UploadHeap.Allocate(CopyInfo.MemorySize, BufferOffsetAlignment);
// The allocation will stay in the upload heap until the end of the frame at which point all upload
// pages will be discarded
- VERIFY( (Allocation.Offset % 4) == 0, "Allocation offset must be at least 32-bit algined");
+ VERIFY( (Allocation.AlignedOffset % BufferOffsetAlignment) == 0, "Allocation offset must be at least 32-bit algined");
#ifdef _DEBUG
VERIFY(SrcStride >= CopyInfo.RowSize, "Source data stride (", SrcStride, ") is below the image row size (", CopyInfo.RowSize, ")");
@@ -1210,7 +1211,7 @@ namespace Diligent
}
}
CopyBufferToTexture(Allocation.vkBuffer,
- static_cast<Uint32>(Allocation.Offset),
+ static_cast<Uint32>(Allocation.AlignedOffset),
CopyInfo.Region,
TextureVk,
MipLevel,
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp
index 53d35753..aba420e8 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp
@@ -79,10 +79,14 @@ VulkanUploadHeap::UploadPageInfo VulkanUploadHeap::CreateNewPage(VkDeviceSize Si
return UploadPageInfo{std::move(MemAllocation), std::move(NewBuffer), CPUAddress};
}
-VulkanUploadAllocation VulkanUploadHeap::Allocate(size_t SizeInBytes)
+VulkanUploadAllocation VulkanUploadHeap::Allocate(size_t SizeInBytes, size_t Alignment)
{
- static constexpr const size_t MinimumAlignment = 4;
- SizeInBytes = (SizeInBytes + MinimumAlignment-1) & ~(MinimumAlignment-1);
+ VERIFY((Alignment & (Alignment-1)) == 0, "Alignment (", Alignment, ") must be power of two");
+ if (Alignment == 0)
+ {
+ static constexpr const size_t MinimumAlignment = 4;
+ Alignment = MinimumAlignment;
+ }
VulkanUploadAllocation Allocation;
if(SizeInBytes >= m_PageSize/2)
@@ -92,30 +96,38 @@ VulkanUploadAllocation VulkanUploadHeap::Allocate(size_t SizeInBytes)
Allocation.vkBuffer = NewPage.Buffer;
Allocation.CPUAddress = NewPage.CPUAddress;
Allocation.Size = SizeInBytes;
- Allocation.Offset = 0;
- m_CurrAllocatedSize += NewPage.MemAllocation.Size;
+ VERIFY(Alignment < SizeInBytes, "Alignment must be smaller than the page size");
+ Allocation.AlignedOffset = 0;
+ m_CurrAllocatedSize += NewPage.MemAllocation.Size;
m_Pages.emplace_back(std::move(NewPage));
}
else
{
- if(m_CurrPage.AvailableSize < SizeInBytes)
+ auto AlignmentOffset = ((m_CurrPage.CurrOffset + (Alignment-1)) & ~(Alignment-1)) - m_CurrPage.CurrOffset;
+ if(m_CurrPage.AvailableSize < SizeInBytes + AlignmentOffset)
{
+ // Allocate new page
auto NewPage = CreateNewPage(m_PageSize);
m_CurrPage.Reset(NewPage, m_PageSize);
m_CurrAllocatedSize += NewPage.MemAllocation.Size;
m_Pages.emplace_back(std::move(NewPage));
+ VERIFY_EXPR((m_CurrPage.CurrOffset & (Alignment-1)) == 0);
+ AlignmentOffset = 0;
}
- Allocation.vkBuffer = m_CurrPage.vkBuffer;
- Allocation.CPUAddress = m_CurrPage.CurrCPUAddress;
- Allocation.Size = SizeInBytes;
- Allocation.Offset = m_CurrPage.CurrOffset;
+ m_CurrPage.Advance(AlignmentOffset);
+ VERIFY_EXPR((m_CurrPage.CurrOffset & (Alignment-1)) == 0);
+ Allocation.vkBuffer = m_CurrPage.vkBuffer;
+ Allocation.CPUAddress = m_CurrPage.CurrCPUAddress;
+ Allocation.Size = SizeInBytes;
+ Allocation.AlignedOffset = m_CurrPage.CurrOffset;
m_CurrPage.Advance(SizeInBytes);
}
- m_CurrFrameSize += SizeInBytes;
+ m_CurrFrameSize += SizeInBytes; // Count unaligned size
m_PeakFrameSize = std::max(m_CurrFrameSize, m_PeakFrameSize);
m_PeakAllocatedSize = std::max(m_CurrAllocatedSize, m_PeakAllocatedSize);
+ VERIFY_EXPR((Allocation.AlignedOffset & (Alignment-1)) == 0);
return Allocation;
}