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