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