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