dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[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  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Image Object Util
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktDrawImageObjectUtil.hpp"
37
38 #include "tcuSurface.hpp"
39 #include "tcuVectorUtil.hpp"
40
41 #include "vkRefUtil.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkImageUtil.hpp"
44 #include "vktDrawCreateInfoUtil.hpp"
45 #include "vktDrawBufferObjectUtil.hpp"
46
47 #include "tcuTextureUtil.hpp"
48
49 namespace vkt
50 {
51 namespace Draw
52 {
53
54 void MemoryOp::pack (int                                pixelSize,
55                                          int                            width,
56                                          int                            height,
57                                          int                            depth,
58                                          vk::VkDeviceSize       rowPitchOrZero,
59                                          vk::VkDeviceSize       depthPitchOrZero,
60                                          const void *           srcBuffer,
61                                          void *                         destBuffer)
62 {
63         vk::VkDeviceSize rowPitch       = rowPitchOrZero;
64         vk::VkDeviceSize depthPitch     = depthPitchOrZero;
65
66         if (rowPitch == 0)
67                 rowPitch = width * pixelSize;
68
69         if (depthPitch == 0)
70                 depthPitch = rowPitch * height;
71
72         const vk::VkDeviceSize size = depthPitch * depth;
73
74         const deUint8* srcRow = reinterpret_cast<const deUint8*>(srcBuffer);
75         const deUint8* srcStart;
76         srcStart = srcRow;
77         deUint8* dstRow = reinterpret_cast<deUint8 *>(destBuffer);
78         deUint8* dstStart;
79         dstStart = dstRow;
80
81         if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
82                 depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
83         {
84                 // fast path
85                 deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
86         }
87         else
88         {
89                 // slower, per row path
90                 for (int d = 0; d < depth; d++)
91                 {
92                         vk::VkDeviceSize offsetDepthDst = d * depthPitch;
93                         vk::VkDeviceSize offsetDepthSrc = d * (pixelSize * width * height);
94                         srcRow = srcStart + offsetDepthSrc;
95                         dstRow = dstStart + offsetDepthDst;
96                         for (int r = 0; r < height; ++r)
97                         {
98                                 deMemcpy(dstRow, srcRow, static_cast<size_t>(rowPitch));
99                                 srcRow += pixelSize * width;
100                                 dstRow += rowPitch;
101                         }
102                 }
103         }
104 }
105
106 void MemoryOp::unpack (int                                      pixelSize,
107                                            int                                  width,
108                                            int                                  height,
109                                            int                                  depth,
110                                            vk::VkDeviceSize             rowPitchOrZero,
111                                            vk::VkDeviceSize             depthPitchOrZero,
112                                            const void *                 srcBuffer,
113                                            void *                               destBuffer)
114 {
115         vk::VkDeviceSize rowPitch       = rowPitchOrZero;
116         vk::VkDeviceSize depthPitch = depthPitchOrZero;
117
118         if (rowPitch == 0)
119                 rowPitch = width * pixelSize;
120
121         if (depthPitch == 0)
122                 depthPitch = rowPitch * height;
123
124         const vk::VkDeviceSize size = depthPitch * depth;
125
126         const deUint8* srcRow = reinterpret_cast<const deUint8*>(srcBuffer);
127         const deUint8* srcStart;
128         srcStart = srcRow;
129         deUint8* dstRow = reinterpret_cast<deUint8*>(destBuffer);
130         deUint8* dstStart;
131         dstStart = dstRow;
132
133         if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
134                 depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
135         {
136                 // fast path
137                 deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
138         }
139         else {
140                 // slower, per row path
141                 for (size_t d = 0; d < (size_t)depth; d++)
142                 {
143                         vk::VkDeviceSize offsetDepthDst = d * (pixelSize * width * height);
144                         vk::VkDeviceSize offsetDepthSrc = d * depthPitch;
145                         srcRow = srcStart + offsetDepthSrc;
146                         dstRow = dstStart + offsetDepthDst;
147                         for (int r = 0; r < height; ++r)
148                         {
149                                 deMemcpy(dstRow, srcRow, static_cast<size_t>(pixelSize * width));
150                                 srcRow += rowPitch;
151                                 dstRow += pixelSize * width;
152                         }
153                 }
154         }
155 }
156
157 Image::Image (const vk::DeviceInterface& vk,
158                           vk::VkDevice                          device,
159                           vk::VkFormat                          format,
160                           const vk::VkExtent3D&         extend,
161                           deUint32                                      levelCount,
162                           deUint32                                      layerCount,
163                           vk::Move<vk::VkImage>         object_)
164         : m_allocation          (DE_NULL)
165         , m_object                      (object_)
166         , m_format                      (format)
167         , m_extent                      (extend)
168         , m_levelCount          (levelCount)
169         , m_layerCount          (layerCount)
170         , m_vk(vk)
171         , m_device(device)
172 {
173 }
174
175 tcu::ConstPixelBufferAccess Image::readSurface (vk::VkQueue                                     queue,
176                                                                                                 vk::Allocator&                          allocator,
177                                                                                                 vk::VkImageLayout                       layout,
178                                                                                                 vk::VkOffset3D                          offset,
179                                                                                                 int                                                     width,
180                                                                                                 int                                                     height,
181                                                                                                 vk::VkImageAspectFlagBits       aspect,
182                                                                                                 unsigned int                            mipLevel,
183                                                                                                 unsigned int                            arrayElement)
184 {
185         m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
186         deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
187         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
188         {
189                 read(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
190                 m_pixelAccessData.data());
191         }
192         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
193         {
194                 readUsingBuffer(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
195         }
196         return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
197 }
198
199 tcu::ConstPixelBufferAccess Image::readVolume (vk::VkQueue                                      queue,
200                                                                                            vk::Allocator&                               allocator,
201                                                                                            vk::VkImageLayout                    layout,
202                                                                                            vk::VkOffset3D                               offset,
203                                                                                            int                                                  width,
204                                                                                            int                                                  height,
205                                                                                            int                                                  depth,
206                                                                                            vk::VkImageAspectFlagBits    aspect,
207                                                                                            unsigned int                                 mipLevel,
208                                                                                            unsigned int                                 arrayElement)
209 {
210         m_pixelAccessData.resize(width * height * depth * vk::mapVkFormat(m_format).getPixelSize());
211         deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
212         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
213         {
214                 read(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_3D,
215                 m_pixelAccessData.data());
216         }
217         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
218         {
219                 readUsingBuffer(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
220         }
221         return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, depth, m_pixelAccessData.data());
222 }
223
224 tcu::ConstPixelBufferAccess Image::readSurface1D(vk::VkQueue                            queue,
225                                                                                                  vk::Allocator&                         allocator,
226                                                                                                  vk::VkImageLayout                      layout,
227                                                                                                  vk::VkOffset3D                         offset,
228                                                                                                  int                                            width,
229                                                                                                  vk::VkImageAspectFlagBits      aspect,
230                                                                                                  unsigned int                           mipLevel,
231                                                                                                  unsigned int                           arrayElement)
232 {
233         m_pixelAccessData.resize(width * vk::mapVkFormat(m_format).getPixelSize());
234         deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
235         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
236         {
237                 read(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
238                 m_pixelAccessData.data());
239         }
240         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
241         {
242                 readUsingBuffer(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect,
243                 m_pixelAccessData.data());
244         }
245         return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, 1, 1, m_pixelAccessData.data());
246 }
247
248 void Image::read (vk::VkQueue                                   queue,
249                                   vk::Allocator&                                allocator,
250                                   vk::VkImageLayout                             layout,
251                                   vk::VkOffset3D                                offset,
252                                   int                                                   width,
253                                   int                                                   height,
254                                   int                                                   depth,
255                                   unsigned int                                  mipLevel,
256                                   unsigned int                                  arrayElement,
257                                   vk::VkImageAspectFlagBits             aspect,
258                                   vk::VkImageType                               type,
259                                   void *                                                data)
260 {
261         DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
262
263         de::SharedPtr<Image> stagingResource = copyToLinearImage(queue, allocator, layout, offset, width,
264                                                                                                                          height, depth, mipLevel, arrayElement, aspect, type);
265         const vk::VkOffset3D zeroOffset = {0, 0, 0};
266         stagingResource->readLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
267 }
268
269 void Image::readUsingBuffer (vk::VkQueue                                queue,
270                                                          vk::Allocator&                         allocator,
271                                                          vk::VkImageLayout                      layout,
272                                                          vk::VkOffset3D                         offset,
273                                                          int                                            width,
274                                                          int                                            height,
275                                                          int                                            depth,
276                                                          unsigned int                           mipLevel,
277                                                          unsigned int                           arrayElement,
278                                                          vk::VkImageAspectFlagBits      aspect,
279                                                          void *                                         data)
280 {
281         DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);;
282
283         de::SharedPtr<Buffer> stagingResource;
284
285         bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
286         vk::VkDeviceSize bufferSize = 0;
287
288         if (!isCombinedType)
289                 bufferSize = vk::mapVkFormat(m_format).getPixelSize() * width * height * depth;
290
291         if (isCombinedType)
292         {
293                 int pixelSize = 0;
294                 switch (m_format)
295                 {
296                         case vk::VK_FORMAT_D16_UNORM_S8_UINT:
297                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
298                                 break;
299                         case  vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
300                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
301                                 break;
302                         case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
303                         case vk::VK_FORMAT_D24_UNORM_S8_UINT:
304                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 3 : 1;
305                                 break;
306
307                         default:
308                                 DE_FATAL("Not implemented");
309                 }
310                 bufferSize = pixelSize*width*height*depth;
311         }
312
313         BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
314         stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator, vk::MemoryRequirement::HostVisible);
315
316         {
317                 //todo [scygan] get proper queueFamilyIndex
318                 CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
319                 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
320
321                 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
322                 {
323                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,     // VkStructureType                      sType;
324                         DE_NULL,                                                                                        // const void*                          pNext;
325                         *copyCmdPool,                                                                           // VkCommandPool                        commandPool;
326                         vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,                            // VkCommandBufferLevel         level;
327                         1u,                                                                                                     // deUint32                                     bufferCount;
328                 };
329                 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
330
331                 CmdBufferBeginInfo beginInfo;
332                 VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
333
334                 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
335                 {
336                         layout = vk::VK_IMAGE_LAYOUT_GENERAL;
337
338                         vk::VkImageMemoryBarrier barrier;
339                         barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
340                         barrier.pNext = DE_NULL;
341                         barrier.srcAccessMask = 0;
342                         barrier.dstAccessMask = 0;
343                         barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
344                         barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
345                         barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
346                         barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
347                         barrier.image = object();
348
349                         barrier.subresourceRange.aspectMask = aspect;
350                         barrier.subresourceRange.baseMipLevel = 0;
351                         barrier.subresourceRange.levelCount = m_levelCount;
352                         barrier.subresourceRange.baseArrayLayer = 0;
353                         barrier.subresourceRange.layerCount = m_layerCount;
354
355                         void* barriers[] = { &barrier };
356
357                         m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
358                                 false, DE_LENGTH_OF_ARRAY(barriers), barriers);
359                 }
360
361                 vk::VkBufferImageCopy region =
362                 {
363                         0, 0, 0,
364                         { aspect, mipLevel, arrayElement, 1 },
365                         offset,
366                         { width, height, depth }
367                 };
368
369                 m_vk.cmdCopyImageToBuffer(*copyCmdBuffer, object(), layout, stagingResource->object(), 1, &region);
370                 VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
371
372                 vk::VkSubmitInfo submitInfo =
373                 {
374                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
375                         DE_NULL,                                                        // const void*                          pNext;
376                         0,                                                                              // deUint32                                     waitSemaphoreCount;
377                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
378                         1,                                                                              // deUint32                                     commandBufferCount;
379                         &copyCmdBuffer.get(),                           // const VkCommandBuffer*       pCommandBuffers;
380                         0,                                                                              // deUint32                                     signalSemaphoreCount;
381                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
382                 };
383                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
384
385                 // TODO: make this less intrusive
386                 VK_CHECK(m_vk.queueWaitIdle(queue));
387         }
388
389         deUint8* destPtr = reinterpret_cast<deUint8*>(stagingResource->getBoundMemory().getHostPtr());
390         deMemcpy(data, destPtr, static_cast<size_t>(bufferSize));
391 }
392
393 tcu::ConstPixelBufferAccess Image::readSurfaceLinear (vk::VkOffset3D                            offset,
394                                                                                                           int                                                   width,
395                                                                                                           int                                                   height,
396                                                                                                           int                                                   depth,
397                                                                                                           vk::VkImageAspectFlagBits             aspect,
398                                                                                                           unsigned int                                  mipLevel,
399                                                                                                           unsigned int                                  arrayElement)
400 {
401         m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
402         readLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
403         return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
404 }
405
406 void Image::readLinear (vk::VkOffset3D                          offset,
407                                                 int                                                     width,
408                                                 int                                                     height,
409                                                 int                                                     depth,
410                                                 unsigned int                            mipLevel,
411                                                 unsigned int                            arrayElement,
412                                                 vk::VkImageAspectFlagBits       aspect,
413                                                 void *                                          data)
414 {
415         vk::VkImageSubresource imageSubResource = { aspect, mipLevel, arrayElement };
416
417         vk::VkSubresourceLayout imageLayout;
418
419         deMemset(&imageLayout, 0, sizeof(imageLayout));
420         m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource, &imageLayout);
421
422         const deUint8* srcPtr = reinterpret_cast<const deUint8*>(getBoundMemory().getHostPtr());
423         srcPtr += imageLayout.offset + getPixelOffset(offset, imageLayout.rowPitch, imageLayout.depthPitch, mipLevel, arrayElement);
424
425         MemoryOp::unpack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth,
426                 imageLayout.rowPitch, imageLayout.depthPitch, srcPtr, data);
427 }
428
429 de::SharedPtr<Image> Image::copyToLinearImage (vk::VkQueue                                      queue,
430                                                                                            vk::Allocator&                               allocator,
431                                                                                            vk::VkImageLayout                    layout,
432                                                                                            vk::VkOffset3D                               offset,
433                                                                                            int                                                  width,
434                                                                                            int                                                  height,
435                                                                                            int                                                  depth,
436                                                                                            unsigned int                                 mipLevel,
437                                                                                            unsigned int                                 arrayElement,
438                                                                                            vk::VkImageAspectFlagBits    aspect,
439                                                                                            vk::VkImageType                              type)
440 {
441         de::SharedPtr<Image> stagingResource;
442         {
443                 vk::VkExtent3D stagingExtent = {width, height, depth};
444                 ImageCreateInfo stagingResourceCreateInfo(type, m_format, stagingExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
445                                                                                                   vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
446
447                 stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
448                                                                                                 vk::MemoryRequirement::HostVisible);
449
450                 //todo [scygan] get proper queueFamilyIndex
451                 CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
452                 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
453
454                 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
455                 {
456                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,     // VkStructureType                      sType;
457                         DE_NULL,                                                                                        // const void*                          pNext;
458                         *copyCmdPool,                                                                           // VkCommandPool                        commandPool;
459                         vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,                            // VkCommandBufferLevel         level;
460                         1u,                                                                                                     // deUint32                                     bufferCount;
461                 };
462                 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
463
464                 CmdBufferBeginInfo beginInfo;
465                 VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
466
467                 transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL);
468
469                 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
470                 vk::VkImageCopy region = { {aspect, mipLevel, arrayElement, 1}, offset, {aspect, 0, 0, 1}, zeroOffset, {width, height, depth} };
471
472                 m_vk.cmdCopyImage(*copyCmdBuffer, object(), layout, stagingResource->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &region);
473                 VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
474
475                 vk::VkSubmitInfo submitInfo =
476                 {
477                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
478                         DE_NULL,                                                        // const void*                          pNext;
479                         0,                                                                              // deUint32                                     waitSemaphoreCount;
480                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
481                         1,                                                                              // deUint32                                     commandBufferCount;
482                         &copyCmdBuffer.get(),                           // const VkCommandBuffer*       pCommandBuffers;
483                         0,                                                                              // deUint32                                     signalSemaphoreCount;
484                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
485                 };
486                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
487
488                 // TODO: make this less intrusive
489                 VK_CHECK(m_vk.queueWaitIdle(queue));
490         }
491         return stagingResource;
492 }
493
494 void Image::uploadVolume(const tcu::ConstPixelBufferAccess&     access,
495                                                  vk::VkQueue                                            queue,
496                                                  vk::Allocator&                                                 allocator,
497                                                  vk::VkImageLayout                                      layout,
498                                                  vk::VkOffset3D                                         offset,
499                                                  vk::VkImageAspectFlagBits                      aspect,
500                                                  unsigned int                                           mipLevel,
501                                                  unsigned int                                           arrayElement)
502 {
503         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
504         {
505                 upload(queue, allocator, layout, offset, access.getWidth(),
506                 access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_3D,
507                 access.getDataPtr());
508         }
509         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
510         {
511                 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
512                 access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
513         }
514 }
515
516 void Image::uploadSurface (const tcu::ConstPixelBufferAccess&   access,
517                                                    vk::VkQueue                                                  queue,
518                                                    vk::Allocator&                                                       allocator,
519                                                    vk::VkImageLayout                                    layout,
520                                                    vk::VkOffset3D                                               offset,
521                                                    vk::VkImageAspectFlagBits                    aspect,
522                                                    unsigned int                                                 mipLevel,
523                                                    unsigned int                                                 arrayElement)
524 {
525         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
526         {
527                 upload(queue, allocator, layout, offset, access.getWidth(),
528                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
529                         access.getDataPtr());
530         }
531         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
532         {
533                 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
534                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
535         }
536 }
537
538 void Image::uploadSurface1D (const tcu::ConstPixelBufferAccess& access,
539                                                          vk::VkQueue                                            queue,
540                                                          vk::Allocator&                                                 allocator,
541                                                          vk::VkImageLayout                                      layout,
542                                                          vk::VkOffset3D                                         offset,
543                                                          vk::VkImageAspectFlagBits                      aspect,
544                                                          unsigned int                                           mipLevel,
545                                                          unsigned int                                           arrayElement)
546 {
547         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
548         {
549                 upload(queue, allocator, layout, offset, access.getWidth(),
550                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
551                         access.getDataPtr());
552         }
553         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
554         {
555                 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
556                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
557         }
558 }
559
560 void Image::uploadSurfaceLinear (const tcu::ConstPixelBufferAccess&     access,
561                                                                  vk::VkOffset3D                                         offset,
562                                                                  int                                                            width,
563                                                                  int                                                            height,
564                                                                  int                                                            depth,
565                                                                  vk::VkImageAspectFlagBits                      aspect,
566                                                                  unsigned int                                           mipLevel,
567                                                                  unsigned int                                           arrayElement)
568 {
569         uploadLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, access.getDataPtr());
570 }
571
572 void Image::upload (vk::VkQueue                                 queue,
573                                         vk::Allocator&                                  allocator,
574                                         vk::VkImageLayout                       layout,
575                                         vk::VkOffset3D                          offset,
576                                         int                                                     width,
577                                         int                                                     height,
578                                         int                                                     depth,
579                                         unsigned int                            mipLevel,
580                                         unsigned int                            arrayElement,
581                                         vk::VkImageAspectFlagBits       aspect,
582                                         vk::VkImageType                         type,
583                                         const void *                            data)
584 {
585         DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
586
587         de::SharedPtr<Image> stagingResource;
588         vk::VkExtent3D extent = {width, height, depth};
589         ImageCreateInfo stagingResourceCreateInfo(
590                 type, m_format, extent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
591                 vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
592
593         stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
594                                                                 vk::MemoryRequirement::HostVisible);
595
596         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
597         stagingResource->uploadLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
598
599         {
600                 //todo [scygan] get proper queueFamilyIndex
601                 CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
602                 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
603
604                 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
605                 {
606                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,     // VkStructureType                      sType;
607                         DE_NULL,                                                                                        // const void*                          pNext;
608                         *copyCmdPool,                                                                           // VkCommandPool                        commandPool;
609                         vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,                            // VkCommandBufferLevel         level;
610                         1u,                                                                                                     // deUint32                                     bufferCount;
611                 };
612
613                 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
614
615                 CmdBufferBeginInfo beginInfo;
616                 VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
617
618                 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
619                 {
620                         layout = vk::VK_IMAGE_LAYOUT_GENERAL;
621
622                         vk::VkImageMemoryBarrier barrier;
623                         barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
624                         barrier.pNext = DE_NULL;
625                         barrier.srcAccessMask = 0;
626                         barrier.dstAccessMask = 0;
627                         barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
628                         barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
629                         barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
630                         barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
631                         barrier.image = object();
632
633                         barrier.subresourceRange.aspectMask = aspect;
634                         barrier.subresourceRange.baseMipLevel = 0;
635                         barrier.subresourceRange.levelCount = m_levelCount;
636                         barrier.subresourceRange.baseArrayLayer = 0;
637                         barrier.subresourceRange.layerCount = m_layerCount;
638
639                         void* barriers[] = { &barrier };
640
641                         m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, DE_LENGTH_OF_ARRAY(barriers), barriers);
642                 }
643
644                 transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL);
645
646                 vk::VkImageCopy region = {{aspect, 0, 0, 1},
647                                                                         zeroOffset,
648                                                                         {aspect, mipLevel, arrayElement, 1},
649                                                                         offset,
650                                                                         {width, height, depth}};
651
652                 m_vk.cmdCopyImage(*copyCmdBuffer, stagingResource->object(),
653                                                                 vk::VK_IMAGE_LAYOUT_GENERAL, object(), layout, 1, &region);
654                 VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
655
656                 vk::VkSubmitInfo submitInfo =
657                 {
658                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
659                         DE_NULL,                                                        // const void*                          pNext;
660                         0,                                                                              // deUint32                                     waitSemaphoreCount;
661                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
662                         1,                                                                              // deUint32                                     commandBufferCount;
663                         &copyCmdBuffer.get(),                           // const VkCommandBuffer*       pCommandBuffers;
664                         0,                                                                              // deUint32                                     signalSemaphoreCount;
665                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
666                 };
667                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
668
669                 // TODO: make this less intrusive
670                 VK_CHECK(m_vk.queueWaitIdle(queue));
671         }
672 }
673
674 void Image::uploadUsingBuffer (vk::VkQueue                                      queue,
675                                                            vk::Allocator&                                       allocator,
676                                                            vk::VkImageLayout                    layout,
677                                                            vk::VkOffset3D                               offset,
678                                                            int                                                  width,
679                                                            int                                                  height,
680                                                            int                                                  depth,
681                                                            unsigned int                                 mipLevel,
682                                                            unsigned int                                 arrayElement,
683                                                            vk::VkImageAspectFlagBits    aspect,
684                                                            const void *                                 data)
685 {
686         DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
687
688         de::SharedPtr<Buffer> stagingResource;
689         bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
690         vk::VkDeviceSize bufferSize = 0;
691         if (!isCombinedType)
692                 bufferSize = vk::mapVkFormat(m_format).getPixelSize() *width*height*depth;
693         if (isCombinedType)
694         {
695                 int pixelSize = 0;
696                 switch (m_format)
697                 {
698                         case vk::VK_FORMAT_D16_UNORM_S8_UINT:
699                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
700                                 break;
701                         case  vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
702                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
703                                 break;
704                         case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
705                         case vk::VK_FORMAT_D24_UNORM_S8_UINT:
706                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 3 : 1;
707                                 break;
708
709                         default:
710                                 DE_FATAL("Not implemented");
711                 }
712                 bufferSize = pixelSize*width*height*depth;
713         }
714         BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
715         stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator, vk::MemoryRequirement::HostVisible);
716         deUint8* destPtr = reinterpret_cast<deUint8*>(stagingResource->getBoundMemory().getHostPtr());
717         deMemcpy(destPtr, data, static_cast<size_t>(bufferSize));
718         vk::flushMappedMemoryRange(m_vk, m_device, stagingResource->getBoundMemory().getMemory(), stagingResource->getBoundMemory().getOffset(), bufferSize);
719         {
720                 //todo [scygan] get proper queueFamilyIndex
721                 CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
722                 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
723
724                 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
725                 {
726                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,     // VkStructureType                      sType;
727                         DE_NULL,                                                                                        // const void*                          pNext;
728                         *copyCmdPool,                                                                           // VkCommandPool                        commandPool;
729                         vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,                            // VkCommandBufferLevel         level;
730                         1u,                                                                                                     // deUint32                                     bufferCount;
731                 };
732                 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
733
734                 CmdBufferBeginInfo beginInfo;
735                 VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
736
737                 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
738                 {
739                         layout = vk::VK_IMAGE_LAYOUT_GENERAL;
740
741                         vk::VkImageMemoryBarrier barrier;
742                         barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
743                         barrier.pNext = DE_NULL;
744                         barrier.srcAccessMask = 0;
745                         barrier.dstAccessMask = 0;
746                         barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
747                         barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
748                         barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
749                         barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
750                         barrier.image = object();
751
752                         barrier.subresourceRange.aspectMask = aspect;
753                         barrier.subresourceRange.baseMipLevel = 0;
754                         barrier.subresourceRange.levelCount = m_levelCount;
755                         barrier.subresourceRange.baseArrayLayer = 0;
756                         barrier.subresourceRange.layerCount = m_layerCount;
757
758                         void* barriers[] = { &barrier };
759
760                         m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, DE_LENGTH_OF_ARRAY(barriers), barriers);
761                 }
762
763                 vk::VkBufferImageCopy region = {
764                         0, 0, 0,
765                         { aspect, mipLevel, arrayElement, 1 },
766                         offset,
767                         { width, height, depth }
768                 };
769
770                 m_vk.cmdCopyBufferToImage(*copyCmdBuffer, stagingResource->object(),
771                         object(), layout, 1, &region);
772                 VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
773
774                 vk::VkSubmitInfo submitInfo =
775                 {
776                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
777                         DE_NULL,                                                        // const void*                          pNext;
778                         0,                                                                              // deUint32                                     waitSemaphoreCount;
779                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores;
780                         1,                                                                              // deUint32                                     commandBufferCount;
781                         &copyCmdBuffer.get(),                           // const VkCommandBuffer*       pCommandBuffers;
782                         0,                                                                              // deUint32                                     signalSemaphoreCount;
783                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
784                 };
785                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
786
787                 // TODO: make this less intrusive
788                 VK_CHECK(m_vk.queueWaitIdle(queue));
789         }
790 }
791
792 void Image::uploadLinear (vk::VkOffset3D                        offset,
793                                                   int                                           width,
794                                                   int                                           height,
795                                                   int                                           depth,
796                                                   unsigned int                          mipLevel,
797                                                   unsigned int                          arrayElement,
798                                                   vk::VkImageAspectFlagBits     aspect,
799                                                   const void *                          data)
800 {
801         vk::VkSubresourceLayout imageLayout;
802
803         vk::VkImageSubresource imageSubResource = {aspect, mipLevel, arrayElement};
804
805         m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource,
806                                                                                                         &imageLayout);
807
808         deUint8* destPtr = reinterpret_cast<deUint8*>(getBoundMemory().getHostPtr());
809
810         destPtr += imageLayout.offset + getPixelOffset(offset, imageLayout.rowPitch, imageLayout.depthPitch, mipLevel, arrayElement);
811
812         MemoryOp::pack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth,
813                 imageLayout.rowPitch, imageLayout.depthPitch, data, destPtr);
814 }
815
816 vk::VkDeviceSize Image::getPixelOffset (vk::VkOffset3D          offset,
817                                                                                 vk::VkDeviceSize        rowPitch,
818                                                                                 vk::VkDeviceSize        depthPitch,
819                                                                                 unsigned int            level,
820                                                                                 unsigned int            layer)
821 {
822         DE_ASSERT(level < m_levelCount);
823         DE_ASSERT(layer < m_layerCount);
824
825         vk::VkDeviceSize mipLevelSizes[32];
826         vk::VkDeviceSize mipLevelRectSizes[32];
827         tcu::IVec3 mipExtend
828         = tcu::IVec3(m_extent.width, m_extent.height, m_extent.depth);
829
830         vk::VkDeviceSize arrayElemSize = 0;
831         for (unsigned int i = 0; i < m_levelCount && (mipExtend[0] > 1 || mipExtend[1] > 1 || mipExtend[2] > 1); ++i)
832         {
833                 // Rect size is just a 3D image size;
834                 mipLevelSizes[i] = mipExtend[2] * depthPitch;
835
836                 arrayElemSize += mipLevelSizes[0];
837
838                 mipExtend = tcu::max(mipExtend / 2, tcu::IVec3(1));
839         }
840
841         vk::VkDeviceSize pixelOffset = layer * arrayElemSize;
842         for (size_t i = 0; i < level; ++i) {
843                 pixelOffset += mipLevelSizes[i];
844         }
845         pixelOffset += offset.z * mipLevelRectSizes[level];
846         pixelOffset += offset.y * rowPitch;
847         pixelOffset += offset.x;
848
849         return pixelOffset;
850 }
851
852 void Image::bindMemory (de::MovePtr<vk::Allocation> allocation)
853 {
854         DE_ASSERT(allocation);
855         VK_CHECK(m_vk.bindImageMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
856
857         DE_ASSERT(!m_allocation);
858         m_allocation = allocation;
859 }
860
861 de::SharedPtr<Image> Image::createAndAlloc(const vk::DeviceInterface&   vk,
862                                                                                    vk::VkDevice                                 device,
863                                                                                    const vk::VkImageCreateInfo& createInfo,
864                                                                                    vk::Allocator&                                       allocator,
865                                                                                    vk::MemoryRequirement                memoryRequirement)
866 {
867         de::SharedPtr<Image> ret = create(vk, device, createInfo);
868
869         vk::VkMemoryRequirements imageRequirements = vk::getImageMemoryRequirements(vk, device, ret->object());
870         ret->bindMemory(allocator.allocate(imageRequirements, memoryRequirement));
871         return ret;
872 }
873
874 de::SharedPtr<Image> Image::create(const vk::DeviceInterface&   vk,
875                                                                    vk::VkDevice                                 device,
876                                                                    const vk::VkImageCreateInfo  &createInfo)
877 {
878         return de::SharedPtr<Image>(new Image(vk, device, createInfo.format, createInfo.extent,
879                                                                 createInfo.mipLevels, createInfo.arrayLayers,
880                                                                 vk::createImage(vk, device, &createInfo)));
881 }
882
883 void transition2DImage (const vk::DeviceInterface&      vk,
884                                                 vk::VkCommandBuffer                             cmdBuffer,
885                                                 vk::VkImage                                     image,
886                                                 vk::VkImageAspectFlags          aspectMask,
887                                                 vk::VkImageLayout                       oldLayout,
888                                                 vk::VkImageLayout                       newLayout)
889 {
890         vk::VkImageMemoryBarrier barrier;
891         barrier.sType                                   = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
892         barrier.pNext                                   = DE_NULL;
893         barrier.srcAccessMask                           = 0;
894         barrier.dstAccessMask                           = 0;
895         barrier.oldLayout                               = oldLayout;
896         barrier.newLayout                               = newLayout;
897         barrier.srcQueueFamilyIndex             = vk::VK_QUEUE_FAMILY_IGNORED;
898         barrier.dstQueueFamilyIndex     = vk::VK_QUEUE_FAMILY_IGNORED;
899         barrier.image                                   = image;
900         barrier.subresourceRange.aspectMask             = aspectMask;
901         barrier.subresourceRange.baseMipLevel   = 0;
902         barrier.subresourceRange.levelCount             = 1;
903         barrier.subresourceRange.baseArrayLayer = 0;
904         barrier.subresourceRange.layerCount             = 1;
905
906         void* barriers[] = { &barrier };
907
908         vk.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, DE_LENGTH_OF_ARRAY(barriers), barriers);
909 }
910
911 void initialTransitionColor2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
912 {
913         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
914 }
915
916 void initialTransitionDepth2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
917 {
918         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
919 }
920
921 void initialTransitionStencil2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
922 {
923         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
924 }
925
926 void initialTransitionDepthStencil2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
927 {
928         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
929 }
930
931 } // Draw
932 } // vkt