Merge branch 'jekstrand_renderpass_transfer_bit_fix' into 'master'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / dynamic_state / vktDynamicStateImageObjectUtil.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 "vktDynamicStateImageObjectUtil.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 "vktDynamicStateCreateInfoUtil.hpp"
45 #include "vktDynamicStateBufferObjectUtil.hpp"
46
47 #include "tcuTextureUtil.hpp"
48
49 namespace vkt
50 {
51 namespace DynamicState
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                 // 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                         m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
356                                                                         0, (const vk::VkMemoryBarrier*)DE_NULL,
357                                                                         0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
358                                                                         1, &barrier);
359                 }
360
361                 vk::VkBufferImageCopy region =
362                 {
363                         0, 0, 0,
364                         { aspect, mipLevel, arrayElement, 1 },
365                         offset,
366                         { (deUint32)width, (deUint32)height, (deUint32)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                         (const vk::VkPipelineStageFlags*)DE_NULL,
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 = {(deUint32)width, (deUint32)height, (deUint32)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, {(deUint32)width, (deUint32)height, (deUint32)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                 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                         (const vk::VkPipelineStageFlags*)DE_NULL,
483                         1,                                                                      // deUint32                                     commandBufferCount;
484                         &copyCmdBuffer.get(),                           // const VkCommandBuffer*       pCommandBuffers;
485                         0,                                                                      // deUint32                                     signalSemaphoreCount;
486                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
487                 };
488                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
489
490                 // TODO: make this less intrusive
491                 VK_CHECK(m_vk.queueWaitIdle(queue));
492         }
493         return stagingResource;
494 }
495
496 void Image::uploadVolume(const tcu::ConstPixelBufferAccess&     access,
497                                                  vk::VkQueue                                            queue,
498                                                  vk::Allocator&                                         allocator,
499                                                  vk::VkImageLayout                                      layout,
500                                                  vk::VkOffset3D                                         offset,
501                                                  vk::VkImageAspectFlagBits                      aspect,
502                                                  unsigned int                                           mipLevel,
503                                                  unsigned int                                           arrayElement)
504 {
505         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
506         {
507                 upload(queue, allocator, layout, offset, access.getWidth(),
508                 access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_3D,
509                 access.getDataPtr());
510         }
511         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
512         {
513                 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
514                 access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
515         }
516 }
517
518 void Image::uploadSurface (const tcu::ConstPixelBufferAccess&   access,
519                                                    vk::VkQueue                                                  queue,
520                                                    vk::Allocator&                                               allocator,
521                                                    vk::VkImageLayout                                    layout,
522                                                    vk::VkOffset3D                                               offset,
523                                                    vk::VkImageAspectFlagBits                    aspect,
524                                                    unsigned int                                                 mipLevel,
525                                                    unsigned int                                                 arrayElement)
526 {
527         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
528         {
529                 upload(queue, allocator, layout, offset, access.getWidth(),
530                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
531                         access.getDataPtr());
532         }
533         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
534         {
535                 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
536                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
537         }
538 }
539
540 void Image::uploadSurface1D (const tcu::ConstPixelBufferAccess& access,
541                                                          vk::VkQueue                                            queue,
542                                                          vk::Allocator&                                         allocator,
543                                                          vk::VkImageLayout                                      layout,
544                                                          vk::VkOffset3D                                         offset,
545                                                          vk::VkImageAspectFlagBits                      aspect,
546                                                          unsigned int                                           mipLevel,
547                                                          unsigned int                                           arrayElement)
548 {
549         if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
550         {
551                 upload(queue, allocator, layout, offset, access.getWidth(),
552                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
553                         access.getDataPtr());
554         }
555         if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
556         {
557                 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
558                         access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
559         }
560 }
561
562 void Image::uploadSurfaceLinear (const tcu::ConstPixelBufferAccess&     access,
563                                                                  vk::VkOffset3D                                         offset,
564                                                                  int                                                            width,
565                                                                  int                                                            height,
566                                                                  int                                                            depth,
567                                                                  vk::VkImageAspectFlagBits                      aspect,
568                                                                  unsigned int                                           mipLevel,
569                                                                  unsigned int                                           arrayElement)
570 {
571         uploadLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, access.getDataPtr());
572 }
573
574 void Image::upload (vk::VkQueue                                 queue,
575                                         vk::Allocator&                          allocator,
576                                         vk::VkImageLayout                       layout,
577                                         vk::VkOffset3D                          offset,
578                                         int                                                     width,
579                                         int                                                     height,
580                                         int                                                     depth,
581                                         unsigned int                            mipLevel,
582                                         unsigned int                            arrayElement,
583                                         vk::VkImageAspectFlagBits       aspect,
584                                         vk::VkImageType                         type,
585                                         const void *                            data)
586 {
587         DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
588
589         de::SharedPtr<Image> stagingResource;
590         vk::VkExtent3D extent = {(deUint32)width, (deUint32)height, (deUint32)depth};
591         ImageCreateInfo stagingResourceCreateInfo(
592                 type, m_format, extent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
593                 vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
594
595         stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
596                                                                 vk::MemoryRequirement::HostVisible);
597
598         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
599         stagingResource->uploadLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
600
601         {
602                 //todo [scygan] get proper queueFamilyIndex
603                 CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
604                 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
605
606                 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
607                 {
608                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,     // VkStructureType                      sType;
609                         DE_NULL,                                                                                        // const void*                          pNext;
610                         *copyCmdPool,                                                                           // VkCommandPool                        commandPool;
611                         vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,                            // VkCommandBufferLevel         level;
612                         1u,                                                                                                     // deUint32                                     bufferCount;
613                 };
614
615                 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
616
617                 CmdBufferBeginInfo beginInfo;
618                 VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
619
620                 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
621                 {
622                         layout = vk::VK_IMAGE_LAYOUT_GENERAL;
623
624                         vk::VkImageMemoryBarrier barrier;
625                         barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
626                         barrier.pNext = DE_NULL;
627                         barrier.srcAccessMask = 0;
628                         barrier.dstAccessMask = 0;
629                         barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
630                         barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
631                         barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
632                         barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
633                         barrier.image = object();
634
635                         barrier.subresourceRange.aspectMask = aspect;
636                         barrier.subresourceRange.baseMipLevel = 0;
637                         barrier.subresourceRange.levelCount = m_levelCount;
638                         barrier.subresourceRange.baseArrayLayer = 0;
639                         barrier.subresourceRange.layerCount = m_layerCount;
640
641                         m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
642                                                                         0, (const vk::VkMemoryBarrier*)DE_NULL,
643                                                                         0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
644                                                                         1, &barrier);
645                 }
646
647                 transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL);
648
649                 vk::VkImageCopy region = {{aspect, 0, 0, 1},
650                                                                         zeroOffset,
651                                                                         {aspect, mipLevel, arrayElement, 1},
652                                                                         offset,
653                                                                         {(deUint32)width, (deUint32)height, (deUint32)depth}};
654
655                 m_vk.cmdCopyImage(*copyCmdBuffer, stagingResource->object(),
656                                                                 vk::VK_IMAGE_LAYOUT_GENERAL, object(), layout, 1, &region);
657                 VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
658
659                 vk::VkSubmitInfo submitInfo =
660                 {
661                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
662                         DE_NULL,                                                        // const void*                          pNext;
663                         0,                                                                      // deUint32                                     waitSemaphoreCount;
664                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
665                         (const vk::VkPipelineStageFlags*)DE_NULL,
666                         1,                                                                      // deUint32                                     commandBufferCount;
667                         &copyCmdBuffer.get(),                           // const VkCommandBuffer*       pCommandBuffers;
668                         0,                                                                      // deUint32                                     signalSemaphoreCount;
669                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
670                 };
671                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
672
673                 // TODO: make this less intrusive
674                 VK_CHECK(m_vk.queueWaitIdle(queue));
675         }
676 }
677
678 void Image::uploadUsingBuffer (vk::VkQueue                                      queue,
679                                                            vk::Allocator&                               allocator,
680                                                            vk::VkImageLayout                    layout,
681                                                            vk::VkOffset3D                               offset,
682                                                            int                                                  width,
683                                                            int                                                  height,
684                                                            int                                                  depth,
685                                                            unsigned int                                 mipLevel,
686                                                            unsigned int                                 arrayElement,
687                                                            vk::VkImageAspectFlagBits    aspect,
688                                                            const void *                                 data)
689 {
690         DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
691
692         de::SharedPtr<Buffer> stagingResource;
693         bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
694         vk::VkDeviceSize bufferSize = 0;
695         if (!isCombinedType)
696                 bufferSize = vk::mapVkFormat(m_format).getPixelSize() *width*height*depth;
697         if (isCombinedType)
698         {
699                 int pixelSize = 0;
700                 switch (m_format)
701                 {
702                         case vk::VK_FORMAT_D16_UNORM_S8_UINT:
703                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
704                                 break;
705                         case  vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
706                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
707                                 break;
708                         case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
709                         case vk::VK_FORMAT_D24_UNORM_S8_UINT:
710                                 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 3 : 1;
711                                 break;
712
713                         default:
714                                 DE_FATAL("Not implemented");
715                 }
716                 bufferSize = pixelSize*width*height*depth;
717         }
718         BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
719         stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator, vk::MemoryRequirement::HostVisible);
720         char* destPtr = reinterpret_cast<char*>(stagingResource->getBoundMemory().getHostPtr());
721         deMemcpy(destPtr, data, static_cast<size_t>(bufferSize));
722         vk::flushMappedMemoryRange(m_vk, m_device, stagingResource->getBoundMemory().getMemory(), stagingResource->getBoundMemory().getOffset(), bufferSize);
723         {
724                 //todo [scygan] get proper queueFamilyIndex
725                 CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
726                 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
727
728                 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
729                 {
730                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,     // VkStructureType                      sType;
731                         DE_NULL,                                                                                        // const void*                          pNext;
732                         *copyCmdPool,                                                                           // VkCommandPool                        commandPool;
733                         vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,                            // VkCommandBufferLevel         level;
734                         1u,                                                                                                     // deUint32                                     bufferCount;
735                 };
736                 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
737
738                 CmdBufferBeginInfo beginInfo;
739                 VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
740
741                 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
742                 {
743                         layout = vk::VK_IMAGE_LAYOUT_GENERAL;
744
745                         vk::VkImageMemoryBarrier barrier;
746                         barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
747                         barrier.pNext = DE_NULL;
748                         barrier.srcAccessMask = 0;
749                         barrier.dstAccessMask = 0;
750                         barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
751                         barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
752                         barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
753                         barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
754                         barrier.image = object();
755
756                         barrier.subresourceRange.aspectMask = aspect;
757                         barrier.subresourceRange.baseMipLevel = 0;
758                         barrier.subresourceRange.levelCount = m_levelCount;
759                         barrier.subresourceRange.baseArrayLayer = 0;
760                         barrier.subresourceRange.layerCount = m_layerCount;
761
762                         m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
763                                                                         0, (const vk::VkMemoryBarrier*)DE_NULL,
764                                                                         0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
765                                                                         1, &barrier);
766                 }
767
768                 vk::VkBufferImageCopy region = {
769                         0, 0, 0,
770                         { aspect, mipLevel, arrayElement, 1 },
771                         offset,
772                         { (deUint32)width, (deUint32)height, (deUint32)depth }
773                 };
774
775                 m_vk.cmdCopyBufferToImage(*copyCmdBuffer, stagingResource->object(),
776                         object(), layout, 1, &region);
777                 VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
778
779                 vk::VkSubmitInfo submitInfo =
780                 {
781                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
782                         DE_NULL,                                                        // const void*                          pNext;
783                         0,                                                                      // deUint32                                     waitSemaphoreCount;
784                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
785                         (const vk::VkPipelineStageFlags*)DE_NULL,
786                         1,                                                                      // deUint32                                     commandBufferCount;
787                         &copyCmdBuffer.get(),                           // const VkCommandBuffer*       pCommandBuffers;
788                         0,                                                                      // deUint32                                     signalSemaphoreCount;
789                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
790                 };
791                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
792
793                 // TODO: make this less intrusive
794                 VK_CHECK(m_vk.queueWaitIdle(queue));
795         }
796 }
797
798 void Image::uploadLinear (vk::VkOffset3D                        offset,
799                                                   int                                           width,
800                                                   int                                           height,
801                                                   int                                           depth,
802                                                   unsigned int                          mipLevel,
803                                                   unsigned int                          arrayElement,
804                                                   vk::VkImageAspectFlagBits     aspect,
805                                                   const void *                          data)
806 {
807         vk::VkSubresourceLayout imageLayout;
808
809         vk::VkImageSubresource imageSubResource = {aspect, mipLevel, arrayElement};
810
811         m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource,
812                                                                                                         &imageLayout);
813
814         char* destPtr = reinterpret_cast<char*>(getBoundMemory().getHostPtr());
815
816         destPtr += imageLayout.offset + getPixelOffset(offset, imageLayout.rowPitch, imageLayout.depthPitch, mipLevel, arrayElement);
817
818         MemoryOp::pack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth,
819                 imageLayout.rowPitch, imageLayout.depthPitch, data, destPtr);
820 }
821
822 vk::VkDeviceSize Image::getPixelOffset (vk::VkOffset3D          offset,
823                                                                                 vk::VkDeviceSize        rowPitch,
824                                                                                 vk::VkDeviceSize        depthPitch,
825                                                                                 unsigned int            level,
826                                                                                 unsigned int            layer)
827 {
828         DE_ASSERT(level < m_levelCount);
829         DE_ASSERT(layer < m_layerCount);
830
831         vk::VkDeviceSize mipLevelSizes[32];
832         vk::VkDeviceSize mipLevelRectSizes[32];
833         tcu::IVec3 mipExtend
834         = tcu::IVec3(m_extent.width, m_extent.height, m_extent.depth);
835
836         vk::VkDeviceSize arrayElemSize = 0;
837         for (unsigned int i = 0; i < m_levelCount && (mipExtend[0] > 1 || mipExtend[1] > 1 || mipExtend[2] > 1); ++i)
838         {
839                 // Rect size is just a 3D image size;
840                 mipLevelSizes[i] = mipExtend[2] * depthPitch;
841
842                 arrayElemSize += mipLevelSizes[0];
843
844                 mipExtend = tcu::max(mipExtend / 2, tcu::IVec3(1));
845         }
846
847         vk::VkDeviceSize pixelOffset = layer * arrayElemSize;
848         for (size_t i = 0; i < level; ++i) {
849                 pixelOffset += mipLevelSizes[i];
850         }
851         pixelOffset += offset.z * mipLevelRectSizes[level];
852         pixelOffset += offset.y * rowPitch;
853         pixelOffset += offset.x;
854
855         return pixelOffset;
856 }
857
858 void Image::bindMemory (de::MovePtr<vk::Allocation> allocation)
859 {
860         DE_ASSERT(allocation);
861         VK_CHECK(m_vk.bindImageMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
862
863         DE_ASSERT(!m_allocation);
864         m_allocation = allocation;
865 }
866
867 de::SharedPtr<Image> Image::createAndAlloc(const vk::DeviceInterface&   vk,
868                                                                                    vk::VkDevice                                 device,
869                                                                                    const vk::VkImageCreateInfo& createInfo,
870                                                                                    vk::Allocator&                               allocator,
871                                                                                    vk::MemoryRequirement                memoryRequirement)
872 {
873         de::SharedPtr<Image> ret = create(vk, device, createInfo);
874
875         vk::VkMemoryRequirements imageRequirements = vk::getImageMemoryRequirements(vk, device, ret->object());
876         ret->bindMemory(allocator.allocate(imageRequirements, memoryRequirement));
877         return ret;
878 }
879
880 de::SharedPtr<Image> Image::create(const vk::DeviceInterface&   vk,
881                                                                    vk::VkDevice                                 device,
882                                                                    const vk::VkImageCreateInfo  &createInfo)
883 {
884         return de::SharedPtr<Image>(new Image(vk, device, createInfo.format, createInfo.extent,
885                                                                 createInfo.mipLevels, createInfo.arrayLayers,
886                                                                 vk::createImage(vk, device, &createInfo)));
887 }
888
889 void transition2DImage (const vk::DeviceInterface&      vk,
890                                                 vk::VkCommandBuffer                             cmdBuffer,
891                                                 vk::VkImage                                     image,
892                                                 vk::VkImageAspectFlags          aspectMask,
893                                                 vk::VkImageLayout                       oldLayout,
894                                                 vk::VkImageLayout                       newLayout)
895 {
896         vk::VkImageMemoryBarrier barrier;
897         barrier.sType                                   = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
898         barrier.pNext                                   = DE_NULL;
899         barrier.srcAccessMask                           = 0;
900         barrier.dstAccessMask                           = 0;
901         barrier.oldLayout                               = oldLayout;
902         barrier.newLayout                               = newLayout;
903         barrier.srcQueueFamilyIndex             = vk::VK_QUEUE_FAMILY_IGNORED;
904         barrier.dstQueueFamilyIndex     = vk::VK_QUEUE_FAMILY_IGNORED;
905         barrier.image                                   = image;
906         barrier.subresourceRange.aspectMask             = aspectMask;
907         barrier.subresourceRange.baseMipLevel   = 0;
908         barrier.subresourceRange.levelCount             = 1;
909         barrier.subresourceRange.baseArrayLayer = 0;
910         barrier.subresourceRange.layerCount             = 1;
911
912         vk.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
913                                                   0, (const vk::VkMemoryBarrier*)DE_NULL,
914                                                   0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
915                                                   1, &barrier);
916 }
917
918 void initialTransitionColor2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
919 {
920         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
921 }
922
923 void initialTransitionDepth2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
924 {
925         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
926 }
927
928 void initialTransitionStencil2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
929 {
930         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
931 }
932
933 void initialTransitionDepthStencil2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
934 {
935         transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
936 }
937
938 } // DynamicState
939 } // vkt