xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/draw/vktDrawImageObjectUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Intel Corporation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Image Object Util
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDrawImageObjectUtil.hpp"
26 
27 #include "tcuSurface.hpp"
28 #include "tcuVectorUtil.hpp"
29 
30 #include "vkRefUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vktDrawCreateInfoUtil.hpp"
35 #include "vktDrawBufferObjectUtil.hpp"
36 
37 #include "tcuTextureUtil.hpp"
38 
39 namespace vkt
40 {
41 namespace Draw
42 {
43 
pack(int pixelSize,int width,int height,int depth,vk::VkDeviceSize rowPitchOrZero,vk::VkDeviceSize depthPitchOrZero,const void * srcBuffer,void * destBuffer)44 void MemoryOp::pack(int pixelSize, int width, int height, int depth, vk::VkDeviceSize rowPitchOrZero,
45                     vk::VkDeviceSize depthPitchOrZero, const void *srcBuffer, void *destBuffer)
46 {
47     vk::VkDeviceSize rowPitch   = rowPitchOrZero;
48     vk::VkDeviceSize depthPitch = depthPitchOrZero;
49 
50     if (rowPitch == 0)
51         rowPitch = width * pixelSize;
52 
53     if (depthPitch == 0)
54         depthPitch = rowPitch * height;
55 
56     const vk::VkDeviceSize size = depthPitch * depth;
57 
58     const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(srcBuffer);
59     const uint8_t *srcStart;
60     srcStart        = srcRow;
61     uint8_t *dstRow = reinterpret_cast<uint8_t *>(destBuffer);
62     uint8_t *dstStart;
63     dstStart = dstRow;
64 
65     if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
66         depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
67     {
68         // fast path
69         deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
70     }
71     else
72     {
73         // slower, per row path
74         for (int d = 0; d < depth; d++)
75         {
76             vk::VkDeviceSize offsetDepthDst = d * depthPitch;
77             vk::VkDeviceSize offsetDepthSrc = d * (pixelSize * width * height);
78             srcRow                          = srcStart + offsetDepthSrc;
79             dstRow                          = dstStart + offsetDepthDst;
80             for (int r = 0; r < height; ++r)
81             {
82                 deMemcpy(dstRow, srcRow, static_cast<size_t>(rowPitch));
83                 srcRow += pixelSize * width;
84                 dstRow += rowPitch;
85             }
86         }
87     }
88 }
89 
unpack(int pixelSize,int width,int height,int depth,vk::VkDeviceSize rowPitchOrZero,vk::VkDeviceSize depthPitchOrZero,const void * srcBuffer,void * destBuffer)90 void MemoryOp::unpack(int pixelSize, int width, int height, int depth, vk::VkDeviceSize rowPitchOrZero,
91                       vk::VkDeviceSize depthPitchOrZero, const void *srcBuffer, void *destBuffer)
92 {
93     vk::VkDeviceSize rowPitch   = rowPitchOrZero;
94     vk::VkDeviceSize depthPitch = depthPitchOrZero;
95 
96     if (rowPitch == 0)
97         rowPitch = width * pixelSize;
98 
99     if (depthPitch == 0)
100         depthPitch = rowPitch * height;
101 
102     const vk::VkDeviceSize size = depthPitch * depth;
103 
104     const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(srcBuffer);
105     const uint8_t *srcStart;
106     srcStart        = srcRow;
107     uint8_t *dstRow = reinterpret_cast<uint8_t *>(destBuffer);
108     uint8_t *dstStart;
109     dstStart = dstRow;
110 
111     if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
112         depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
113     {
114         // fast path
115         deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
116     }
117     else
118     {
119         // slower, per row path
120         for (size_t d = 0; d < (size_t)depth; d++)
121         {
122             vk::VkDeviceSize offsetDepthDst = d * (pixelSize * width * height);
123             vk::VkDeviceSize offsetDepthSrc = d * depthPitch;
124             srcRow                          = srcStart + offsetDepthSrc;
125             dstRow                          = dstStart + offsetDepthDst;
126             for (int r = 0; r < height; ++r)
127             {
128                 deMemcpy(dstRow, srcRow, static_cast<size_t>(pixelSize * width));
129                 srcRow += rowPitch;
130                 dstRow += pixelSize * width;
131             }
132         }
133     }
134 }
135 
Image(const vk::DeviceInterface & vk,vk::VkDevice device,uint32_t queueFamilyIndex,vk::VkFormat format,const vk::VkExtent3D & extend,uint32_t levelCount,uint32_t layerCount,vk::Move<vk::VkImage> object_)136 Image::Image(const vk::DeviceInterface &vk, vk::VkDevice device, uint32_t queueFamilyIndex, vk::VkFormat format,
137              const vk::VkExtent3D &extend, uint32_t levelCount, uint32_t layerCount, vk::Move<vk::VkImage> object_)
138     : m_allocation(DE_NULL)
139     , m_object(object_)
140     , m_queueFamilyIndex(queueFamilyIndex)
141     , m_format(format)
142     , m_extent(extend)
143     , m_levelCount(levelCount)
144     , m_layerCount(layerCount)
145     , m_vk(vk)
146     , m_device(device)
147 {
148 }
149 
readSurface(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)150 tcu::ConstPixelBufferAccess Image::readSurface(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
151                                                vk::VkOffset3D offset, int width, int height,
152                                                vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
153                                                unsigned int arrayElement)
154 {
155     m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
156     deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
157     if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
158     {
159         read(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
160              m_pixelAccessData.data());
161     }
162     if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
163     {
164         readUsingBuffer(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect,
165                         m_pixelAccessData.data());
166     }
167     return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
168 }
169 
readDepth(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)170 tcu::ConstPixelBufferAccess Image::readDepth(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
171                                              vk::VkOffset3D offset, int width, int height,
172                                              vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
173                                              unsigned int arrayElement)
174 {
175     DE_ASSERT(aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT);
176     const tcu::TextureFormat tcuFormat = getDepthCopyFormat(m_format);
177     m_pixelAccessData.resize(width * height * tcuFormat.getPixelSize());
178     deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
179 
180     readUsingBuffer(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect,
181                     m_pixelAccessData.data());
182     return tcu::ConstPixelBufferAccess(tcuFormat, width, height, 1, m_pixelAccessData.data());
183 }
184 
readVolume(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)185 tcu::ConstPixelBufferAccess Image::readVolume(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
186                                               vk::VkOffset3D offset, int width, int height, int depth,
187                                               vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
188                                               unsigned int arrayElement)
189 {
190     m_pixelAccessData.resize(width * height * depth * vk::mapVkFormat(m_format).getPixelSize());
191     deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
192     if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
193     {
194         read(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect,
195              vk::VK_IMAGE_TYPE_3D, m_pixelAccessData.data());
196     }
197     if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
198     {
199         readUsingBuffer(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect,
200                         m_pixelAccessData.data());
201     }
202     return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, depth, m_pixelAccessData.data());
203 }
204 
readSurface1D(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)205 tcu::ConstPixelBufferAccess Image::readSurface1D(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
206                                                  vk::VkOffset3D offset, int width, vk::VkImageAspectFlagBits aspect,
207                                                  unsigned int mipLevel, unsigned int arrayElement)
208 {
209     m_pixelAccessData.resize(width * vk::mapVkFormat(m_format).getPixelSize());
210     deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
211     if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
212     {
213         read(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
214              m_pixelAccessData.data());
215     }
216     if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
217     {
218         readUsingBuffer(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect,
219                         m_pixelAccessData.data());
220     }
221     return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, 1, 1, m_pixelAccessData.data());
222 }
223 
read(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,vk::VkImageType type,void * data)224 void Image::read(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout, vk::VkOffset3D offset,
225                  int width, int height, int depth, unsigned int mipLevel, unsigned int arrayElement,
226                  vk::VkImageAspectFlagBits aspect, vk::VkImageType type, void *data)
227 {
228     DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
229 
230     de::SharedPtr<Image> stagingResource =
231         copyToLinearImage(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, type);
232     const vk::VkOffset3D zeroOffset = {0, 0, 0};
233     stagingResource->readLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
234 }
235 
readUsingBuffer(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,void * data)236 void Image::readUsingBuffer(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
237                             vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
238                             unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, void *data)
239 {
240     DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
241 
242     de::SharedPtr<Buffer> stagingResource;
243 
244     bool isCombinedType         = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
245     vk::VkDeviceSize bufferSize = 0;
246 
247     if (!isCombinedType)
248         bufferSize = vk::mapVkFormat(m_format).getPixelSize() * width * height * depth;
249 
250     uint32_t pixelMask = 0xffffffff;
251     if (isCombinedType)
252     {
253         int pixelSize = 0;
254         switch (m_format)
255         {
256         case vk::VK_FORMAT_D16_UNORM_S8_UINT:
257             pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
258             break;
259         case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
260             pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
261             break;
262         case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
263         case vk::VK_FORMAT_D24_UNORM_S8_UINT:
264             // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
265             pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
266             pixelMask = 0x00ffffff;
267             break;
268 
269         default:
270             DE_FATAL("Not implemented");
271         }
272         bufferSize = pixelSize * width * height * depth;
273     }
274 
275     BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT |
276                                                                      vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
277     stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator,
278                                              vk::MemoryRequirement::HostVisible);
279 
280     {
281         CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
282         vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
283         vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
284             vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
285 
286         beginCommandBuffer(m_vk, *copyCmdBuffer);
287 
288         if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
289         {
290             layout = vk::VK_IMAGE_LAYOUT_GENERAL;
291 
292             vk::VkImageMemoryBarrier barrier;
293             barrier.sType               = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
294             barrier.pNext               = DE_NULL;
295             barrier.srcAccessMask       = 0;
296             barrier.dstAccessMask       = 0;
297             barrier.oldLayout           = vk::VK_IMAGE_LAYOUT_UNDEFINED;
298             barrier.newLayout           = vk::VK_IMAGE_LAYOUT_GENERAL;
299             barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
300             barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
301             barrier.image               = object();
302 
303             barrier.subresourceRange.aspectMask     = aspect;
304             barrier.subresourceRange.baseMipLevel   = 0;
305             barrier.subresourceRange.levelCount     = m_levelCount;
306             barrier.subresourceRange.baseArrayLayer = 0;
307             barrier.subresourceRange.layerCount     = m_layerCount;
308 
309             m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
310                                     vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0, 0,
311                                     (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL,
312                                     1, &barrier);
313         }
314 
315         vk::VkBufferImageCopy region = {0,      0,
316                                         0,      {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
317                                         offset, {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
318 
319         m_vk.cmdCopyImageToBuffer(*copyCmdBuffer, object(), layout, stagingResource->object(), 1, &region);
320 
321         // pipeline barrier for accessing the staging buffer from HOST
322         {
323             const vk::VkBufferMemoryBarrier memoryBarrier = {vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
324                                                              DE_NULL,
325                                                              vk::VK_ACCESS_TRANSFER_WRITE_BIT,
326                                                              vk::VK_ACCESS_HOST_READ_BIT,
327                                                              VK_QUEUE_FAMILY_IGNORED,
328                                                              VK_QUEUE_FAMILY_IGNORED,
329                                                              stagingResource->object(),
330                                                              0u,
331                                                              VK_WHOLE_SIZE};
332             m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
333                                     0u, 0u, DE_NULL, 1u, &memoryBarrier, 0u, DE_NULL);
334         }
335 
336         endCommandBuffer(m_vk, *copyCmdBuffer);
337 
338         submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
339     }
340 
341     // Validate the results
342     const vk::Allocation &bufAllocation = stagingResource->getBoundMemory();
343     invalidateMappedMemoryRange(m_vk, m_device, bufAllocation.getMemory(), bufAllocation.getOffset(), VK_WHOLE_SIZE);
344 
345     uint8_t *destPtr = reinterpret_cast<uint8_t *>(stagingResource->getBoundMemory().getHostPtr());
346     deMemcpy(data, destPtr, static_cast<size_t>(bufferSize));
347     if (pixelMask != 0xffffffff)
348     {
349         /* data copied to or from the depth aspect of a
350            VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D24_UNORM_S8_UINT format
351            is packed with one 32-bit word per texel with the D24 value in the
352            LSBs of the word, and *undefined* values in the eight MSBs. */
353         uint32_t *const data32             = static_cast<uint32_t *>(data);
354         const vk::VkDeviceSize data32Count = bufferSize / sizeof(uint32_t);
355         for (vk::VkDeviceSize i = 0; i < data32Count; ++i)
356             data32[i] &= pixelMask;
357     }
358 }
359 
readSurfaceLinear(vk::VkOffset3D offset,int width,int height,int depth,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)360 tcu::ConstPixelBufferAccess Image::readSurfaceLinear(vk::VkOffset3D offset, int width, int height, int depth,
361                                                      vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
362                                                      unsigned int arrayElement)
363 {
364     m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
365     readLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
366     return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
367 }
368 
readLinear(vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,void * data)369 void Image::readLinear(vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
370                        unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, void *data)
371 {
372     DE_ASSERT(mipLevel < m_levelCount);
373     DE_ASSERT(arrayElement < m_layerCount);
374 
375     vk::VkImageSubresource imageSubResource = {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement};
376 
377     vk::VkSubresourceLayout imageLayout;
378     deMemset(&imageLayout, 0, sizeof(imageLayout));
379 
380     m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource, &imageLayout);
381 
382     const uint8_t *srcPtr = reinterpret_cast<const uint8_t *>(getBoundMemory().getHostPtr());
383     srcPtr += imageLayout.offset;
384     srcPtr += offset.z * imageLayout.depthPitch;
385     srcPtr += offset.y * imageLayout.rowPitch;
386     srcPtr += offset.x;
387 
388     MemoryOp::unpack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth, imageLayout.rowPitch,
389                      imageLayout.depthPitch, srcPtr, data);
390 }
391 
copyToLinearImage(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,vk::VkImageType type)392 de::SharedPtr<Image> Image::copyToLinearImage(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
393                                               vk::VkOffset3D offset, int width, int height, int depth,
394                                               unsigned int mipLevel, unsigned int arrayElement,
395                                               vk::VkImageAspectFlagBits aspect, vk::VkImageType type)
396 {
397     de::SharedPtr<Image> stagingResource;
398     {
399         vk::VkExtent3D stagingExtent = {(uint32_t)width, (uint32_t)height, (uint32_t)depth};
400         ImageCreateInfo stagingResourceCreateInfo(type, m_format, stagingExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
401                                                   vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
402 
403         stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
404                                                 m_queueFamilyIndex, vk::MemoryRequirement::HostVisible);
405 
406         CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
407         vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
408         vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
409             vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
410 
411         beginCommandBuffer(m_vk, *copyCmdBuffer);
412 
413         transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED,
414                           vk::VK_IMAGE_LAYOUT_GENERAL, 0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT,
415                           vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
416 
417         const vk::VkOffset3D zeroOffset = {0, 0, 0};
418         vk::VkImageCopy region          = {{(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
419                                            offset,
420                                            {(vk::VkImageAspectFlags)aspect, 0, 0, 1},
421                                            zeroOffset,
422                                            {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
423 
424         m_vk.cmdCopyImage(*copyCmdBuffer, object(), layout, stagingResource->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1,
425                           &region);
426 
427         // pipeline barrier for accessing the staging image from HOST
428         {
429             const vk::VkImageMemoryBarrier memoryBarrier = {
430                 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
431                 DE_NULL,
432                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
433                 vk::VK_ACCESS_HOST_READ_BIT,
434                 vk::VK_IMAGE_LAYOUT_GENERAL,
435                 vk::VK_IMAGE_LAYOUT_GENERAL,
436                 VK_QUEUE_FAMILY_IGNORED,
437                 VK_QUEUE_FAMILY_IGNORED,
438                 stagingResource->object(),
439                 {static_cast<vk::VkImageAspectFlags>(aspect), 0u, 1u, 0u, 1u}};
440             m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
441                                     0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &memoryBarrier);
442         }
443 
444         endCommandBuffer(m_vk, *copyCmdBuffer);
445 
446         submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
447 
448         // Validate the results
449         const vk::Allocation &imgAllocation = stagingResource->getBoundMemory();
450         invalidateMappedMemoryRange(m_vk, m_device, imgAllocation.getMemory(), imgAllocation.getOffset(),
451                                     VK_WHOLE_SIZE);
452     }
453     return stagingResource;
454 }
455 
uploadVolume(const tcu::ConstPixelBufferAccess & access,vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)456 void Image::uploadVolume(const tcu::ConstPixelBufferAccess &access, vk::VkQueue queue, vk::Allocator &allocator,
457                          vk::VkImageLayout layout, vk::VkOffset3D offset, vk::VkImageAspectFlagBits aspect,
458                          unsigned int mipLevel, unsigned int arrayElement)
459 {
460     if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
461     {
462         upload(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(), mipLevel,
463                arrayElement, aspect, vk::VK_IMAGE_TYPE_3D, access.getDataPtr());
464     }
465     if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
466     {
467         uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(),
468                           mipLevel, arrayElement, aspect, access.getDataPtr());
469     }
470 }
471 
uploadSurface(const tcu::ConstPixelBufferAccess & access,vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)472 void Image::uploadSurface(const tcu::ConstPixelBufferAccess &access, vk::VkQueue queue, vk::Allocator &allocator,
473                           vk::VkImageLayout layout, vk::VkOffset3D offset, vk::VkImageAspectFlagBits aspect,
474                           unsigned int mipLevel, unsigned int arrayElement)
475 {
476     if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
477     {
478         upload(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(), mipLevel,
479                arrayElement, aspect, vk::VK_IMAGE_TYPE_2D, access.getDataPtr());
480     }
481     if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
482     {
483         uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(),
484                           mipLevel, arrayElement, aspect, access.getDataPtr());
485     }
486 }
487 
uploadSurface1D(const tcu::ConstPixelBufferAccess & access,vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)488 void Image::uploadSurface1D(const tcu::ConstPixelBufferAccess &access, vk::VkQueue queue, vk::Allocator &allocator,
489                             vk::VkImageLayout layout, vk::VkOffset3D offset, vk::VkImageAspectFlagBits aspect,
490                             unsigned int mipLevel, unsigned int arrayElement)
491 {
492     if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
493     {
494         upload(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(), mipLevel,
495                arrayElement, aspect, vk::VK_IMAGE_TYPE_1D, access.getDataPtr());
496     }
497     if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
498     {
499         uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(),
500                           mipLevel, arrayElement, aspect, access.getDataPtr());
501     }
502 }
503 
uploadSurfaceLinear(const tcu::ConstPixelBufferAccess & access,vk::VkOffset3D offset,int width,int height,int depth,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)504 void Image::uploadSurfaceLinear(const tcu::ConstPixelBufferAccess &access, vk::VkOffset3D offset, int width, int height,
505                                 int depth, vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
506                                 unsigned int arrayElement)
507 {
508     uploadLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, access.getDataPtr());
509 }
510 
upload(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,vk::VkImageType type,const void * data)511 void Image::upload(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout, vk::VkOffset3D offset,
512                    int width, int height, int depth, unsigned int mipLevel, unsigned int arrayElement,
513                    vk::VkImageAspectFlagBits aspect, vk::VkImageType type, const void *data)
514 {
515     DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED ||
516               layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
517 
518     de::SharedPtr<Image> stagingResource;
519     vk::VkExtent3D extent = {(uint32_t)width, (uint32_t)height, (uint32_t)depth};
520     ImageCreateInfo stagingResourceCreateInfo(type, m_format, extent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
521                                               vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
522 
523     stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator, m_queueFamilyIndex,
524                                             vk::MemoryRequirement::HostVisible);
525 
526     const vk::VkOffset3D zeroOffset = {0, 0, 0};
527     stagingResource->uploadLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
528 
529     {
530         CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
531         vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
532         vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
533             vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
534 
535         beginCommandBuffer(m_vk, *copyCmdBuffer);
536 
537         if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
538         {
539             layout = vk::VK_IMAGE_LAYOUT_GENERAL;
540 
541             vk::VkImageMemoryBarrier barrier;
542             barrier.sType               = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
543             barrier.pNext               = DE_NULL;
544             barrier.srcAccessMask       = 0;
545             barrier.dstAccessMask       = 0;
546             barrier.oldLayout           = vk::VK_IMAGE_LAYOUT_UNDEFINED;
547             barrier.newLayout           = vk::VK_IMAGE_LAYOUT_GENERAL;
548             barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
549             barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
550             barrier.image               = object();
551 
552             barrier.subresourceRange.aspectMask     = aspect;
553             barrier.subresourceRange.baseMipLevel   = 0;
554             barrier.subresourceRange.levelCount     = m_levelCount;
555             barrier.subresourceRange.baseArrayLayer = 0;
556             barrier.subresourceRange.layerCount     = m_layerCount;
557 
558             m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
559                                     vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0, 0,
560                                     (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL,
561                                     1, &barrier);
562         }
563 
564         transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED,
565                           vk::VK_IMAGE_LAYOUT_GENERAL, 0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT,
566                           vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
567 
568         vk::VkImageCopy region = {{(vk::VkImageAspectFlags)aspect, 0, 0, 1},
569                                   zeroOffset,
570                                   {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
571                                   offset,
572                                   {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
573 
574         m_vk.cmdCopyImage(*copyCmdBuffer, stagingResource->object(), vk::VK_IMAGE_LAYOUT_GENERAL, object(), layout, 1,
575                           &region);
576         endCommandBuffer(m_vk, *copyCmdBuffer);
577 
578         submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
579     }
580 }
581 
uploadUsingBuffer(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,const void * data)582 void Image::uploadUsingBuffer(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
583                               vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
584                               unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, const void *data)
585 {
586     DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED ||
587               layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
588 
589     de::SharedPtr<Buffer> stagingResource;
590     bool isCombinedType         = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
591     vk::VkDeviceSize bufferSize = 0;
592     if (!isCombinedType)
593         bufferSize = vk::mapVkFormat(m_format).getPixelSize() * width * height * depth;
594     if (isCombinedType)
595     {
596         int pixelSize = 0;
597         switch (m_format)
598         {
599         case vk::VK_FORMAT_D16_UNORM_S8_UINT:
600             pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
601             break;
602         case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
603             pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
604             break;
605         case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
606         case vk::VK_FORMAT_D24_UNORM_S8_UINT:
607             pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 3 : 1;
608             break;
609 
610         default:
611             DE_FATAL("Not implemented");
612         }
613         bufferSize = pixelSize * width * height * depth;
614     }
615     BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT |
616                                                                      vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
617     stagingResource  = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator,
618                                               vk::MemoryRequirement::HostVisible);
619     uint8_t *destPtr = reinterpret_cast<uint8_t *>(stagingResource->getBoundMemory().getHostPtr());
620     deMemcpy(destPtr, data, static_cast<size_t>(bufferSize));
621     vk::flushAlloc(m_vk, m_device, stagingResource->getBoundMemory());
622     {
623         CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
624         vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
625         vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
626             vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
627 
628         beginCommandBuffer(m_vk, *copyCmdBuffer);
629 
630         if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
631         {
632             layout = vk::VK_IMAGE_LAYOUT_GENERAL;
633 
634             vk::VkImageMemoryBarrier barrier;
635             barrier.sType               = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
636             barrier.pNext               = DE_NULL;
637             barrier.srcAccessMask       = 0;
638             barrier.dstAccessMask       = 0;
639             barrier.oldLayout           = vk::VK_IMAGE_LAYOUT_UNDEFINED;
640             barrier.newLayout           = vk::VK_IMAGE_LAYOUT_GENERAL;
641             barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
642             barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
643             barrier.image               = object();
644 
645             barrier.subresourceRange.aspectMask     = aspect;
646             barrier.subresourceRange.baseMipLevel   = 0;
647             barrier.subresourceRange.levelCount     = m_levelCount;
648             barrier.subresourceRange.baseArrayLayer = 0;
649             barrier.subresourceRange.layerCount     = m_layerCount;
650 
651             m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
652                                     vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0, 0,
653                                     (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL,
654                                     1, &barrier);
655         }
656 
657         vk::VkBufferImageCopy region = {0,      0,
658                                         0,      {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
659                                         offset, {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
660 
661         m_vk.cmdCopyBufferToImage(*copyCmdBuffer, stagingResource->object(), object(), layout, 1, &region);
662         endCommandBuffer(m_vk, *copyCmdBuffer);
663 
664         submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
665     }
666 }
667 
uploadLinear(vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,const void * data)668 void Image::uploadLinear(vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
669                          unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, const void *data)
670 {
671     DE_ASSERT(mipLevel < m_levelCount);
672     DE_ASSERT(arrayElement < m_layerCount);
673 
674     vk::VkSubresourceLayout imageLayout;
675 
676     vk::VkImageSubresource imageSubResource = {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement};
677 
678     m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource, &imageLayout);
679 
680     uint8_t *destPtr = reinterpret_cast<uint8_t *>(getBoundMemory().getHostPtr());
681     destPtr += imageLayout.offset;
682     destPtr += offset.z * imageLayout.depthPitch;
683     destPtr += offset.y * imageLayout.rowPitch;
684     destPtr += offset.x;
685 
686     MemoryOp::pack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth, imageLayout.rowPitch,
687                    imageLayout.depthPitch, data, destPtr);
688 }
689 
bindMemory(de::MovePtr<vk::Allocation> allocation)690 void Image::bindMemory(de::MovePtr<vk::Allocation> allocation)
691 {
692     DE_ASSERT(allocation);
693     VK_CHECK(m_vk.bindImageMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
694 
695     DE_ASSERT(!m_allocation);
696     m_allocation = allocation;
697 }
698 
createAndAlloc(const vk::DeviceInterface & vk,vk::VkDevice device,const vk::VkImageCreateInfo & createInfo,vk::Allocator & allocator,uint32_t queueFamilyIndex,vk::MemoryRequirement memoryRequirement)699 de::SharedPtr<Image> Image::createAndAlloc(const vk::DeviceInterface &vk, vk::VkDevice device,
700                                            const vk::VkImageCreateInfo &createInfo, vk::Allocator &allocator,
701                                            uint32_t queueFamilyIndex, vk::MemoryRequirement memoryRequirement)
702 {
703     de::SharedPtr<Image> ret = create(vk, device, createInfo, queueFamilyIndex);
704 
705     vk::VkMemoryRequirements imageRequirements = vk::getImageMemoryRequirements(vk, device, ret->object());
706     ret->bindMemory(allocator.allocate(imageRequirements, memoryRequirement));
707     return ret;
708 }
709 
create(const vk::DeviceInterface & vk,vk::VkDevice device,const vk::VkImageCreateInfo & createInfo,uint32_t queueFamilyIndex)710 de::SharedPtr<Image> Image::create(const vk::DeviceInterface &vk, vk::VkDevice device,
711                                    const vk::VkImageCreateInfo &createInfo, uint32_t queueFamilyIndex)
712 {
713     return de::SharedPtr<Image>(new Image(vk, device, queueFamilyIndex, createInfo.format, createInfo.extent,
714                                           createInfo.mipLevels, createInfo.arrayLayers,
715                                           vk::createImage(vk, device, &createInfo)));
716 }
717 
transition2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageAspectFlags aspectMask,vk::VkImageLayout oldLayout,vk::VkImageLayout newLayout,vk::VkAccessFlags srcAccessMask,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags srcStageMask,vk::VkPipelineStageFlags dstStageMask,uint32_t numLayers)718 void transition2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
719                        vk::VkImageAspectFlags aspectMask, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout,
720                        vk::VkAccessFlags srcAccessMask, vk::VkAccessFlags dstAccessMask,
721                        vk::VkPipelineStageFlags srcStageMask, vk::VkPipelineStageFlags dstStageMask, uint32_t numLayers)
722 {
723     vk::VkImageMemoryBarrier barrier;
724     barrier.sType                           = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
725     barrier.pNext                           = DE_NULL;
726     barrier.srcAccessMask                   = srcAccessMask;
727     barrier.dstAccessMask                   = dstAccessMask;
728     barrier.oldLayout                       = oldLayout;
729     barrier.newLayout                       = newLayout;
730     barrier.srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
731     barrier.dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
732     barrier.image                           = image;
733     barrier.subresourceRange.aspectMask     = aspectMask;
734     barrier.subresourceRange.baseMipLevel   = 0;
735     barrier.subresourceRange.levelCount     = 1;
736     barrier.subresourceRange.baseArrayLayer = 0;
737     barrier.subresourceRange.layerCount     = numLayers;
738 
739     vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (vk::VkDependencyFlags)0, 0,
740                           (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1,
741                           &barrier);
742 }
743 
initialTransitionColor2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask,uint32_t numLayers)744 void initialTransitionColor2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
745                                    vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
746                                    vk::VkPipelineStageFlags dstStageMask, uint32_t numLayers)
747 {
748     transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u,
749                       dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, numLayers);
750 }
751 
initialTransitionDepth2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask)752 void initialTransitionDepth2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
753                                    vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
754                                    vk::VkPipelineStageFlags dstStageMask)
755 {
756     transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u,
757                       dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask);
758 }
759 
initialTransitionStencil2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask)760 void initialTransitionStencil2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
761                                      vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
762                                      vk::VkPipelineStageFlags dstStageMask)
763 {
764     transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u,
765                       dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask);
766 }
767 
initialTransitionDepthStencil2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask)768 void initialTransitionDepthStencil2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer,
769                                           vk::VkImage image, vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
770                                           vk::VkPipelineStageFlags dstStageMask)
771 {
772     transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
773                       vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u, dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
774                       dstStageMask);
775 }
776 
777 } // namespace Draw
778 } // namespace vkt
779