Skip to content

Commit 286b3b5

Browse files
Improve the Blit command API
1 parent b0c9e09 commit 286b3b5

File tree

5 files changed

+52
-48
lines changed

5 files changed

+52
-48
lines changed

include/nbl/video/IGPUCommandBuffer.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,12 +460,18 @@ class NBL_API2 IGPUCommandBuffer : public IBackendObject
460460

461461
struct SImageBlit
462462
{
463-
IGPUImage::SSubresourceLayers srcSubresource;
464-
asset::VkOffset3D srcOffsets[2];
465-
IGPUImage::SSubresourceLayers dstSubresource;
466-
asset::VkOffset3D dstOffsets[2];
463+
asset::VkOffset3D srcMinCoord;
464+
asset::VkOffset3D srcMaxCoord;
465+
asset::VkOffset3D dstMinCoord;
466+
asset::VkOffset3D dstMaxCoord;
467+
uint64_t layerCount : 15 = 1u;
468+
uint64_t srcBaseLayer : 14 = 0u;
469+
uint64_t dstBaseLayer : 14 = 0u;
470+
uint64_t srcMipLevel : 5 = 0u;
471+
uint64_t dstMipLevel : 5 = 0u;
472+
uint64_t aspectMask : 11 = IGPUImage::E_ASPECT_FLAGS::EAF_COLOR_BIT;
467473
};
468-
bool blitImage(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageBlit* const pRegions, const IGPUSampler::E_TEXTURE_FILTER filter);
474+
bool blitImage(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const std::span<const SImageBlit> regions, const IGPUSampler::E_TEXTURE_FILTER filter);
469475
struct SImageResolve
470476
{
471477
IGPUImage::SSubresourceLayers srcSubresource;
@@ -613,7 +619,7 @@ class NBL_API2 IGPUCommandBuffer : public IBackendObject
613619
virtual bool drawIndirectCount_impl(const asset::SBufferBinding<const IGPUBuffer>& indirectBinding, const asset::SBufferBinding<const IGPUBuffer>& countBinding, const uint32_t maxDrawCount, const uint32_t stride) = 0;
614620
virtual bool drawIndexedIndirectCount_impl(const asset::SBufferBinding<const IGPUBuffer>& indirectBinding, const asset::SBufferBinding<const IGPUBuffer>& countBinding, const uint32_t maxDrawCount, const uint32_t stride) = 0;
615621

616-
virtual bool blitImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageBlit* pRegions, const IGPUSampler::E_TEXTURE_FILTER filter) = 0;
622+
virtual bool blitImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const std::span<const SImageBlit> regions, const IGPUSampler::E_TEXTURE_FILTER filter) = 0;
617623
virtual bool resolveImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageResolve* pRegions) = 0;
618624

619625
virtual bool executeCommands_impl(const uint32_t count, IGPUCommandBuffer* const* const cmdbufs) = 0;

src/nbl/video/CVulkanCommandBuffer.cpp

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -729,39 +729,32 @@ bool CVulkanCommandBuffer::drawIndexedIndirectCount_impl(const asset::SBufferBin
729729
return true;
730730
}
731731

732-
bool CVulkanCommandBuffer::blitImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageBlit* pRegions, const IGPUSampler::E_TEXTURE_FILTER filter)
732+
bool CVulkanCommandBuffer::blitImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const std::span<const SImageBlit> regions, const IGPUSampler::E_TEXTURE_FILTER filter)
733733
{
734734
VkImage vk_srcImage = static_cast<const CVulkanImage*>(srcImage)->getInternalObject();
735735
VkImage vk_dstImage = static_cast<const CVulkanImage*>(dstImage)->getInternalObject();
736736

737-
constexpr uint32_t MAX_BLIT_REGION_COUNT = 100u;
738-
VkImageBlit vk_blitRegions[MAX_BLIT_REGION_COUNT];
739-
assert(regionCount <= MAX_BLIT_REGION_COUNT);
740-
741-
for (uint32_t i = 0u; i < regionCount; ++i)
737+
core::vector<VkImageBlit> vk_blitRegions(regions.size());
738+
auto outRegionIt = vk_blitRegions.data();
739+
for (auto region : regions)
742740
{
743-
vk_blitRegions[i].srcSubresource.aspectMask = static_cast<VkImageAspectFlags>(pRegions[i].srcSubresource.aspectMask.value);
744-
vk_blitRegions[i].srcSubresource.mipLevel = pRegions[i].srcSubresource.mipLevel;
745-
vk_blitRegions[i].srcSubresource.baseArrayLayer = pRegions[i].srcSubresource.baseArrayLayer;
746-
vk_blitRegions[i].srcSubresource.layerCount = pRegions[i].srcSubresource.layerCount;
747-
748-
// Todo(achal): Remove `static_cast`s
749-
vk_blitRegions[i].srcOffsets[0] = { static_cast<int32_t>(pRegions[i].srcOffsets[0].x), static_cast<int32_t>(pRegions[i].srcOffsets[0].y), static_cast<int32_t>(pRegions[i].srcOffsets[0].z) };
750-
vk_blitRegions[i].srcOffsets[1] = { static_cast<int32_t>(pRegions[i].srcOffsets[1].x), static_cast<int32_t>(pRegions[i].srcOffsets[1].y), static_cast<int32_t>(pRegions[i].srcOffsets[1].z) };
751-
752-
vk_blitRegions[i].dstSubresource.aspectMask = static_cast<VkImageAspectFlags>(pRegions[i].dstSubresource.aspectMask.value);
753-
vk_blitRegions[i].dstSubresource.mipLevel = pRegions[i].dstSubresource.mipLevel;
754-
vk_blitRegions[i].dstSubresource.baseArrayLayer = pRegions[i].dstSubresource.baseArrayLayer;
755-
vk_blitRegions[i].dstSubresource.layerCount = pRegions[i].dstSubresource.layerCount;
756-
757-
// Todo(achal): Remove `static_cast`s
758-
vk_blitRegions[i].dstOffsets[0] = { static_cast<int32_t>(pRegions[i].dstOffsets[0].x), static_cast<int32_t>(pRegions[i].dstOffsets[0].y), static_cast<int32_t>(pRegions[i].dstOffsets[0].z) };
759-
vk_blitRegions[i].dstOffsets[1] = { static_cast<int32_t>(pRegions[i].dstOffsets[1].x), static_cast<int32_t>(pRegions[i].dstOffsets[1].y), static_cast<int32_t>(pRegions[i].dstOffsets[1].z) };
741+
outRegionIt->srcSubresource.aspectMask = static_cast<VkImageAspectFlags>(region.aspectMask);
742+
outRegionIt->srcSubresource.mipLevel = region.srcMipLevel;
743+
outRegionIt->srcSubresource.baseArrayLayer = region.srcBaseLayer;
744+
outRegionIt->srcSubresource.layerCount = region.layerCount;
745+
746+
memcpy(outRegionIt->srcOffsets,&region.srcMinCoord,sizeof(VkOffset3D)*2);
747+
748+
outRegionIt->dstSubresource.aspectMask = static_cast<VkImageAspectFlags>(region.aspectMask);
749+
outRegionIt->dstSubresource.mipLevel = region.dstMipLevel;
750+
outRegionIt->dstSubresource.baseArrayLayer = region.dstBaseLayer;
751+
outRegionIt->dstSubresource.layerCount = region.layerCount;
752+
753+
memcpy(outRegionIt->dstOffsets,&region.dstMinCoord,sizeof(VkOffset3D)*2);
754+
outRegionIt++;
760755
}
761756

762-
getFunctionTable().vkCmdBlitImage(m_cmdbuf, vk_srcImage, getVkImageLayoutFromImageLayout(srcImageLayout),
763-
vk_dstImage, getVkImageLayoutFromImageLayout(dstImageLayout), regionCount, vk_blitRegions,
764-
static_cast<VkFilter>(filter));
757+
getFunctionTable().vkCmdBlitImage(m_cmdbuf,vk_srcImage,getVkImageLayoutFromImageLayout(srcImageLayout),vk_dstImage,getVkImageLayoutFromImageLayout(dstImageLayout),regions.size(),vk_blitRegions.data(),static_cast<VkFilter>(filter));
765758

766759
return true;
767760
}

src/nbl/video/CVulkanCommandBuffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ class CVulkanCommandBuffer final : public IGPUCommandBuffer
221221
bool drawIndirectCount_impl(const asset::SBufferBinding<const IGPUBuffer>& indirectBinding, const asset::SBufferBinding<const IGPUBuffer>& countBinding, const uint32_t maxDrawCount, const uint32_t stride) override;
222222
bool drawIndexedIndirectCount_impl(const asset::SBufferBinding<const IGPUBuffer>& indirectBinding, const asset::SBufferBinding<const IGPUBuffer>& countBinding, const uint32_t maxDrawCount, const uint32_t stride) override;
223223

224-
bool blitImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageBlit* pRegions, const IGPUSampler::E_TEXTURE_FILTER filter) override;
224+
bool blitImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const std::span<const SImageBlit> regions, const IGPUSampler::E_TEXTURE_FILTER filter) override;
225225
bool resolveImage_impl(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageResolve* pRegions) override;
226226

227227
bool executeCommands_impl(const uint32_t count, IGPUCommandBuffer* const* const cmdbufs) override;

src/nbl/video/IGPUCommandBuffer.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,12 +1259,12 @@ static bool disallowedLayoutForBlitAndResolve(const IGPUImage::LAYOUT layout)
12591259
return true;
12601260
}
12611261

1262-
bool IGPUCommandBuffer::blitImage(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageBlit* pRegions, const IGPUSampler::E_TEXTURE_FILTER filter)
1262+
bool IGPUCommandBuffer::blitImage(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const std::span<const SImageBlit> regions, const IGPUSampler::E_TEXTURE_FILTER filter)
12631263
{
12641264
if (!checkStateBeforeRecording(queue_flags_t::GRAPHICS_BIT,RENDERPASS_SCOPE::OUTSIDE))
12651265
return false;
12661266

1267-
if (regionCount==0u || !pRegions || disallowedLayoutForBlitAndResolve<false>(srcImageLayout) || disallowedLayoutForBlitAndResolve<true>(dstImageLayout))
1267+
if (regions.empty() || disallowedLayoutForBlitAndResolve<false>(srcImageLayout) || disallowedLayoutForBlitAndResolve<true>(dstImageLayout))
12681268
return false;
12691269

12701270
const auto* physDev = getOriginDevice()->getPhysicalDevice();
@@ -1278,18 +1278,17 @@ bool IGPUCommandBuffer::blitImage(const IGPUImage* const srcImage, const IGPUIma
12781278

12791279
// TODO rest of: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdBlitImage.html#VUID-vkCmdBlitImage-srcImage-00229
12801280

1281-
for (uint32_t i=0u; i<regionCount; ++i)
1281+
for (auto region : regions)
12821282
{
1283-
if (pRegions[i].dstSubresource.aspectMask!=pRegions[i].srcSubresource.aspectMask)
1284-
return false;
1285-
if (pRegions[i].dstSubresource.layerCount!=pRegions[i].srcSubresource.layerCount)
1283+
if (region.layerCount==0 || !region.aspectMask)
12861284
return false;
1285+
// probably validate the offsets, and extents
12871286
}
12881287

12891288
if (!m_cmdpool->m_commandListPool.emplace<IGPUCommandPool::CBlitImageCmd>(m_commandList, core::smart_refctd_ptr<const IGPUImage>(srcImage), core::smart_refctd_ptr<const IGPUImage>(dstImage)))
12901289
return false;
12911290

1292-
return blitImage_impl(srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
1291+
return blitImage_impl(srcImage, srcImageLayout, dstImage, dstImageLayout, regions, filter);
12931292
}
12941293

12951294
bool IGPUCommandBuffer::resolveImage(const IGPUImage* const srcImage, const IGPUImage::LAYOUT srcImageLayout, IGPUImage* const dstImage, const IGPUImage::LAYOUT dstImageLayout, const uint32_t regionCount, const SImageResolve* pRegions)

src/nbl/video/utilities/ISimpleManagedSurface.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,21 @@ bool ISimpleManagedSurface::immediateBlit(const image_barrier_t& contents, IQueu
103103
if (!cmdbuf->pipelineBarrier(asset::EDF_NONE,depInfo))
104104
return false;
105105

106-
// do the blit
106+
// TODO: Implement scaling modes other than plain STRETCH, and allow for using subrectangles of the initial contents
107107
{
108-
const IGPUCommandBuffer::SImageBlit region = {
109-
// .srcSubresource = contents.subresourceRange,
110-
// .srcOffsets[2] = ,
111-
// .dstSubresource = ,
112-
// .dstOffsets =,
113-
};
114-
if (!cmdbuf->blitImage(contents.image,blitSrcLayout,acquiredImage,blitDstLayout,1,&region,IGPUSampler::ETF_LINEAR))
108+
const auto srcExtent = contents.image->getCreationParameters().extent;
109+
const auto dstExtent = acquiredImage->getCreationParameters().extent;
110+
const IGPUCommandBuffer::SImageBlit regions[1] = {{
111+
.srcMinCoord = {0,0,0},
112+
.srcMaxCoord = {srcExtent.width,srcExtent.height,1},
113+
.dstMinCoord = {0,0,0},
114+
.dstMaxCoord = {dstExtent.width,dstExtent.height,1},
115+
.layerCount = acquiredImage->getCreationParameters().arrayLayers,
116+
.srcBaseLayer = 0, // TODO
117+
.dstBaseLayer = 0,
118+
.srcMipLevel = 0 // TODO
119+
}};
120+
if (!cmdbuf->blitImage(contents.image,blitSrcLayout,acquiredImage,blitDstLayout,regions,IGPUSampler::ETF_LINEAR))
115121
return false;
116122
}
117123

0 commit comments

Comments
 (0)