Skip to content

Commit 6cd2893

Browse files
Vulkan: use host_image_copy extension to initialize textures (API256006, close #655)
1 parent 7773dc2 commit 6cd2893

File tree

12 files changed

+288
-36
lines changed

12 files changed

+288
-36
lines changed

Graphics/GraphicsEngine/interface/APIInfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,7 +30,7 @@
3030
/// \file
3131
/// Diligent API information
3232

33-
#define DILIGENT_API_VERSION 256005
33+
#define DILIGENT_API_VERSION 256006
3434

3535
#include "../../../Primitives/interface/BasicTypes.h"
3636

Graphics/GraphicsEngine/interface/GraphicsTypes.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,16 +3940,23 @@ struct DeviceFeaturesVk
39403940
/// using framebuffer and render pass caches.
39413941
DEVICE_FEATURE_STATE DynamicRendering DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
39423942

3943+
/// Indicates whether the device supports VK_EXT_host_image_copy extension.
3944+
///
3945+
/// \remarks This extension is used to initialize the texture on the host.
3946+
/// If the extension is not supported, the texture is initialized on the device.
3947+
DEVICE_FEATURE_STATE HostImageCopy DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
3948+
39433949

39443950
#if DILIGENT_CPP_INTERFACE
39453951
constexpr DeviceFeaturesVk() noexcept {}
39463952

39473953
#define ENUMERATE_VK_DEVICE_FEATURES(Handler) \
3948-
Handler(DynamicRendering)
3954+
Handler(DynamicRendering) \
3955+
Handler(HostImageCopy)
39493956

39503957
explicit constexpr DeviceFeaturesVk(DEVICE_FEATURE_STATE State) noexcept
39513958
{
3952-
static_assert(sizeof(*this) == 1, "Did you add a new feature to DeviceFeatures? Please add it to ENUMERATE_DEVICE_FEATURES.");
3959+
static_assert(sizeof(*this) == 2, "Did you add a new feature to DeviceFeatures? Please add it to ENUMERATE_VK_DEVICE_FEATURES.");
39533960
#define INIT_FEATURE(Feature) Feature = State;
39543961
ENUMERATE_VK_DEVICE_FEATURES(INIT_FEATURE)
39553962
#undef INIT_FEATURE

Graphics/GraphicsEngine/src/RenderDeviceBase.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,9 @@ DeviceFeaturesVk EnableDeviceFeaturesVk(const DeviceFeaturesVk& SupportedFeature
133133
DeviceFeaturesVk EnabledFeatures;
134134

135135
ENABLE_FEATURE(DynamicRendering, "VK_KHR_dynamic_rendering is");
136+
ENABLE_FEATURE(HostImageCopy, "VK_EXT_host_image_copy is");
136137

137-
ASSERT_SIZEOF(DeviceFeaturesVk, 1, "Did you add a new feature to DeviceFeaturesVk? Please handle its status here (if necessary).");
138+
ASSERT_SIZEOF(DeviceFeaturesVk, 2, "Did you add a new feature to DeviceFeaturesVk? Please handle its status here (if necessary).");
138139

139140
return EnabledFeatures;
140141
}

Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2023 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -101,9 +101,13 @@ class TextureVkImpl final : public TextureBase<EngineVkImplTraits>
101101
protected:
102102
void CreateViewInternal(const struct TextureViewDesc& ViewDesc, ITextureView** ppView, bool bIsDefaultView) override;
103103

104-
void InitializeTextureContent(const TextureData& InitData,
105-
const TextureFormatAttribs& FmtAttribs,
106-
const VkImageCreateInfo& ImageCI) noexcept(false);
104+
void InitializeContentOnDevice(const TextureData& InitData,
105+
const TextureFormatAttribs& FmtAttribs,
106+
const VkImageCreateInfo& ImageCI) noexcept(false);
107+
bool InitializeContentOnHost(const TextureData& InitData,
108+
const TextureFormatAttribs& FmtAttribs,
109+
const VkImageCreateInfo& ImageCI) noexcept(false);
110+
107111
void CreateStagingTexture(const TextureData* pInitData,
108112
const TextureFormatAttribs& FmtAttribs);
109113

@@ -117,6 +121,4 @@ class TextureVkImpl final : public TextureBase<EngineVkImplTraits>
117121
VkDeviceSize m_StagingDataAlignedOffset = 0;
118122
};
119123

120-
VkImageCreateInfo TextureDescToVkImageCreateInfo(const TextureDesc& Desc, const RenderDeviceVkImpl* pDevice) noexcept;
121-
122124
} // namespace Diligent

Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -237,6 +237,9 @@ class VulkanLogicalDevice : public std::enable_shared_from_this<VulkanLogicalDev
237237
uint32_t firstQuery,
238238
uint32_t queryCount) const;
239239

240+
VkResult CopyMemoryToImage(const VkCopyMemoryToImageInfoEXT& CopyInfo) const;
241+
VkResult HostTransitionImageLayout(const VkHostImageLayoutTransitionInfoEXT& TransitionInfo) const;
242+
240243
void GetAccelerationStructureBuildSizes(const VkAccelerationStructureBuildGeometryInfoKHR& BuildInfo, const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR& SizeInfo) const;
241244

242245
VkResult GetRayTracingShaderGroupHandles(VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData) const;

Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class VulkanPhysicalDevice
6868
VkPhysicalDeviceMultiDrawFeaturesEXT MultiDraw = {};
6969
VkPhysicalDeviceShaderDrawParametersFeatures ShaderDrawParameters = {};
7070
VkPhysicalDeviceDynamicRenderingFeaturesKHR DynamicRendering = {};
71+
VkPhysicalDeviceHostImageCopyFeaturesEXT HostImageCopy = {};
72+
7173

7274
bool Spirv14 = false; // Ray tracing requires Vulkan 1.2 or SPIRV 1.4 extension
7375
bool Spirv15 = false; // DXC shaders with ray tracing requires Vulkan 1.2 with SPIRV 1.5
@@ -93,6 +95,9 @@ class VulkanPhysicalDevice
9395
VkPhysicalDeviceMaintenance3Properties Maintenance3 = {};
9496
VkPhysicalDeviceFragmentDensityMap2PropertiesEXT FragmentDensityMap2 = {};
9597
VkPhysicalDeviceMultiDrawPropertiesEXT MultiDraw = {};
98+
VkPhysicalDeviceHostImageCopyPropertiesEXT HostImageCopy = {};
99+
100+
std::unique_ptr<VkImageLayout[]> HostImageCopyLayouts;
96101
};
97102

98103
public:
@@ -121,7 +126,7 @@ class VulkanPhysicalDevice
121126
const ExtensionFeatures& GetExtFeatures() const { return m_ExtFeatures; }
122127
const ExtensionProperties& GetExtProperties() const { return m_ExtProperties; }
123128
const VkPhysicalDeviceMemoryProperties& GetMemoryProperties() const { return m_MemoryProperties; }
124-
VkFormatProperties GetPhysicalDeviceFormatProperties(VkFormat imageFormat) const;
129+
VkFormatProperties GetPhysicalDeviceFormatProperties(VkFormat imageFormat, VkFormatProperties3* Properties3 = nullptr) const;
125130
const std::vector<VkQueueFamilyProperties>& GetQueueProperties() const { return m_QueueFamilyProperties; }
126131

127132
private:

Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,17 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& En
12461246
NextExt = &EnabledExtFeats.DynamicRendering.pNext;
12471247
}
12481248

1249+
if (EnabledFeaturesVk.HostImageCopy)
1250+
{
1251+
VERIFY_EXPR(PhysicalDevice->IsExtensionSupported(VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME));
1252+
DeviceExtensions.push_back(VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME);
1253+
1254+
EnabledExtFeats.HostImageCopy = DeviceExtFeatures.HostImageCopy;
1255+
1256+
*NextExt = &EnabledExtFeats.HostImageCopy;
1257+
NextExt = &EnabledExtFeats.HostImageCopy.pNext;
1258+
}
1259+
12491260
// Append user-defined features
12501261
*NextExt = EngineCI.pDeviceExtensionFeatures;
12511262
}

Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp

Lines changed: 174 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -38,6 +38,9 @@
3838
namespace Diligent
3939
{
4040

41+
namespace
42+
{
43+
4144
VkImageCreateInfo TextureDescToVkImageCreateInfo(const TextureDesc& Desc, const RenderDeviceVkImpl* pRenderDeviceVk) noexcept
4245
{
4346
const bool IsMemoryless = (Desc.MiscFlags & MISC_TEXTURE_FLAG_MEMORYLESS) != 0;
@@ -143,6 +146,60 @@ VkImageCreateInfo TextureDescToVkImageCreateInfo(const TextureDesc& Desc, const
143146
return ImageCI;
144147
}
145148

149+
VkImageLayout VkImageLayoutFromUsage(VkImageUsageFlags Usage)
150+
{
151+
if ((Usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) != 0)
152+
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
153+
154+
if ((Usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) != 0)
155+
return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
156+
157+
if ((Usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) != 0)
158+
return VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
159+
160+
if ((Usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
161+
return VK_IMAGE_LAYOUT_GENERAL;
162+
163+
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
164+
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
165+
166+
if ((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
167+
return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR;
168+
169+
VERIFY((Usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0, "TRANSFER_SRC_BIT should always be set");
170+
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
171+
}
172+
173+
bool CheckHostImageCopySupport(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice,
174+
const VulkanUtilities::VulkanPhysicalDevice& PhysicalDevice,
175+
const VkImageCreateInfo& ImageCI)
176+
{
177+
if (!LogicalDevice.GetEnabledExtFeatures().HostImageCopy.hostImageCopy)
178+
return false;
179+
180+
VkFormatProperties3 vkFormatProps3{};
181+
VkFormatProperties VkFormatProps = PhysicalDevice.GetPhysicalDeviceFormatProperties(ImageCI.format, &vkFormatProps3);
182+
(void)VkFormatProps;
183+
184+
if ((vkFormatProps3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0)
185+
return false;
186+
187+
const VulkanUtilities::VulkanPhysicalDevice::ExtensionProperties& ExtProps = PhysicalDevice.GetExtProperties();
188+
const VkPhysicalDeviceHostImageCopyPropertiesEXT& HostImageCopyProps = ExtProps.HostImageCopy;
189+
190+
const VkImageLayout DstLayout = VkImageLayoutFromUsage(ImageCI.usage);
191+
192+
auto LayoutSupported = [](const VkImageLayout* pLayouts, uint32_t LayoutCount, VkImageLayout Layout) {
193+
return std::find(pLayouts, pLayouts + LayoutCount, Layout) != pLayouts + LayoutCount;
194+
};
195+
196+
if (!LayoutSupported(HostImageCopyProps.pCopyDstLayouts, HostImageCopyProps.copyDstLayoutCount, DstLayout))
197+
return false;
198+
199+
return true;
200+
}
201+
202+
} // namespace
146203

147204
TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
148205
FixedBlockMemoryAllocator& TexViewObjAllocator,
@@ -179,6 +236,11 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
179236

180237
VkImageCreateInfo ImageCI = TextureDescToVkImageCreateInfo(m_Desc, pRenderDeviceVk);
181238

239+
const bool InitContent = pInitData != nullptr && pInitData->pSubResources != nullptr && pInitData->NumSubresources > 0;
240+
const bool UseHostImageCopy = InitContent && CheckHostImageCopySupport(LogicalDevice, pRenderDeviceVk->GetPhysicalDevice(), ImageCI);
241+
if (UseHostImageCopy)
242+
ImageCI.usage |= VK_IMAGE_USAGE_HOST_TRANSFER_BIT;
243+
182244
const std::vector<uint32_t> QueueFamilyIndices = PlatformMisc::CountOneBits(m_Desc.ImmediateContextMask) > 1 ?
183245
GetDevice()->ConvertCmdQueueIdsToQueueFamilies(m_Desc.ImmediateContextMask) :
184246
std::vector<uint32_t>{};
@@ -223,10 +285,23 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
223285
VkResult err = LogicalDevice.BindImageMemory(m_VulkanImage, Memory, AlignedOffset);
224286
CHECK_VK_ERROR_AND_THROW(err, "Failed to bind image memory");
225287

226-
if (pInitData != nullptr && pInitData->pSubResources != nullptr && pInitData->NumSubresources > 0)
227-
InitializeTextureContent(*pInitData, FmtAttribs, ImageCI);
288+
if (InitContent)
289+
{
290+
bool InitializedOnHost = false;
291+
if (UseHostImageCopy)
292+
{
293+
InitializedOnHost = InitializeContentOnHost(*pInitData, FmtAttribs, ImageCI);
294+
}
295+
296+
if (!InitializedOnHost)
297+
{
298+
InitializeContentOnDevice(*pInitData, FmtAttribs, ImageCI);
299+
}
300+
}
228301
else
302+
{
229303
SetState(RESOURCE_STATE_UNDEFINED);
304+
}
230305
}
231306
}
232307
else if (m_Desc.Usage == USAGE_STAGING)
@@ -241,9 +316,100 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
241316
VERIFY_EXPR(IsInKnownState());
242317
}
243318

244-
void TextureVkImpl::InitializeTextureContent(const TextureData& InitData,
245-
const TextureFormatAttribs& FmtAttribs,
246-
const VkImageCreateInfo& ImageCI) noexcept(false)
319+
bool TextureVkImpl::InitializeContentOnHost(const TextureData& InitData,
320+
const TextureFormatAttribs& FmtAttribs,
321+
const VkImageCreateInfo& ImageCI) noexcept(false)
322+
{
323+
const VulkanUtilities::VulkanLogicalDevice& LogicalDevice = GetDevice()->GetLogicalDevice();
324+
VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().HostImageCopy.hostImageCopy);
325+
326+
Uint32 ExpectedNumSubresources = ImageCI.mipLevels * ImageCI.arrayLayers;
327+
if (InitData.NumSubresources != ExpectedNumSubresources)
328+
LOG_ERROR_AND_THROW("Incorrect number of subresources in init data. ", ExpectedNumSubresources, " expected, while ", InitData.NumSubresources, " provided");
329+
330+
VERIFY(FmtAttribs.ComponentType != COMPONENT_TYPE_DEPTH_STENCIL, "Initializing depth-stencil texture is currently not supported.");
331+
const VkImageAspectFlags aspectMask = ComponentTypeToVkAspectMask(FmtAttribs.ComponentType);
332+
333+
std::vector<VkMemoryToImageCopyEXT> vkCopyRegions(InitData.NumSubresources);
334+
335+
Uint32 subres = 0;
336+
for (Uint32 layer = 0; layer < ImageCI.arrayLayers; ++layer)
337+
{
338+
for (Uint32 mip = 0; mip < ImageCI.mipLevels; ++mip)
339+
{
340+
const TextureSubResData& SubResData = InitData.pSubResources[subres];
341+
VkMemoryToImageCopyEXT& vkCopyInfo = vkCopyRegions[subres];
342+
MipLevelProperties MipInfo = GetMipLevelProperties(m_Desc, mip);
343+
344+
vkCopyInfo.sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT;
345+
vkCopyInfo.pNext = nullptr;
346+
vkCopyInfo.pHostPointer = SubResData.pData;
347+
348+
const Uint32 PixelSize = FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED ?
349+
Uint32{FmtAttribs.ComponentSize} :
350+
Uint32{FmtAttribs.ComponentSize} * Uint32{FmtAttribs.NumComponents};
351+
if ((SubResData.Stride % PixelSize) != 0)
352+
{
353+
LOG_DVP_WARNING_MESSAGE("Unable to initialize texture '", m_Desc.Name, "' on host: subresource ", subres, " has stride ", SubResData.Stride,
354+
" that is not multiple of pixel size ", PixelSize, ". The content will be initialized on device.");
355+
return false;
356+
}
357+
vkCopyInfo.memoryRowLength = FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED ?
358+
static_cast<uint32_t>(SubResData.Stride * FmtAttribs.BlockWidth / FmtAttribs.ComponentSize) :
359+
static_cast<uint32_t>(SubResData.Stride / PixelSize);
360+
361+
if ((SubResData.DepthStride % SubResData.Stride) != 0)
362+
{
363+
LOG_DVP_WARNING_MESSAGE("Unable to initialize texture '", m_Desc.Name, "' on host: subresource ", subres, " has depth stride ", SubResData.DepthStride,
364+
" that is not multiple of row stride ", SubResData.Stride, ". The content will be initialized on device.");
365+
return false;
366+
}
367+
vkCopyInfo.memoryImageHeight = static_cast<uint32_t>(SubResData.DepthStride * FmtAttribs.BlockHeight / SubResData.Stride);
368+
369+
vkCopyInfo.imageSubresource.aspectMask = aspectMask;
370+
vkCopyInfo.imageSubresource.mipLevel = mip;
371+
vkCopyInfo.imageSubresource.baseArrayLayer = layer;
372+
vkCopyInfo.imageSubresource.layerCount = 1;
373+
374+
vkCopyInfo.imageOffset = {0, 0, 0};
375+
vkCopyInfo.imageExtent = {MipInfo.LogicalWidth, MipInfo.LogicalHeight, MipInfo.Depth};
376+
377+
++subres;
378+
}
379+
}
380+
381+
VkHostImageLayoutTransitionInfoEXT vkLayoutTransitionInfo{};
382+
vkLayoutTransitionInfo.sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT;
383+
vkLayoutTransitionInfo.image = m_VulkanImage;
384+
vkLayoutTransitionInfo.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
385+
vkLayoutTransitionInfo.newLayout = VkImageLayoutFromUsage(ImageCI.usage);
386+
387+
vkLayoutTransitionInfo.subresourceRange.aspectMask = aspectMask;
388+
vkLayoutTransitionInfo.subresourceRange.baseArrayLayer = 0;
389+
vkLayoutTransitionInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
390+
vkLayoutTransitionInfo.subresourceRange.baseMipLevel = 0;
391+
vkLayoutTransitionInfo.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
392+
LogicalDevice.HostTransitionImageLayout(vkLayoutTransitionInfo);
393+
394+
VkCopyMemoryToImageInfoEXT vkCopyInfo{};
395+
vkCopyInfo.sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT;
396+
vkCopyInfo.pNext = nullptr;
397+
vkCopyInfo.flags = 0;
398+
vkCopyInfo.dstImage = m_VulkanImage;
399+
vkCopyInfo.dstImageLayout = vkLayoutTransitionInfo.newLayout;
400+
vkCopyInfo.regionCount = static_cast<uint32_t>(vkCopyRegions.size());
401+
vkCopyInfo.pRegions = vkCopyRegions.data();
402+
403+
LogicalDevice.CopyMemoryToImage(vkCopyInfo);
404+
405+
SetState(VkImageLayoutToResourceState(vkCopyInfo.dstImageLayout));
406+
407+
return true;
408+
}
409+
410+
void TextureVkImpl::InitializeContentOnDevice(const TextureData& InitData,
411+
const TextureFormatAttribs& FmtAttribs,
412+
const VkImageCreateInfo& ImageCI) noexcept(false)
247413
{
248414
const VulkanUtilities::VulkanLogicalDevice& LogicalDevice = GetDevice()->GetLogicalDevice();
249415

@@ -258,18 +424,8 @@ void TextureVkImpl::InitializeTextureContent(const TextureData& InitDat
258424
VulkanUtilities::VulkanCommandBuffer CmdBuffer;
259425
GetDevice()->AllocateTransientCmdPool(CmdQueueInd, CmdPool, CmdBuffer, "Transient command pool to copy staging data to a device buffer");
260426

261-
VkImageAspectFlags aspectMask = 0;
262-
if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH)
263-
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
264-
else if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL)
265-
{
266-
UNSUPPORTED("Initializing depth-stencil texture is not currently supported");
267-
// Only single aspect bit must be specified when copying texture data
268-
269-
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
270-
}
271-
else
272-
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
427+
VERIFY(FmtAttribs.ComponentType != COMPONENT_TYPE_DEPTH_STENCIL, "Initializing depth-stencil texture is currently not supported.");
428+
const VkImageAspectFlags aspectMask = ComponentTypeToVkAspectMask(FmtAttribs.ComponentType);
273429

274430
// For either clear or copy command, dst layout must be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
275431
VkImageSubresourceRange SubresRange;

0 commit comments

Comments
 (0)