Fix stageMask (0x1) usage in renderpass, image and texture tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / image / vktImageMutableTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Tests for mutable images
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktImageMutableTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktImageTexture.hpp"
27
28 #include "vkBuilderUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkImageUtil.hpp"
31
32 #include "deUniquePtr.hpp"
33 #include "deSharedPtr.hpp"
34
35 #include "tcuImageCompare.hpp"
36 #include "tcuTestLog.hpp"
37 #include "tcuTextureUtil.hpp"
38
39 #include <string>
40 #include <vector>
41
42 using namespace vk;
43 using namespace tcu;
44
45 using de::UniquePtr;
46 using de::MovePtr;
47 using de::SharedPtr;
48 using std::vector;
49
50 namespace vkt
51 {
52 namespace image
53 {
54
55 typedef SharedPtr<Unique<VkPipeline> >  SharedPtrVkPipeline;
56 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
57
58 template<typename T>
59 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
60 {
61         return SharedPtr<Unique<T> >(new Unique<T>(move));
62 }
63
64 enum Upload {
65         UPLOAD_CLEAR = 0,
66         UPLOAD_COPY,
67         UPLOAD_STORE,
68         UPLOAD_DRAW,
69         UPLOAD_LAST
70 };
71
72 enum Download {
73         DOWNLOAD_COPY = 0,
74         DOWNLOAD_LOAD,
75         DOWNLOAD_TEXTURE,
76         DOWNLOAD_LAST
77 };
78
79 std::string getUploadString (const int upload)
80 {
81         const char* strs[] = { "clear", "copy", "store", "draw" };
82         return strs[upload];
83 }
84
85 std::string getDownloadString (const int download)
86 {
87         const char* strs[] = { "copy", "load", "texture" };
88         return strs[download];
89 }
90
91 struct CaseDef
92 {
93         ImageType               imageType;
94         IVec3                   size;
95         deUint32                numLayers;
96         VkFormat                imageFormat;
97         VkFormat                viewFormat;
98         enum Upload             upload;
99         enum Download   download;
100         bool                    isFormatListTest;
101 };
102
103 static const deUint32 COLOR_TABLE_SIZE = 4;
104
105 // Reference color values for float color rendering. Values have been chosen
106 // so that when the bit patterns are reinterpreted as a 16-bit float, we do not
107 // run into NaN / inf / denorm values.
108 static const Vec4       COLOR_TABLE_FLOAT[COLOR_TABLE_SIZE]     =
109 {
110         Vec4(0.00f, 0.40f, 0.80f, 0.10f),
111         Vec4(0.10f, 0.50f, 0.90f, 0.20f),
112         Vec4(0.20f, 0.60f, 1.00f, 0.30f),
113         Vec4(0.30f, 0.70f, 0.00f, 0.40f),
114 };
115
116 // Reference color values for integer color rendering. We avoid negative
117 // values (even for SINT formats) to avoid the situation where sign extension
118 // leads to NaN / inf values when they are reinterpreted with a float
119 // format.
120 static const IVec4      COLOR_TABLE_INT[COLOR_TABLE_SIZE]       =
121 {
122         IVec4(112,  60, 101,  41),
123         IVec4( 60, 101,  41, 112),
124         IVec4( 41, 112,  60, 101),
125         IVec4(101,  41, 112,  60),
126 };
127
128 // Reference clear colors created from the color table values
129 static const VkClearValue REFERENCE_CLEAR_COLOR_FLOAT[COLOR_TABLE_SIZE] =
130 {
131         makeClearValueColorF32(COLOR_TABLE_FLOAT[0].x(), COLOR_TABLE_FLOAT[0].y(), COLOR_TABLE_FLOAT[0].z(), COLOR_TABLE_FLOAT[0].w()),
132         makeClearValueColorF32(COLOR_TABLE_FLOAT[1].x(), COLOR_TABLE_FLOAT[1].y(), COLOR_TABLE_FLOAT[1].z(), COLOR_TABLE_FLOAT[1].w()),
133         makeClearValueColorF32(COLOR_TABLE_FLOAT[2].x(), COLOR_TABLE_FLOAT[2].y(), COLOR_TABLE_FLOAT[2].z(), COLOR_TABLE_FLOAT[2].w()),
134         makeClearValueColorF32(COLOR_TABLE_FLOAT[3].x(), COLOR_TABLE_FLOAT[3].y(), COLOR_TABLE_FLOAT[3].z(), COLOR_TABLE_FLOAT[3].w()),
135 };
136
137 static const VkClearValue REFERENCE_CLEAR_COLOR_INT[COLOR_TABLE_SIZE]   =
138 {
139         makeClearValueColorI32(COLOR_TABLE_INT[0].x(), COLOR_TABLE_INT[0].y(), COLOR_TABLE_INT[0].z(), COLOR_TABLE_INT[0].w()),
140         makeClearValueColorI32(COLOR_TABLE_INT[1].x(), COLOR_TABLE_INT[1].y(), COLOR_TABLE_INT[1].z(), COLOR_TABLE_INT[1].w()),
141         makeClearValueColorI32(COLOR_TABLE_INT[2].x(), COLOR_TABLE_INT[2].y(), COLOR_TABLE_INT[2].z(), COLOR_TABLE_INT[2].w()),
142         makeClearValueColorI32(COLOR_TABLE_INT[3].x(), COLOR_TABLE_INT[3].y(), COLOR_TABLE_INT[3].z(), COLOR_TABLE_INT[3].w()),
143 };
144
145 static const Texture s_textures[] =
146 {
147         Texture(IMAGE_TYPE_2D,                  tcu::IVec3(32, 32, 1),  1),
148         Texture(IMAGE_TYPE_2D_ARRAY,    tcu::IVec3(32, 32, 1),  4),
149 };
150
151 VkImageType getImageType (const ImageType textureImageType)
152 {
153         switch (textureImageType)
154         {
155                 case IMAGE_TYPE_2D:
156                 case IMAGE_TYPE_2D_ARRAY:
157                         return VK_IMAGE_TYPE_2D;
158
159                 default:
160                         DE_ASSERT(0);
161                         return VK_IMAGE_TYPE_LAST;
162         }
163 }
164
165 VkImageViewType getImageViewType (const ImageType textureImageType)
166 {
167         switch (textureImageType)
168         {
169                 case IMAGE_TYPE_2D:
170                         return VK_IMAGE_VIEW_TYPE_2D;
171                 case IMAGE_TYPE_2D_ARRAY:
172                         return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
173
174                 default:
175                         DE_ASSERT(0);
176                         return VK_IMAGE_VIEW_TYPE_LAST;
177         }
178 }
179
180 static const VkFormat s_formats[] =
181 {
182         VK_FORMAT_R32G32B32A32_SFLOAT,
183         VK_FORMAT_R16G16B16A16_SFLOAT,
184         VK_FORMAT_R32G32_SFLOAT,
185         VK_FORMAT_R16G16_SFLOAT,
186         VK_FORMAT_R32_SFLOAT,
187
188         VK_FORMAT_R32G32B32A32_UINT,
189         VK_FORMAT_R16G16B16A16_UINT,
190         VK_FORMAT_R8G8B8A8_UINT,
191         VK_FORMAT_R32G32_UINT,
192         VK_FORMAT_R16G16_UINT,
193         VK_FORMAT_R32_UINT,
194
195         VK_FORMAT_R32G32B32A32_SINT,
196         VK_FORMAT_R16G16B16A16_SINT,
197         VK_FORMAT_R8G8B8A8_SINT,
198         VK_FORMAT_R32G32_SINT,
199         VK_FORMAT_R16G16_SINT,
200         VK_FORMAT_R32_SINT,
201
202         VK_FORMAT_R8G8B8A8_UNORM,
203
204         VK_FORMAT_R8G8B8A8_SNORM,
205 };
206
207 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
208 {
209         return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
210 }
211
212 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
213 {
214         std::ostringstream str;
215         if (numComponents == 1)
216                 str << (isUint ? "uint" : isSint ? "int" : "float");
217         else
218                 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
219
220         return str.str();
221 }
222
223 std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
224 {
225         std::ostringstream samplerType;
226
227         if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
228                 samplerType << "u";
229         else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
230                 samplerType << "i";
231
232         switch (type)
233         {
234                 case VK_IMAGE_VIEW_TYPE_2D:
235                         samplerType << "sampler2D";
236                         break;
237
238                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
239                         samplerType << "sampler2DArray";
240                         break;
241
242                 default:
243                         DE_FATAL("Ivalid image view type");
244                         break;
245         }
246
247         return samplerType.str();
248 }
249
250 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
251 {
252         if (caseDef.upload == UPLOAD_DRAW)
253         {
254                 {
255                         std::ostringstream src;
256                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
257                                 << "\n"
258                                 << "layout(location = 0) in  vec4 in_position;\n"
259                                 << "layout(location = 1) in  vec4 in_color;\n"
260                                 << "layout(location = 0) out vec4 out_color;\n"
261                                 << "\n"
262                                 << "out gl_PerVertex {\n"
263                                 << "    vec4 gl_Position;\n"
264                                 << "};\n"
265                                 << "\n"
266                                 << "void main(void)\n"
267                                 << "{\n"
268                                 << "    gl_Position     = in_position;\n"
269                                 << "    out_color       = in_color;\n"
270                                 << "}\n";
271
272                         programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str());
273                 }
274
275                 {
276                         const int       numComponents           = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
277                         const bool      isUint                          = isUintFormat(caseDef.viewFormat);
278                         const bool      isSint                          = isIntFormat(caseDef.viewFormat);
279                         const std::string colorFormat   = getColorFormatStr(numComponents, isUint, isSint);
280
281                         std::ostringstream src;
282                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
283                                 << "\n"
284                                 << "layout(location = 0) in  vec4 in_color;\n"
285                                 << "layout(location = 0) out " << colorFormat << " out_color;\n"
286                                 << "\n"
287                                 << "void main(void)\n"
288                                 << "{\n"
289                                 << "    out_color = " << colorFormat << "("
290                                 << (numComponents == 1 ? "in_color.r"   :
291                                         numComponents == 2 ? "in_color.rg"  :
292                                         numComponents == 3 ? "in_color.rgb" : "in_color")
293                                 << ");\n"
294                                 << "}\n";
295
296                         programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str());
297                 }
298         }
299
300         if (caseDef.upload == UPLOAD_STORE)
301         {
302                 const TextureFormat     tcuFormat               = mapVkFormat(caseDef.viewFormat);
303                 const std::string       imageFormatStr  = getShaderImageFormatQualifier(tcuFormat);
304                 const std::string       imageTypeStr    = getShaderImageType(tcuFormat, caseDef.imageType);
305                 const std::string       colorTypeStr    = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
306                 const bool                      isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
307
308                 std::ostringstream src;
309                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
310                         << "\n"
311                         << "layout (local_size_x = 1) in;\n"
312                         << "\n"
313                         << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
314                         << "\n"
315                         << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
316                 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
317                 {
318                         if (isIntegerFormat)
319                                 src << "     " << colorTypeStr << "(" << COLOR_TABLE_INT[idx].x() << ", " << COLOR_TABLE_INT[idx].y() << ", " << COLOR_TABLE_INT[idx].z() << ", " << COLOR_TABLE_INT[idx].w() << ")";
320                         else
321                                 src << "     " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
322                         if (idx < COLOR_TABLE_SIZE - 1)
323                                 src << ",";
324                         src << "\n";
325                 }
326                 src << ");\n"
327                         << "\n"
328                         << "void main(void)\n"
329                         << "{\n";
330                 if (caseDef.imageType == IMAGE_TYPE_2D)
331                 {
332                         src     << "    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
333                 }
334                 else
335                 {
336                         DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
337                         src     << "    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
338                 }
339                 src << "    " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
340                         << "    imageStore(u_image, pos, color);\n"
341                         << "}\n";
342
343                 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
344         }
345
346         if (caseDef.download == DOWNLOAD_LOAD)
347         {
348                 const TextureFormat     tcuFormat               = mapVkFormat(caseDef.viewFormat);
349                 const std::string       imageFormatStr  = getShaderImageFormatQualifier(tcuFormat);
350                 const std::string       imageTypeStr    = getShaderImageType(tcuFormat, caseDef.imageType);
351                 const std::string       colorTypeStr    = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
352
353                 std::ostringstream src;
354                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
355                         << "\n"
356                         << "layout (local_size_x = 1) in;\n"
357                         << "\n"
358                         << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
359                         << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
360                         << "\n"
361                         << "void main(void)\n"
362                         << "{\n";
363                 if (caseDef.imageType == IMAGE_TYPE_2D)
364                 {
365                         src     << "    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
366                 }
367                 else
368                 {
369                         DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
370                         src     << "    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
371                 }
372                 src     << "    imageStore(out_image, pos, imageLoad(in_image, pos));\n"
373                         << "}\n";
374
375                 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
376         }
377
378         if (caseDef.download == DOWNLOAD_TEXTURE)
379         {
380                 const TextureFormat             tcuFormat               = mapVkFormat(caseDef.viewFormat);
381                 const VkImageViewType   viewType                = getImageViewType(caseDef.imageType);
382                 const std::string               samplerTypeStr  = getShaderSamplerType(tcuFormat, viewType);
383                 const std::string               imageFormatStr  = getShaderImageFormatQualifier(tcuFormat);
384                 const std::string               imageTypeStr    = getShaderImageType(tcuFormat, caseDef.imageType);
385                 const std::string               colorTypeStr    = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
386
387                 std::ostringstream src;
388                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
389                         << "\n"
390                         << "layout (local_size_x = 1) in;\n"
391                         << "\n"
392                         << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
393                         << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
394                         << "\n"
395                         << "void main(void)\n"
396                         << "{\n";
397                 if (caseDef.imageType == IMAGE_TYPE_2D)
398                 {
399                         src     << "    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
400                 }
401                 else
402                 {
403                         DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
404                         src     << "    ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
405                 }
406                 src     << "    imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
407                         << "}\n";
408
409                 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
410         }
411 }
412
413 Move<VkImage> makeImage (const DeviceInterface&         vk,
414                                                  const VkDevice                         device,
415                                                  VkImageCreateFlags                     flags,
416                                                  VkImageType                            imageType,
417                                                  const VkFormat                         format,
418                                                  const VkFormat                         viewFormat,
419                                                  const bool                                     useImageFormatList,
420                                                  const IVec3&                           size,
421                                                  const deUint32                         numMipLevels,
422                                                  const deUint32                         numLayers,
423                                                  const VkImageUsageFlags        usage)
424 {
425         const VkFormat formatList[2] =
426         {
427                 format,
428                 viewFormat
429         };
430
431         const VkImageFormatListCreateInfoKHR formatListInfo =
432         {
433                 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,    // VkStructureType                      sType;
434                 DE_NULL,                                                                                                // const void*                          pNext;
435                 2u,                                                                                                             // deUint32                                     viewFormatCount
436                 formatList                                                                                              // const VkFormat*                      pViewFormats
437         };
438
439         const VkImageCreateInfo imageParams =
440         {
441                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                    // VkStructureType                      sType;
442                 useImageFormatList ? &formatListInfo : DE_NULL,                 // const void*                          pNext;
443                 flags,                                                                                                  // VkImageCreateFlags           flags;
444                 imageType,                                                                                              // VkImageType                          imageType;
445                 format,                                                                                                 // VkFormat                                     format;
446                 makeExtent3D(size),                                                                             // VkExtent3D                           extent;
447                 numMipLevels,                                                                                   // deUint32                                     mipLevels;
448                 numLayers,                                                                                              // deUint32                                     arrayLayers;
449                 VK_SAMPLE_COUNT_1_BIT,                                                                  // VkSampleCountFlagBits        samples;
450                 VK_IMAGE_TILING_OPTIMAL,                                                                // VkImageTiling                        tiling;
451                 usage,                                                                                                  // VkImageUsageFlags            usage;
452                 VK_SHARING_MODE_EXCLUSIVE,                                                              // VkSharingMode                        sharingMode;
453                 0u,                                                                                                             // deUint32                                     queueFamilyIndexCount;
454                 DE_NULL,                                                                                                // const deUint32*                      pQueueFamilyIndices;
455                 VK_IMAGE_LAYOUT_UNDEFINED,                                                              // VkImageLayout                        initialLayout;
456         };
457         return createImage(vk, device, &imageParams);
458 }
459
460 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
461 {
462         const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
463         return createBuffer(vk, device, &bufferCreateInfo);
464 }
465
466 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
467 {
468         return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
469 }
470
471 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
472 {
473         const VkSamplerCreateInfo samplerParams =
474         {
475                 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,          // VkStructureType                      sType;
476                 DE_NULL,                                                                        // const void*                          pNext;
477                 (VkSamplerCreateFlags)0,                                        // VkSamplerCreateFlags         flags;
478                 VK_FILTER_NEAREST,                                                      // VkFilter                                     magFilter;
479                 VK_FILTER_NEAREST,                                                      // VkFilter                                     minFilter;
480                 VK_SAMPLER_MIPMAP_MODE_NEAREST,                         // VkSamplerMipmapMode          mipmapMode;
481                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeU;
482                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeV;
483                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeW;
484                 0.0f,                                                                           // float                                        mipLodBias;
485                 VK_FALSE,                                                                       // VkBool32                                     anisotropyEnable;
486                 1.0f,                                                                           // float                                        maxAnisotropy;
487                 VK_FALSE,                                                                       // VkBool32                                     compareEnable;
488                 VK_COMPARE_OP_ALWAYS,                                           // VkCompareOp                          compareOp;
489                 0.0f,                                                                           // float                                        minLod;
490                 0.0f,                                                                           // float                                        maxLod;
491                 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,        // VkBorderColor                        borderColor;
492                 VK_FALSE,                                                                       // VkBool32                                     unnormalizedCoordinates;
493         };
494
495         return createSampler(vk, device, &samplerParams);
496 }
497
498
499 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&       vk,
500                                                                                    const VkDevice                       device)
501 {
502         const VkPipelineLayoutCreateInfo info =
503         {
504                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
505                 DE_NULL,
506                 (VkPipelineLayoutCreateFlags)0,
507                 0u,
508                 DE_NULL,
509                 0u,
510                 DE_NULL,
511         };
512         return createPipelineLayout(vk, device, &info);
513 }
514
515 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&           vk,
516                                                                            const VkDevice                               device,
517                                                                            const VkPipelineLayout               pipelineLayout,
518                                                                            const VkRenderPass                   renderPass,
519                                                                            const VkShaderModule                 vertexModule,
520                                                                            const VkShaderModule                 fragmentModule,
521                                                                            const IVec2&                                 renderSize,
522                                                                            const VkPrimitiveTopology    topology,
523                                                                            const deUint32                               subpass)
524 {
525         const VkVertexInputBindingDescription vertexInputBindingDescription =
526         {
527                 0u,                                                                     // deUint32                             binding;
528                 (deUint32)(2 * sizeof(Vec4)),           // deUint32                             stride;
529                 VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
530         };
531
532         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
533         {
534                 {
535                         0u,                                                             // deUint32                     location;
536                         0u,                                                             // deUint32                     binding;
537                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat                     format;
538                         0u,                                                             // deUint32                     offset;
539                 },
540                 {
541                         1u,                                                             // deUint32                     location;
542                         0u,                                                             // deUint32                     binding;
543                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat                     format;
544                         (deUint32)sizeof(Vec4),                 // deUint32                     offset;
545                 }
546         };
547
548         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
549         {
550                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
551                 DE_NULL,                                                                                                        // const void*                                                          pNext;
552                 (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags        flags;
553                 1u,                                                                                                                     // deUint32                                                                     vertexBindingDescriptionCount;
554                 &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
555                 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),           // deUint32                                                                     vertexAttributeDescriptionCount;
556                 vertexInputAttributeDescriptions,                                                       // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
557         };
558
559         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
560         {
561                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
562                 DE_NULL,                                                                                                                // const void*                                                          pNext;
563                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
564                 topology,                                                                                                               // VkPrimitiveTopology                                          topology;
565                 VK_FALSE,                                                                                                               // VkBool32                                                                     primitiveRestartEnable;
566         };
567
568         const VkViewport viewport = makeViewport(
569                 0.0f, 0.0f,
570                 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
571                 0.0f, 1.0f);
572
573         const VkRect2D scissor =
574         {
575                 makeOffset2D(0, 0),
576                 makeExtent2D(renderSize.x(), renderSize.y()),
577         };
578
579         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
580         {
581                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,          // VkStructureType                                              sType;
582                 DE_NULL,                                                                                                        // const void*                                                  pNext;
583                 (VkPipelineViewportStateCreateFlags)0,                                          // VkPipelineViewportStateCreateFlags   flags;
584                 1u,                                                                                                                     // deUint32                                                             viewportCount;
585                 &viewport,                                                                                                      // const VkViewport*                                    pViewports;
586                 1u,                                                                                                                     // deUint32                                                             scissorCount;
587                 &scissor,                                                                                                       // const VkRect2D*                                              pScissors;
588         };
589
590         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
591         {
592                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
593                 DE_NULL,                                                                                                        // const void*                                                          pNext;
594                 (VkPipelineRasterizationStateCreateFlags)0,                                     // VkPipelineRasterizationStateCreateFlags      flags;
595                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthClampEnable;
596                 VK_FALSE,                                                                                                       // VkBool32                                                                     rasterizerDiscardEnable;
597                 VK_POLYGON_MODE_FILL,                                                                           // VkPolygonMode                                                        polygonMode;
598                 VK_CULL_MODE_NONE,                                                                                      // VkCullModeFlags                                                      cullMode;
599                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                        // VkFrontFace                                                          frontFace;
600                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBiasEnable;
601                 0.0f,                                                                                                           // float                                                                        depthBiasConstantFactor;
602                 0.0f,                                                                                                           // float                                                                        depthBiasClamp;
603                 0.0f,                                                                                                           // float                                                                        depthBiasSlopeFactor;
604                 1.0f,                                                                                                           // float                                                                        lineWidth;
605         };
606
607         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
608         {
609                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
610                 DE_NULL,                                                                                                        // const void*                                                          pNext;
611                 (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
612                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
613                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
614                 0.0f,                                                                                                           // float                                                                        minSampleShading;
615                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
616                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
617                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
618         };
619
620         const VkStencilOpState stencilOpState = makeStencilOpState(
621                 VK_STENCIL_OP_KEEP,                                                                                     // stencil fail
622                 VK_STENCIL_OP_ZERO,                                                                                     // depth & stencil pass
623                 VK_STENCIL_OP_KEEP,                                                                                     // depth only fail
624                 VK_COMPARE_OP_EQUAL,                                                                            // compare op
625                 ~0u,                                                                                                            // compare mask
626                 ~0u,                                                                                                            // write mask
627                 0u);                                                                                                            // reference
628
629         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
630         {
631                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
632                 DE_NULL,                                                                                                        // const void*                                                          pNext;
633                 (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
634                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
635                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
636                 VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
637                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
638                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
639                 stencilOpState,                                                                                         // VkStencilOpState                                                     front;
640                 stencilOpState,                                                                                         // VkStencilOpState                                                     back;
641                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
642                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
643         };
644
645         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
646         const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
647         {
648                 VK_FALSE,                                                                                                       // VkBool32                                     blendEnable;
649                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcColorBlendFactor;
650                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstColorBlendFactor;
651                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
652                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcAlphaBlendFactor;
653                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstAlphaBlendFactor;
654                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
655                 colorComponentsAll,                                                                                     // VkColorComponentFlags        colorWriteMask;
656         };
657
658         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
659         {
660                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
661                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
662                 (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
663                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
664                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
665                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
666                 &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
667                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
668         };
669
670         const VkPipelineShaderStageCreateInfo pShaderStages[] =
671         {
672                 {
673                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
674                         DE_NULL,                                                                                                // const void*                                                  pNext;
675                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
676                         VK_SHADER_STAGE_VERTEX_BIT,                                                             // VkShaderStageFlagBits                                stage;
677                         vertexModule,                                                                                   // VkShaderModule                                               module;
678                         "main",                                                                                                 // const char*                                                  pName;
679                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
680                 },
681                 {
682                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
683                         DE_NULL,                                                                                                // const void*                                                  pNext;
684                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
685                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // VkShaderStageFlagBits                                stage;
686                         fragmentModule,                                                                                 // VkShaderModule                                               module;
687                         "main",                                                                                                 // const char*                                                  pName;
688                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
689                 }
690         };
691
692         const VkGraphicsPipelineCreateInfo      graphicsPipelineInfo =
693         {
694                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
695                 DE_NULL,                                                                                        // const void*                                                                          pNext;
696                 0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
697                 DE_LENGTH_OF_ARRAY(pShaderStages),                                      // deUint32                                                                                     stageCount;
698                 pShaderStages,                                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
699                 &vertexInputStateInfo,                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
700                 &pipelineInputAssemblyStateInfo,                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
701                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
702                 &pipelineViewportStateInfo,                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
703                 &pipelineRasterizationStateInfo,                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
704                 &pipelineMultisampleStateInfo,                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
705                 &pipelineDepthStencilStateInfo,                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
706                 &pipelineColorBlendStateInfo,                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
707                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
708                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
709                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
710                 subpass,                                                                                        // deUint32                                                                                     subpass;
711                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
712                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
713         };
714
715         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
716 }
717
718 Move<VkPipeline> makeComputePipeline (const DeviceInterface&            vk,
719                                                                           const VkDevice                                device,
720                                                                           const VkPipelineLayout                pipelineLayout,
721                                                                           const VkShaderModule                  shaderModule,
722                                                                           const VkSpecializationInfo*   specInfo)
723 {
724         const VkPipelineShaderStageCreateInfo shaderStageInfo =
725         {
726                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                      sType;
727                 DE_NULL,                                                                                                // const void*                                          pNext;
728                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags     flags;
729                 VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                        stage;
730                 shaderModule,                                                                                   // VkShaderModule                                       module;
731                 "main",                                                                                                 // const char*                                          pName;
732                 specInfo,                                                                                               // const VkSpecializationInfo*          pSpecializationInfo;
733         };
734         const VkComputePipelineCreateInfo pipelineInfo =
735         {
736                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                 // VkStructureType                                      sType;
737                 DE_NULL,                                                                                                // const void*                                          pNext;
738                 (VkPipelineCreateFlags)0,                                                               // VkPipelineCreateFlags                        flags;
739                 shaderStageInfo,                                                                                // VkPipelineShaderStageCreateInfo      stage;
740                 pipelineLayout,                                                                                 // VkPipelineLayout                                     layout;
741                 DE_NULL,                                                                                                // VkPipeline                                           basePipelineHandle;
742                 0,                                                                                                              // deInt32                                                      basePipelineIndex;
743         };
744         return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
745 }
746
747 Move<VkRenderPass> makeRenderPass (const DeviceInterface&       vk,
748                                                                    const VkDevice                       device,
749                                                                    const VkFormat                       colorFormat,
750                                                                    const deUint32                       numLayers)
751 {
752         const VkAttachmentDescription colorAttachmentDescription =
753         {
754                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
755                 colorFormat,                                                                            // VkFormat                                                     format;
756                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
757                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
758                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
759                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
760                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
761                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
762                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
763         };
764         vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
765
766         // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
767         vector<VkAttachmentReference>   colorAttachmentReferences       (numLayers);
768         vector<VkSubpassDescription>    subpasses;
769
770         // Ordering here must match the framebuffer attachments
771         for (deUint32 i = 0; i < numLayers; ++i)
772         {
773                 const VkAttachmentReference attachmentRef =
774                 {
775                         i,                                                                                                      // deUint32                     attachment;
776                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
777                 };
778
779                 colorAttachmentReferences[i]    = attachmentRef;
780
781                 const VkSubpassDescription              subpassDescription      =
782                 {
783                         (VkSubpassDescriptionFlags)0,                                   // VkSubpassDescriptionFlags            flags;
784                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                // VkPipelineBindPoint                          pipelineBindPoint;
785                         0u,                                                                                             // deUint32                                                     inputAttachmentCount;
786                         DE_NULL,                                                                                // const VkAttachmentReference*         pInputAttachments;
787                         1u,                                                                                             // deUint32                                                     colorAttachmentCount;
788                         &colorAttachmentReferences[i],                                  // const VkAttachmentReference*         pColorAttachments;
789                         DE_NULL,                                                                                // const VkAttachmentReference*         pResolveAttachments;
790                         DE_NULL,                                                                                // const VkAttachmentReference*         pDepthStencilAttachment;
791                         0u,                                                                                             // deUint32                                                     preserveAttachmentCount;
792                         DE_NULL                                                                                 // const deUint32*                                      pPreserveAttachments;
793                 };
794                 subpasses.push_back(subpassDescription);
795         }
796
797         const VkRenderPassCreateInfo renderPassInfo =
798         {
799                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              // VkStructureType                                      sType;
800                 DE_NULL,                                                                                                // const void*                                          pNext;
801                 (VkRenderPassCreateFlags)0,                                                             // VkRenderPassCreateFlags                      flags;
802                 static_cast<deUint32>(attachmentDescriptions.size()),   // deUint32                                                     attachmentCount;
803                 &attachmentDescriptions[0],                                                             // const VkAttachmentDescription*       pAttachments;
804                 static_cast<deUint32>(subpasses.size()),                                // deUint32                                                     subpassCount;
805                 &subpasses[0],                                                                                  // const VkSubpassDescription*          pSubpasses;
806                 0u,                                                                                                             // deUint32                                                     dependencyCount;
807                 DE_NULL                                                                                                 // const VkSubpassDependency*           pDependencies;
808         };
809
810         return createRenderPass(vk, device, &renderPassInfo);
811 }
812
813 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&     vk,
814                                                                          const VkDevice                 device,
815                                                                          const VkRenderPass             renderPass,
816                                                                          const deUint32                 attachmentCount,
817                                                                          const VkImageView*             pAttachments,
818                                                                          const IVec2                    size)
819 {
820         const VkFramebufferCreateInfo framebufferInfo =
821         {
822                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
823                 DE_NULL,
824                 (VkFramebufferCreateFlags)0,
825                 renderPass,
826                 attachmentCount,
827                 pAttachments,
828                 static_cast<deUint32>(size.x()),
829                 static_cast<deUint32>(size.y()),
830                 1u,
831         };
832
833         return createFramebuffer(vk, device, &framebufferInfo);
834 }
835
836 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
837 {
838         return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
839 }
840
841 MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
842 {
843         MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
844         VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
845         return alloc;
846 }
847
848 MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
849 {
850         MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
851         VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
852         return alloc;
853 }
854
855 vector<Vec4> genVertexData (const CaseDef& caseDef)
856 {
857         vector<Vec4>    vectorData;
858         const bool              isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
859
860         for (deUint32 z = 0; z < caseDef.numLayers; z++)
861         {
862                 const deUint32  colorIdx        = z % COLOR_TABLE_SIZE;
863                 const Vec4              color           = isIntegerFormat ? COLOR_TABLE_INT[colorIdx].cast<float>() : COLOR_TABLE_FLOAT[colorIdx];
864
865                 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
866                 vectorData.push_back(color);
867                 vectorData.push_back(Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
868                 vectorData.push_back(color);
869                 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
870                 vectorData.push_back(color);
871                 vectorData.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
872                 vectorData.push_back(color);
873         }
874
875         return vectorData;
876 }
877
878 void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
879 {
880         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(image.getFormat().type);
881         const bool                                              isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
882         const IVec2                                             size                    = caseDef.size.swizzle(0, 1);
883
884         for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
885         {
886                 const deUint32  colorIdx        = z % COLOR_TABLE_SIZE;
887                 for (int y = 0; y < size.y(); y++)
888                 for (int x = 0; x < size.x(); x++)
889                 {
890                         if (isIntegerFormat)
891                                 image.setPixel(COLOR_TABLE_INT[colorIdx], x, y, z);
892                         else
893                                 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
894                 }
895         }
896 }
897
898 VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
899 {
900         VkImageUsageFlags flags = 0u;
901
902         switch (caseDef.upload)
903         {
904         case UPLOAD_CLEAR:
905                 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
906                 break;
907         case UPLOAD_DRAW:
908                 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
909                 break;
910         case UPLOAD_STORE:
911                 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
912                 break;
913         case UPLOAD_COPY:
914                 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
915                 break;
916         default:
917                 DE_ASSERT("Invalid upload method");
918                 break;
919         }
920
921         switch (caseDef.download)
922         {
923         case DOWNLOAD_TEXTURE:
924                 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
925                 break;
926         case DOWNLOAD_LOAD:
927                 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
928                 break;
929         case DOWNLOAD_COPY:
930                 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
931                 break;
932         default:
933                 DE_ASSERT("Invalid download method");
934                 break;
935         }
936
937         // We can only create a view for the image if it is going to be used for any of these usages,
938         // so let's make sure that we have at least one of them.
939         VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
940         if (!(flags & viewRequiredFlags))
941                 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
942
943         return flags;
944 }
945
946 // Executes a combination of upload/download methods
947 class UploadDownloadExecutor
948 {
949 public:
950         UploadDownloadExecutor(Context &context, const CaseDef& caseSpec) :
951         m_caseDef(caseSpec),
952         m_haveMaintenance2(de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2")),
953         m_vk(context.getDeviceInterface()),
954         m_device(context.getDevice()),
955         m_queue(context.getUniversalQueue()),
956         m_queueFamilyIndex(context.getUniversalQueueFamilyIndex()),
957         m_allocator(context.getDefaultAllocator())
958         {
959         }
960
961         void run(Context& context, VkBuffer buffer);
962
963 private:
964         void uploadClear(Context& context);
965         void uploadStore(Context& context);
966         void uploadCopy(Context& context);
967         void uploadDraw(Context& context);
968         void downloadCopy(Context& context, VkBuffer buffer);
969         void downloadTexture(Context& context, VkBuffer buffer);
970         void downloadLoad(Context& context, VkBuffer buffer);
971
972         void copyImageToBuffer(VkImage                          image,
973                                                    VkBuffer                             buffer,
974                                                    const IVec3                  size,
975                                                    const VkAccessFlags  srcAccessMask,
976                                                    const VkImageLayout  oldLayout,
977                                                    const deUint32               numLayers);
978
979         const CaseDef&                                          m_caseDef;
980
981         bool                                                            m_haveMaintenance2;
982
983         const DeviceInterface&                          m_vk;
984         const VkDevice                                          m_device;
985         const VkQueue                                           m_queue;
986         const deUint32                                          m_queueFamilyIndex;
987         Allocator&                                                      m_allocator;
988
989         Move<VkCommandPool>                                     m_cmdPool;
990         Move<VkCommandBuffer>                           m_cmdBuffer;
991
992         bool                                                            m_imageIsIntegerFormat;
993         bool                                                            m_viewIsIntegerFormat;
994
995         // Target image for upload paths
996         Move<VkImage>                                           m_image;
997         MovePtr<Allocation>                                     m_imageAlloc;
998
999         // Upload copy
1000         struct
1001         {
1002                 Move<VkBuffer>                                  colorBuffer;
1003                 VkDeviceSize                                    colorBufferSize;
1004                 MovePtr<Allocation>                             colorBufferAlloc;
1005         } m_uCopy;
1006
1007         // Upload draw
1008         struct
1009         {
1010                 Move<VkBuffer>                                  vertexBuffer;
1011                 MovePtr<Allocation>                             vertexBufferAlloc;
1012                 Move<VkPipelineLayout>                  pipelineLayout;
1013                 Move<VkRenderPass>                              renderPass;
1014                 Move<VkShaderModule>                    vertexModule;
1015                 Move<VkShaderModule>                    fragmentModule;
1016                 vector<SharedPtrVkImageView>    attachments;
1017                 vector<VkImageView>                             attachmentHandles;
1018                 vector<SharedPtrVkPipeline>             pipelines;
1019                 Move<VkFramebuffer>                             framebuffer;
1020         } m_uDraw;
1021
1022         // Upload store
1023         struct
1024         {
1025                 Move<VkDescriptorPool>                  descriptorPool;
1026                 Move<VkPipelineLayout>                  pipelineLayout;
1027                 Move<VkDescriptorSetLayout>             descriptorSetLayout;
1028                 Move<VkDescriptorSet>                   descriptorSet;
1029                 VkDescriptorImageInfo                   imageDescriptorInfo;
1030                 Move<VkShaderModule>                    computeModule;
1031                 Move<VkPipeline>                                computePipeline;
1032                 Move<VkImageView>                               imageView;
1033         } m_uStore;
1034
1035         // Download load
1036         struct
1037         {
1038                 Move<VkDescriptorPool>                  descriptorPool;
1039                 Move<VkPipelineLayout>                  pipelineLayout;
1040                 Move<VkDescriptorSetLayout>             descriptorSetLayout;
1041                 Move<VkDescriptorSet>                   descriptorSet;
1042                 Move<VkShaderModule>                    computeModule;
1043                 Move<VkPipeline>                                computePipeline;
1044                 Move<VkImageView>                               inImageView;
1045                 VkDescriptorImageInfo                   inImageDescriptorInfo;
1046                 Move<VkImage>                                   outImage;
1047                 Move<VkImageView>                               outImageView;
1048                 MovePtr<Allocation>                             outImageAlloc;
1049                 VkDescriptorImageInfo                   outImageDescriptorInfo;
1050         } m_dLoad;
1051
1052         // Download texture
1053         struct
1054         {
1055                 Move<VkDescriptorPool>                  descriptorPool;
1056                 Move<VkPipelineLayout>                  pipelineLayout;
1057                 Move<VkDescriptorSetLayout>             descriptorSetLayout;
1058                 Move<VkDescriptorSet>                   descriptorSet;
1059                 Move<VkShaderModule>                    computeModule;
1060                 Move<VkPipeline>                                computePipeline;
1061                 Move<VkImageView>                               inImageView;
1062                 VkDescriptorImageInfo                   inImageDescriptorInfo;
1063                 Move<VkSampler>                                 sampler;
1064                 Move<VkImage>                                   outImage;
1065                 Move<VkImageView>                               outImageView;
1066                 MovePtr<Allocation>                             outImageAlloc;
1067                 VkDescriptorImageInfo                   outImageDescriptorInfo;
1068         } m_dTex;
1069
1070         VkImageLayout                                           m_imageLayoutAfterUpload;
1071         VkAccessFlagBits                                        m_imageUploadAccessMask;
1072 };
1073
1074 void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
1075 {
1076         m_imageIsIntegerFormat  = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1077         m_viewIsIntegerFormat   = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1078
1079         m_cmdPool                               = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1080         m_cmdBuffer                             = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1081         beginCommandBuffer(m_vk, *m_cmdBuffer);
1082
1083         const VkImageUsageFlags         imageUsage      = getImageUsageForTestCase(m_caseDef);
1084         const VkImageCreateFlags        imageFlags      = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0);
1085         m_image                                                                 = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat,
1086                                                                                                                 m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
1087         m_imageAlloc                                                    = bindImage(m_vk, m_device, m_allocator, *m_image, MemoryRequirement::Any);
1088
1089         switch (m_caseDef.upload)
1090         {
1091         case UPLOAD_DRAW:
1092                 uploadDraw(context);
1093                 break;
1094         case UPLOAD_STORE:
1095                 uploadStore(context);
1096                 break;
1097         case UPLOAD_CLEAR:
1098                 uploadClear(context);
1099                 break;
1100         case UPLOAD_COPY:
1101                 uploadCopy(context);
1102                 break;
1103         default:
1104                 DE_ASSERT("Unsupported upload method");
1105         }
1106
1107         switch (m_caseDef.download)
1108         {
1109         case DOWNLOAD_COPY:
1110                 downloadCopy(context, buffer);
1111                 break;
1112         case DOWNLOAD_LOAD:
1113                 downloadLoad(context, buffer);
1114                 break;
1115         case DOWNLOAD_TEXTURE:
1116                 downloadTexture(context, buffer);
1117                 break;
1118         default:
1119                 DE_ASSERT("Unsupported download method");
1120         }
1121
1122         VK_CHECK(m_vk.endCommandBuffer(*m_cmdBuffer));
1123         submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1124 }
1125
1126 void UploadDownloadExecutor::uploadClear(Context& context)
1127 {
1128         (void) context;
1129
1130         VkImageLayout                                   requiredImageLayout     = VK_IMAGE_LAYOUT_GENERAL;
1131
1132         const VkImageSubresourceRange   subresourceRange        = makeColorSubresourceRange(0, m_caseDef.numLayers);
1133         const VkImageMemoryBarrier              imageInitBarrier        =
1134         {
1135                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
1136                 DE_NULL,                                                                                // const void*                          pNext;
1137                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
1138                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAcessMask;
1139                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
1140                 requiredImageLayout,                                                    // VkImageLayout                        newLayout;
1141                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
1142                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
1143                 *m_image,                                                                               // VkImage                                      image;
1144                 subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
1145         };
1146
1147         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1148                 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);
1149
1150         for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1151         {
1152                 const VkImageSubresourceRange   layerSubresourceRange   = makeColorSubresourceRange(layer, 1u);
1153                 const deUint32                                  colorIdx                                = layer % COLOR_TABLE_SIZE;
1154                 const VkClearColorValue                 clearColor                              = m_imageIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[colorIdx].color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
1155                 m_vk.cmdClearColorImage(*m_cmdBuffer, *m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
1156         }
1157
1158         m_imageLayoutAfterUpload        = requiredImageLayout;
1159         m_imageUploadAccessMask         = VK_ACCESS_TRANSFER_WRITE_BIT;
1160 }
1161
1162 void UploadDownloadExecutor::uploadStore(Context& context)
1163 {
1164         const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = {
1165                 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,     // VkStructureType              sType
1166                 DE_NULL,                                                                                        // const void*                  pNext
1167                 VK_IMAGE_USAGE_STORAGE_BIT,                                                     // VkImageUsageFlags    usage;
1168         };
1169         m_uStore.imageView                              = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1170                                                                                                         makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1171
1172         // Setup compute pipeline
1173         m_uStore.descriptorPool                 = DescriptorPoolBuilder()
1174                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1175                 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1176
1177         m_uStore.descriptorSetLayout    = DescriptorSetLayoutBuilder()
1178                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1179                 .build(m_vk, m_device);
1180
1181         m_uStore.pipelineLayout                 = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
1182         m_uStore.descriptorSet                  = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
1183         m_uStore.imageDescriptorInfo    = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
1184         m_uStore.computeModule                  = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
1185         m_uStore.computePipeline                = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL);
1186
1187         DescriptorSetUpdateBuilder()
1188                 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
1189                 .update(m_vk, m_device);
1190
1191         // Transition storage image for shader access (imageStore)
1192         VkImageLayout requiredImageLayout       = VK_IMAGE_LAYOUT_GENERAL;
1193         const VkImageMemoryBarrier imageBarrier =
1194         {
1195                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
1196                 DE_NULL,                                                                                        // const void*                          pNext;
1197                 (VkAccessFlags)0,                                                                       // VkAccessFlags                        srcAccessMask;
1198                 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT,                      // VkAccessFlags                        dstAccessMask;
1199                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
1200                 requiredImageLayout,                                                            // VkImageLayout                        newLayout;
1201                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
1202                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     destQueueFamilyIndex;
1203                 *m_image,                                                                                       // VkImage                                      image;
1204                 makeColorSubresourceRange(0, m_caseDef.numLayers),      // VkImageSubresourceRange      subresourceRange;
1205         };
1206
1207         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1208                 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1209
1210         // Dispatch
1211         m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
1212         m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
1213         m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1214
1215         m_imageLayoutAfterUpload        = requiredImageLayout;
1216         m_imageUploadAccessMask         = VK_ACCESS_SHADER_WRITE_BIT;
1217 }
1218
1219 void UploadDownloadExecutor::uploadCopy(Context& context)
1220 {
1221         (void) context;
1222
1223         // Create a host-mappable buffer with the color data to upload
1224         const VkDeviceSize      pixelSize                       = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
1225         const VkDeviceSize      layerSize                       = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;
1226
1227         m_uCopy.colorBufferSize                                 = layerSize * m_caseDef.numLayers;
1228         m_uCopy.colorBuffer                                             = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1229         m_uCopy.colorBufferAlloc                                = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);
1230
1231         // Fill color buffer
1232         const tcu::TextureFormat        tcuFormat       = mapVkFormat(m_caseDef.imageFormat);
1233         VkDeviceSize                            layerOffset = 0ull;
1234         for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1235         {
1236                 tcu::PixelBufferAccess  imageAccess     = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
1237                 const deUint32                  colorIdx        = layer % COLOR_TABLE_SIZE;
1238                 if (m_imageIsIntegerFormat)
1239                         tcu::clear(imageAccess, COLOR_TABLE_INT[colorIdx]);
1240                 else
1241                         tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
1242                 layerOffset += layerSize;
1243         }
1244
1245         flushMappedMemoryRange(m_vk, m_device, m_uCopy.colorBufferAlloc->getMemory(), m_uCopy.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1246
1247         // Prepare buffer and image for copy
1248         const VkBufferMemoryBarrier     bufferInitBarrier       =
1249         {
1250                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                        // VkStructureType    sType;
1251                 DE_NULL,                                                                                        // const void*        pNext;
1252                 VK_ACCESS_HOST_WRITE_BIT,                                                       // VkAccessFlags      srcAccessMask;
1253                 VK_ACCESS_TRANSFER_READ_BIT,                                            // VkAccessFlags      dstAccessMask;
1254                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32           srcQueueFamilyIndex;
1255                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32           dstQueueFamilyIndex;
1256                 *m_uCopy.colorBuffer,                                                           // VkBuffer           buffer;
1257                 0ull,                                                                                           // VkDeviceSize       offset;
1258                 VK_WHOLE_SIZE,                                                                          // VkDeviceSize       size;
1259         };
1260
1261         const VkImageMemoryBarrier      imageInitBarrier        =
1262         {
1263                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
1264                 DE_NULL,                                                                                        // const void*                          pNext;
1265                 0u,                                                                                                     // VkAccessFlags                        srcAccessMask;
1266                 VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                        dstAccessMask;
1267                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
1268                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                        newLayout;
1269                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
1270                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     destQueueFamilyIndex;
1271                 *m_image,                                                                                       // VkImage                                      image;
1272                 makeColorSubresourceRange(0, m_caseDef.numLayers)       // VkImageSubresourceRange      subresourceRange;
1273         };
1274
1275         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1276                 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);
1277
1278         // Copy buffer to image
1279         const VkImageSubresourceLayers  subresource     =
1280         {
1281                 VK_IMAGE_ASPECT_COLOR_BIT,                                                      // VkImageAspectFlags    aspectMask;
1282                 0u,                                                                                                     // deUint32              mipLevel;
1283                 0u,                                                                                                     // deUint32              baseArrayLayer;
1284                 m_caseDef.numLayers,                                                            // deUint32              layerCount;
1285         };
1286
1287         const VkBufferImageCopy                 region          =
1288         {
1289                 0ull,                                                                                           // VkDeviceSize                bufferOffset;
1290                 0u,                                                                                                     // deUint32                    bufferRowLength;
1291                 0u,                                                                                                     // deUint32                    bufferImageHeight;
1292                 subresource,                                                                            // VkImageSubresourceLayers    imageSubresource;
1293                 makeOffset3D(0, 0, 0),                                                          // VkOffset3D                  imageOffset;
1294                 makeExtent3D(m_caseDef.size),                                           // VkExtent3D                  imageExtent;
1295         };
1296
1297         m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &region);
1298
1299         const VkImageMemoryBarrier      imagePostInitBarrier    =
1300         {
1301                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
1302                 DE_NULL,                                                                                        // const void*                          pNext;
1303                 VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                        srcAccessMask;
1304                 VK_ACCESS_TRANSFER_READ_BIT,                                            // VkAccessFlags                        dstAccessMask;
1305                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                        oldLayout;
1306                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                        newLayout;
1307                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
1308                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     destQueueFamilyIndex;
1309                 *m_image,                                                                                       // VkImage                                      image;
1310                 makeColorSubresourceRange(0, m_caseDef.numLayers)       // VkImageSubresourceRange      subresourceRange;
1311         };
1312
1313         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1314                 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);
1315
1316         m_imageLayoutAfterUpload        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1317         m_imageUploadAccessMask         = VK_ACCESS_TRANSFER_WRITE_BIT;
1318 }
1319
1320 void UploadDownloadExecutor::uploadDraw(Context& context)
1321 {
1322         // Create vertex buffer
1323         {
1324                 const vector<Vec4>      vertices                                = genVertexData(m_caseDef);
1325                 const VkDeviceSize      vertexBufferSize                = vertices.size() * sizeof(Vec4);
1326
1327                 m_uDraw.vertexBuffer                                            = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1328                 m_uDraw.vertexBufferAlloc                                       = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
1329                 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
1330                 flushMappedMemoryRange(m_vk, m_device, m_uDraw.vertexBufferAlloc->getMemory(), m_uDraw.vertexBufferAlloc->getOffset(), vertexBufferSize);
1331         }
1332
1333         // Create attachments and pipelines for each image layer
1334         m_uDraw.pipelineLayout                                                  = makePipelineLayout(m_vk, m_device);
1335         m_uDraw.renderPass                                                              = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
1336         m_uDraw.vertexModule                                                    = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
1337         m_uDraw.fragmentModule                                                  = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);
1338
1339         for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1340         {
1341                 const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = {
1342                         VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,     // VkStructureType              sType
1343                         DE_NULL,                                                                                        // const void*                  pNext
1344                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,                            // VkImageUsageFlags    usage;
1345                 };
1346                 Move<VkImageView>       imageView       = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1347                                                                                                                 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1348                 m_uDraw.attachmentHandles.push_back(*imageView);
1349                 m_uDraw.attachments.push_back(makeSharedPtr(imageView));
1350                 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
1351                         m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
1352         }
1353
1354         // Create framebuffer
1355         m_uDraw.framebuffer     = makeFramebuffer(m_vk, m_device, *m_uDraw.renderPass, static_cast<deUint32>(m_uDraw.attachmentHandles.size()), &m_uDraw.attachmentHandles[0], m_caseDef.size.swizzle(0, 1));
1356
1357         // Create command buffer
1358         {
1359                 {
1360                         vector<VkClearValue>    clearValues             (m_caseDef.numLayers, m_viewIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[0] : REFERENCE_CLEAR_COLOR_FLOAT[0]);
1361
1362                         const VkRect2D                  renderArea      =
1363                         {
1364                                 makeOffset2D(0, 0),
1365                                 makeExtent2D(m_caseDef.size.x(), m_caseDef.size.y()),
1366                         };
1367
1368                         const VkRenderPassBeginInfo     renderPassBeginInfo     =
1369                         {
1370                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType         sType;
1371                                 DE_NULL,                                                                        // const void*             pNext;
1372                                 *m_uDraw.renderPass,                                                    // VkRenderPass            renderPass;
1373                                 *m_uDraw.framebuffer,                                                   // VkFramebuffer           framebuffer;
1374                                 renderArea,                                                                     // VkRect2D                renderArea;
1375                                 static_cast<deUint32>(clearValues.size()),      // deUint32                clearValueCount;
1376                                 &clearValues[0],                                                        // const VkClearValue*     pClearValues;
1377                         };
1378
1379                         m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1380                 }
1381
1382                 // Render
1383                 const VkDeviceSize      vertexDataPerDraw       = 4 * 2 * sizeof(Vec4);
1384                 VkDeviceSize            vertexBufferOffset      = 0ull;
1385                 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1386                 {
1387                         if (subpassNdx != 0)
1388                                 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1389
1390                         m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);
1391
1392                         m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
1393                         m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
1394                         vertexBufferOffset      += vertexDataPerDraw;
1395                 }
1396
1397                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
1398         }
1399
1400         m_imageLayoutAfterUpload        = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1401         m_imageUploadAccessMask         = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1402 }
1403
1404 void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
1405 {
1406         (void) context;
1407
1408         copyImageToBuffer(*m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
1409 }
1410
1411 void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
1412 {
1413         // Create output image with download result
1414         const VkImageUsageFlags usageFlags      = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1415         m_dTex.outImage                                         = makeImage(m_vk, m_device, 0u, VK_IMAGE_TYPE_2D, m_caseDef.viewFormat, m_caseDef.viewFormat, false, m_caseDef.size, 1u, m_caseDef.numLayers, usageFlags);
1416         m_dTex.outImageAlloc                            = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
1417         m_dTex.outImageView                                     = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1418
1419         const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = {
1420                 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,     // VkStructureType              sType
1421                 DE_NULL,                                                                                        // const void*                  pNext
1422                 VK_IMAGE_USAGE_SAMPLED_BIT,                                                     // VkImageUsageFlags    usage;
1423         };
1424         m_dTex.inImageView                                      = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1425                                                                                                                 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1426         m_dTex.sampler                                          = makeSampler(m_vk, m_device);
1427
1428         // Setup compute pipeline
1429         m_dTex.descriptorPool                           = DescriptorPoolBuilder()
1430                 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1431                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1432                 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1433
1434         m_dTex.descriptorSetLayout                      = DescriptorSetLayoutBuilder()
1435                 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get())
1436                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1437                 .build(m_vk, m_device);
1438
1439         m_dTex.pipelineLayout                           = makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout);
1440         m_dTex.descriptorSet                            = makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout);
1441         m_dTex.inImageDescriptorInfo            = makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1442         m_dTex.outImageDescriptorInfo           = makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1443         m_dTex.computeModule                            = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0);
1444         m_dTex.computePipeline                          = makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule, DE_NULL);
1445
1446         DescriptorSetUpdateBuilder()
1447                 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo)
1448                 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo)
1449                 .update(m_vk, m_device);
1450
1451         // Transition images for shader access (texture / imageStore)
1452         const VkImageMemoryBarrier imageBarriers[]      =
1453         {
1454                 {
1455                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
1456                         DE_NULL,                                                                                        // const void*                          pNext;
1457                         (VkAccessFlags)m_imageUploadAccessMask,                         // VkAccessFlags                        srcAccessMask;
1458                         (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,                       // VkAccessFlags                        dstAccessMask;
1459                         m_imageLayoutAfterUpload,                                                       // VkImageLayout                        oldLayout;
1460                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,                       // VkImageLayout                        newLayout;
1461                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
1462                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     destQueueFamilyIndex;
1463                         *m_image,                                                                                       // VkImage                                      image;
1464                         makeColorSubresourceRange(0, m_caseDef.numLayers),      // VkImageSubresourceRange      subresourceRange;
1465                 },
1466                 {
1467                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
1468                         DE_NULL,                                                                                        // const void*                          pNext;
1469                         (VkAccessFlags)0,                                                                       // VkAccessFlags                        srcAccessMask;
1470                         (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT,                      // VkAccessFlags                        dstAccessMask;
1471                         VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
1472                         VK_IMAGE_LAYOUT_GENERAL,                                                        // VkImageLayout                        newLayout;
1473                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
1474                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     destQueueFamilyIndex;
1475                         *m_dTex.outImage,                                                                       // VkImage                                      image;
1476                         makeColorSubresourceRange(0, m_caseDef.numLayers),      // VkImageSubresourceRange      subresourceRange;
1477                 }
1478         };
1479
1480         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1481                 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1482
1483         // Dispatch
1484         m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline);
1485         m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL);
1486         m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1487
1488         // Copy output image to color buffer
1489         copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers);
1490 }
1491
1492 void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer)
1493 {
1494         // Create output image with download result
1495         const VkImageUsageFlags usageFlags      = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1496         m_dLoad.outImage                                        = makeImage(m_vk, m_device, 0u, VK_IMAGE_TYPE_2D, m_caseDef.viewFormat, m_caseDef.viewFormat, false, m_caseDef.size, 1u, m_caseDef.numLayers, usageFlags);
1497         m_dLoad.outImageAlloc                           = bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any);
1498         m_dLoad.outImageView                            = makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1499
1500         const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = {
1501                 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,     // VkStructureType              sType
1502                 DE_NULL,                                                                                        // const void*                  pNext
1503                 VK_IMAGE_USAGE_STORAGE_BIT,                                                     // VkImageUsageFlags    usage;
1504         };
1505         m_dLoad.inImageView                                     = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1506                                                                                                                 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1507
1508         // Setup compute pipeline
1509         m_dLoad.descriptorPool                          = DescriptorPoolBuilder()
1510                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
1511                 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1512
1513         m_dLoad.descriptorSetLayout                     = DescriptorSetLayoutBuilder()
1514                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1515                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1516                 .build(m_vk, m_device);
1517
1518         m_dLoad.pipelineLayout                          = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
1519         m_dLoad.descriptorSet                           = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
1520         m_dLoad.inImageDescriptorInfo           = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
1521         m_dLoad.outImageDescriptorInfo          = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1522         m_dLoad.computeModule                           = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
1523         m_dLoad.computePipeline                         = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL);
1524
1525         DescriptorSetUpdateBuilder()
1526                 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
1527                 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
1528                 .update(m_vk, m_device);
1529
1530         // Transition storage images for shader access (imageLoad/Store)
1531         VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1532         const VkImageMemoryBarrier imageBarriers[]      =
1533         {
1534                 {
1535                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
1536                         DE_NULL,                                                                                        // const void*                          pNext;
1537                         (VkAccessFlags)m_imageUploadAccessMask,                         // VkAccessFlags                        srcAccessMask;
1538                         (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,                       // VkAccessFlags                        dstAccessMask;
1539                         m_imageLayoutAfterUpload,                                                       // VkImageLayout                        oldLayout;
1540                         requiredImageLayout,                                                            // VkImageLayout                        newLayout;
1541                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
1542                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     destQueueFamilyIndex;
1543                         *m_image,                                                                                       // VkImage                                      image;
1544                         makeColorSubresourceRange(0, m_caseDef.numLayers),      // VkImageSubresourceRange      subresourceRange;
1545                 },
1546                 {
1547                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
1548                         DE_NULL,                                                                                        // const void*                          pNext;
1549                         (VkAccessFlags)0,                                                                       // VkAccessFlags                        srcAccessMask;
1550                         (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT,                      // VkAccessFlags                        dstAccessMask;
1551                         VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
1552                         requiredImageLayout,                                                            // VkImageLayout                        newLayout;
1553                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
1554                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     destQueueFamilyIndex;
1555                         *m_dLoad.outImage,                                                                      // VkImage                                      image;
1556                         makeColorSubresourceRange(0, m_caseDef.numLayers),      // VkImageSubresourceRange      subresourceRange;
1557                 }
1558         };
1559
1560         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1561                 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1562
1563         // Dispatch
1564         m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
1565         m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
1566         m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1567
1568         // Copy output image to color buffer
1569         copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
1570 }
1571
1572 void UploadDownloadExecutor::copyImageToBuffer(VkImage                          sourceImage,
1573                                                                                            VkBuffer                             buffer,
1574                                                                                            const IVec3                  size,
1575                                                                                            const VkAccessFlags  srcAccessMask,
1576                                                                                            const VkImageLayout  oldLayout,
1577                                                                                            const deUint32               numLayers)
1578 {
1579         // Copy result to host visible buffer for inspection
1580         const VkImageMemoryBarrier      imageBarrier    =
1581         {
1582                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1583                 DE_NULL,                                                                        // const void*                          pNext;
1584                 srcAccessMask,                                                          // VkAccessFlags                        srcAccessMask;
1585                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1586                 oldLayout,                                                                      // VkImageLayout                        oldLayout;
1587                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1588                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1589                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     destQueueFamilyIndex;
1590                 sourceImage,                                                            // VkImage                                      image;
1591                 makeColorSubresourceRange(0, numLayers)         // VkImageSubresourceRange      subresourceRange;
1592         };
1593
1594         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1595                 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1596
1597         const VkImageSubresourceLayers  subresource     =
1598         {
1599                 VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags    aspectMask;
1600                 0u,                                                                                     // deUint32              mipLevel;
1601                 0u,                                                                                     // deUint32              baseArrayLayer;
1602                 numLayers,                                                                      // deUint32              layerCount;
1603         };
1604
1605         const VkBufferImageCopy                 region          =
1606         {
1607                 0ull,                                                                           // VkDeviceSize                bufferOffset;
1608                 0u,                                                                                     // deUint32                    bufferRowLength;
1609                 0u,                                                                                     // deUint32                    bufferImageHeight;
1610                 subresource,                                                            // VkImageSubresourceLayers    imageSubresource;
1611                 makeOffset3D(0, 0, 0),                                          // VkOffset3D                  imageOffset;
1612                 makeExtent3D(size),                                                     // VkExtent3D                  imageExtent;
1613         };
1614
1615         m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, &region);
1616
1617         const VkBufferMemoryBarrier     bufferBarrier =
1618         {
1619                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType    sType;
1620                 DE_NULL,                                                                        // const void*        pNext;
1621                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags      srcAccessMask;
1622                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags      dstAccessMask;
1623                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32           srcQueueFamilyIndex;
1624                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32           dstQueueFamilyIndex;
1625                 buffer,                                                                         // VkBuffer           buffer;
1626                 0ull,                                                                           // VkDeviceSize       offset;
1627                 VK_WHOLE_SIZE,                                                          // VkDeviceSize       size;
1628         };
1629
1630         m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1631                 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
1632 }
1633
1634 bool isStorageImageExtendedFormat (const VkFormat format)
1635 {
1636         switch (format)
1637         {
1638                 case VK_FORMAT_R32G32_SFLOAT:
1639                 case VK_FORMAT_R32G32_SINT:
1640                 case VK_FORMAT_R32G32_UINT:
1641                 case VK_FORMAT_R16G16B16A16_UNORM:
1642                 case VK_FORMAT_R16G16B16A16_SNORM:
1643                 case VK_FORMAT_R16G16_SFLOAT:
1644                 case VK_FORMAT_R16G16_UNORM:
1645                 case VK_FORMAT_R16G16_SNORM:
1646                 case VK_FORMAT_R16G16_SINT:
1647                 case VK_FORMAT_R16G16_UINT:
1648                 case VK_FORMAT_R16_SFLOAT:
1649                 case VK_FORMAT_R16_UNORM:
1650                 case VK_FORMAT_R16_SNORM:
1651                 case VK_FORMAT_R16_SINT:
1652                 case VK_FORMAT_R16_UINT:
1653                 case VK_FORMAT_R8G8_UNORM:
1654                 case VK_FORMAT_R8G8_SNORM:
1655                 case VK_FORMAT_R8G8_SINT:
1656                 case VK_FORMAT_R8G8_UINT:
1657                 case VK_FORMAT_R8_UNORM:
1658                 case VK_FORMAT_R8_SNORM:
1659                 case VK_FORMAT_R8_SINT:
1660                 case VK_FORMAT_R8_UINT:
1661                         return true;
1662
1663                 default:
1664                         return false;
1665         }
1666 }
1667
1668 tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
1669 {
1670         const DeviceInterface&                  vk                      = context.getDeviceInterface();
1671         const InstanceInterface&                vki                     = context.getInstanceInterface();
1672         const VkDevice                                  device          = context.getDevice();
1673         const VkPhysicalDevice                  physDevice      = context.getPhysicalDevice();
1674         Allocator&                                              allocator       = context.getDefaultAllocator();
1675
1676         // If this is a VK_KHR_image_format_list test, check that the extension is supported
1677         if (caseDef.isFormatListTest && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_image_format_list"))
1678                 TCU_THROW(NotSupportedError, "VK_KHR_image_format_list not supported");
1679
1680         // Check required features on the format for the required upload/download methods
1681         VkFormatProperties      imageFormatProps, viewFormatProps;
1682         vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
1683         vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
1684
1685         VkFormatFeatureFlags    viewFormatFeatureFlags = 0u;
1686         switch (caseDef.upload)
1687         {
1688         case UPLOAD_DRAW:
1689                 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1690                 break;
1691         case UPLOAD_STORE:
1692                 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1693                 break;
1694         default:
1695                 DE_ASSERT("Invalid upload method");
1696                 break;
1697         }
1698         switch (caseDef.download)
1699         {
1700         case DOWNLOAD_TEXTURE:
1701                 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1702                 // For the texture case we write the samples read to a separate output image with the same view format
1703                 // so we need to check that we can also use the view format for storage
1704                 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1705                 break;
1706         case DOWNLOAD_LOAD:
1707                 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1708                 break;
1709         default:
1710                 DE_ASSERT("Invalid download method");
1711                 break;
1712         }
1713
1714         if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
1715                 isStorageImageExtendedFormat(caseDef.viewFormat) &&
1716                 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
1717         {
1718                 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
1719         }
1720
1721         if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
1722                 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
1723
1724         // We don't use the base image for anything other than transfer
1725         // operations so there are no features to check.  However, The Vulkan
1726         // 1.0 spec does not allow us to create an image view with usage that
1727         // is not supported by the main format.  With VK_KHR_maintenance2, we
1728         // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
1729         if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
1730             !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2"))
1731         {
1732                 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
1733         }
1734
1735         // Create a color buffer for host-inspection of results
1736         // For the Copy download method, this is the target of the download, for other
1737         // download methods, pixel data will be copied to this buffer from the download
1738         // target
1739         const VkDeviceSize                      colorBufferSize         = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
1740         const Unique<VkBuffer>          colorBuffer                     (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1741         const UniquePtr<Allocation>     colorBufferAlloc        (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1742         deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
1743         flushMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1744
1745         // Execute the test
1746         UploadDownloadExecutor executor(context, caseDef);
1747         executor.run(context, *colorBuffer);
1748
1749         // Verify results
1750         {
1751                 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1752
1753                 // For verification purposes, we use the format of the upload to generate the expected image
1754                 const VkFormat                                          format                  = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
1755                 const tcu::TextureFormat                        tcuFormat               = mapVkFormat(format);
1756                 const bool                                                      isIntegerFormat = isUintFormat(format) || isIntFormat(format);
1757                 const tcu::ConstPixelBufferAccess       resultImage             (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
1758                 tcu::TextureLevel                                       textureLevel    (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
1759                 const tcu::PixelBufferAccess            expectedImage   = textureLevel.getAccess();
1760                 generateExpectedImage(expectedImage, caseDef);
1761
1762                 bool ok;
1763                 if (isIntegerFormat)
1764                         ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1765                 else
1766                         ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1767                 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
1768         }
1769 }
1770
1771 tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
1772 {
1773         de::MovePtr<TestCaseGroup> testGroup    (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
1774         for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
1775         {
1776                 const Texture&                                  texture                                 = s_textures[textureNdx];
1777                 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType    (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
1778
1779                 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
1780                 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
1781                 {
1782                         if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
1783                         {
1784                                 for (int upload = 0; upload < UPLOAD_LAST; upload++)
1785                                 for (int download = 0; download < DOWNLOAD_LAST; download++)
1786                                 {
1787                                         CaseDef caseDef =
1788                                         {
1789                                                 texture.type(),
1790                                                 texture.layerSize(),
1791                                                 static_cast<deUint32>(texture.numLayers()),
1792                                                 s_formats[imageFormatNdx],
1793                                                 s_formats[viewFormatNdx],
1794                                                 static_cast<enum Upload>(upload),
1795                                                 static_cast<enum Download>(download),
1796                                                 false
1797                                         };
1798
1799                                         std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
1800                                                 "_" + getUploadString(upload) + "_" + getDownloadString(download);
1801                                         addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1802
1803                                         caseDef.isFormatListTest = true;
1804                                         caseName += "_format_list";
1805                                         addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1806                                 }
1807                         }
1808                 }
1809
1810                 testGroup->addChild(groupByImageViewType.release());
1811         }
1812
1813         return testGroup.release();
1814 }
1815
1816 } // image
1817 } // vkt