summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-10-01 01:24:40 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-10-01 01:24:40 +0000
commitd8fa7f9dc4304973265461c076883053d87e52dd (patch)
tree455c568dccc24f65d7bda2303a74b53519116bea /Graphics/GraphicsEngineVulkan
parentA number of updates to support Metal backend (diff)
downloadDiligentCore-d8fa7f9dc4304973265461c076883053d87e52dd.tar.gz
DiligentCore-d8fa7f9dc4304973265461c076883053d87e52dd.zip
Unified staging buffer offset processing in Vulkan and GL
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp7
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp47
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp2
3 files changed, 26 insertions, 30 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp
index b04babec..7ca629ad 100644
--- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp
@@ -99,11 +99,8 @@ public:
void InvalidateStagingRange(VkDeviceSize Offset, VkDeviceSize Size);
- // bufferOffset must be a multiple of 4 (18.4)
- // If the calling command's VkImage parameter is a compressed image, bufferOffset
- // must be a multiple of the compressed texel block size in bytes (18.4). This
- // is automatically guaranteed as MipWidth and MipHeight are rounded to block size.
- static constexpr Uint32 StagingDataAlignment = 4;
+ // Buffer offset must be a multiple of 4 (18.4)
+ static constexpr Uint32 StagingBufferOffsetAlignment = 4;
protected:
void CreateViewInternal(const struct TextureViewDesc& ViewDesc, ITextureView** ppView, bool bIsDefaultView) override;
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index f14e7f9c..2d7b9591 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -1590,8 +1590,7 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
FullMipBox.MaxZ = MipLevelAttribs.Depth;
pSrcBox = &FullMipBox;
}
- const auto& DstFmtAttribs = GetTextureFormatAttribs(DstTexDesc.Format);
- const auto& SrcFmtAttribs = GetTextureFormatAttribs(SrcTexDesc.Format);
+
if (SrcTexDesc.Usage != USAGE_STAGING && DstTexDesc.Usage != USAGE_STAGING)
{
VkImageCopy CopyRegion = {};
@@ -1603,6 +1602,8 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
CopyRegion.extent.height = std::max(pSrcBox->MaxY - pSrcBox->MinY, 1u);
CopyRegion.extent.depth = std::max(pSrcBox->MaxZ - pSrcBox->MinZ, 1u);
+ const auto& DstFmtAttribs = GetTextureFormatAttribs(DstTexDesc.Format);
+
VkImageAspectFlags aspectMask = 0;
if (DstFmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH)
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
@@ -1634,15 +1635,18 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
DEV_CHECK_ERR((SrcTexDesc.CPUAccessFlags & CPU_ACCESS_WRITE), "Attempting to copy from staging texture that was not created with CPU_ACCESS_WRITE flag");
DEV_CHECK_ERR(pSrcTexVk->GetState() == RESOURCE_STATE_COPY_SOURCE, "Source staging texture must permanently be in RESOURCE_STATE_COPY_SOURCE state");
- auto SrcBufferOffset = GetStagingTextureSubresOffset(SrcTexDesc, CopyAttribs.SrcSlice, CopyAttribs.SrcMipLevel, TextureVkImpl::StagingDataAlignment);
- auto SrcMipLevelAttribs = GetMipLevelProperties(SrcTexDesc, CopyAttribs.SrcMipLevel);
// address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelBlockSize; (18.4.1)
- SrcBufferOffset +=
- // For compressed-block formats, RowSize is the size of one compressed row.
- // For non-compressed formats, BlockHeight is 1.
- (pSrcBox->MinZ * SrcMipLevelAttribs.StorageHeight + pSrcBox->MinY) / SrcFmtAttribs.BlockHeight * SrcMipLevelAttribs.RowSize +
- // For non-compressed formats, BlockWidth is 1.
- (pSrcBox->MinX / SrcFmtAttribs.BlockWidth) * SrcFmtAttribs.GetElementSize();
+
+ // bufferOffset must be a multiple of 4 (18.4)
+ // If the calling command's VkImage parameter is a compressed image, bufferOffset
+ // must be a multiple of the compressed texel block size in bytes (18.4). This
+ // is automatically guaranteed as MipWidth and MipHeight are rounded to block size.
+
+ const auto SrcBufferOffset =
+ GetStagingTextureLocationOffset(SrcTexDesc, CopyAttribs.SrcSlice, CopyAttribs.SrcMipLevel,
+ TextureVkImpl::StagingBufferOffsetAlignment,
+ pSrcBox->MinX, pSrcBox->MinY, pSrcBox->MinZ);
+ const auto SrcMipLevelAttribs = GetMipLevelProperties(SrcTexDesc, CopyAttribs.SrcMipLevel);
Box DstBox;
DstBox.MinX = CopyAttribs.DstX;
@@ -1655,7 +1659,7 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
CopyBufferToTexture(
pSrcTexVk->GetVkStagingBuffer(),
SrcBufferOffset,
- SrcMipLevelAttribs.StorageWidth,
+ SrcMipLevelAttribs.StorageWidth, // GetStagingTextureLocationOffset assumes texels are tightly packed
*pDstTexVk,
DstBox,
CopyAttribs.DstMipLevel,
@@ -1667,17 +1671,12 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
DEV_CHECK_ERR((DstTexDesc.CPUAccessFlags & CPU_ACCESS_READ), "Attempting to copy to staging texture that was not created with CPU_ACCESS_READ flag");
DEV_CHECK_ERR(pDstTexVk->GetState() == RESOURCE_STATE_COPY_DEST, "Destination staging texture must permanently be in RESOURCE_STATE_COPY_DEST state");
- auto DstBufferOffset =
- GetStagingTextureSubresOffset(DstTexDesc, CopyAttribs.DstSlice, CopyAttribs.DstMipLevel,
- TextureVkImpl::StagingDataAlignment);
- const auto DstMipLevelAttribs = GetMipLevelProperties(DstTexDesc, CopyAttribs.DstMipLevel);
// address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelBlockSize; (18.4.1)
- DstBufferOffset +=
- // For compressed-block formats, RowSize is the size of one compressed row.
- // For non-compressed formats, BlockHeight is 1.
- (CopyAttribs.DstZ * DstMipLevelAttribs.StorageHeight + CopyAttribs.DstY) / DstFmtAttribs.BlockHeight * DstMipLevelAttribs.RowSize *
- // For non-compressed formats, BlockWidth is 1.
- (CopyAttribs.DstX / DstFmtAttribs.BlockWidth) * DstFmtAttribs.GetElementSize();
+ const auto DstBufferOffset =
+ GetStagingTextureLocationOffset(DstTexDesc, CopyAttribs.DstSlice, CopyAttribs.DstMipLevel,
+ TextureVkImpl::StagingBufferOffsetAlignment,
+ CopyAttribs.DstX, CopyAttribs.DstY, CopyAttribs.DstZ);
+ const auto DstMipLevelAttribs = GetMipLevelProperties(DstTexDesc, CopyAttribs.DstMipLevel);
CopyTextureToBuffer(
*pSrcTexVk,
@@ -1687,7 +1686,8 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
CopyAttribs.SrcTextureTransitionMode,
pDstTexVk->GetVkStagingBuffer(),
DstBufferOffset,
- DstMipLevelAttribs.StorageWidth);
+ DstMipLevelAttribs.StorageWidth // GetStagingTextureLocationOffset assumes texels are tightly packed
+ );
}
else
{
@@ -2010,8 +2010,7 @@ void DeviceContextVkImpl::MapTextureSubresource(ITexture* pTextu
else if (TexDesc.Usage == USAGE_STAGING)
{
auto SubresourceOffset =
- GetStagingTextureSubresOffset(TexDesc, ArraySlice, MipLevel,
- TextureVkImpl::StagingDataAlignment);
+ GetStagingTextureSubresourceOffset(TexDesc, ArraySlice, MipLevel, TextureVkImpl::StagingBufferOffsetAlignment);
const auto MipLevelAttribs = GetMipLevelProperties(TexDesc, MipLevel);
// address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelBlockSize; (18.4.1)
auto MapStartOffset = SubresourceOffset +
diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
index 8a37df0c..313de089 100644
--- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
@@ -408,7 +408,7 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
VkStagingBuffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
VkStagingBuffCI.pNext = nullptr;
VkStagingBuffCI.flags = 0;
- VkStagingBuffCI.size = GetStagingTextureSubresOffset(m_Desc, m_Desc.ArraySize, 0, StagingDataAlignment);
+ VkStagingBuffCI.size = GetStagingTextureSubresourceOffset(m_Desc, m_Desc.ArraySize, 0, StagingBufferOffsetAlignment);
// clang-format off
DEV_CHECK_ERR((m_Desc.CPUAccessFlags & (CPU_ACCESS_READ | CPU_ACCESS_WRITE)) == CPU_ACCESS_READ ||