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