dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineImageSamplingInstance.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Image sampling case
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktPipelineImageSamplingInstance.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "vktPipelineReferenceRenderer.hpp"
39 #include "vkBuilderUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkPrograms.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkRefUtil.hpp"
44 #include "tcuImageCompare.hpp"
45
46 namespace vkt
47 {
48 namespace pipeline
49 {
50
51 using namespace vk;
52 using de::MovePtr;
53
54 namespace
55 {
56
57 static VkImageType getCompatibleImageType (VkImageViewType viewType)
58 {
59         switch (viewType)
60         {
61                 case VK_IMAGE_VIEW_TYPE_1D:                             return VK_IMAGE_TYPE_1D;
62                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:               return VK_IMAGE_TYPE_1D;
63                 case VK_IMAGE_VIEW_TYPE_2D:                             return VK_IMAGE_TYPE_2D;
64                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:               return VK_IMAGE_TYPE_2D;
65                 case VK_IMAGE_VIEW_TYPE_3D:                             return VK_IMAGE_TYPE_3D;
66                 case VK_IMAGE_VIEW_TYPE_CUBE:                   return VK_IMAGE_TYPE_2D;
67                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:             return VK_IMAGE_TYPE_2D;
68                 default:
69                         break;
70         }
71
72         DE_ASSERT(false);
73         return VK_IMAGE_TYPE_1D;
74 }
75
76 template<typename TcuFormatType>
77 static MovePtr<TestTexture> createTestTexture (const TcuFormatType format, VkImageViewType viewType, const tcu::IVec3& size, int layerCount)
78 {
79         MovePtr<TestTexture>    texture;
80         const VkImageType               imageType = getCompatibleImageType(viewType);
81
82         switch (imageType)
83         {
84                 case VK_IMAGE_TYPE_1D:
85                         if (layerCount == 1)
86                                 texture = MovePtr<TestTexture>(new TestTexture1D(format, size.x()));
87                         else
88                                 texture = MovePtr<TestTexture>(new TestTexture1DArray(format, size.x(), layerCount));
89
90                         break;
91
92                 case VK_IMAGE_TYPE_2D:
93                         if (layerCount == 1)
94                         {
95                                 texture = MovePtr<TestTexture>(new TestTexture2D(format, size.x(), size.y()));
96                         }
97                         else
98                         {
99                                 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
100                                 {
101                                         if (layerCount == tcu::CUBEFACE_LAST)
102                                         {
103                                                 texture = MovePtr<TestTexture>(new TestTextureCube(format, size.x()));
104                                         }
105                                         else
106                                         {
107                                                 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
108
109                                                 texture = MovePtr<TestTexture>(new TestTextureCubeArray(format, size.x(), layerCount));
110                                         }
111                                 }
112                                 else
113                                 {
114                                         texture = MovePtr<TestTexture>(new TestTexture2DArray(format, size.x(), size.y(), layerCount));
115                                 }
116                         }
117
118                         break;
119
120                 case VK_IMAGE_TYPE_3D:
121                         texture = MovePtr<TestTexture>(new TestTexture3D(format, size.x(), size.y(), size.z()));
122                         break;
123
124                 default:
125                         DE_ASSERT(false);
126         }
127
128         return texture;
129 }
130
131 template<typename TcuTextureType>
132 static void copySubresourceRange (TcuTextureType& dest, const TcuTextureType& src, const VkImageSubresourceRange& subresourceRange)
133 {
134         DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
135         DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
136
137         for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
138         {
139                 const tcu::ConstPixelBufferAccess       srcLevel                (src.getLevel(subresourceRange.baseMipLevel + levelNdx));
140                 const deUint32                                          srcLayerOffset  = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getHeight() * srcLevel.getFormat().getPixelSize();
141                 const tcu::ConstPixelBufferAccess       srcLevelLayers  (srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), subresourceRange.layerCount, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset);
142
143                 if (dest.isLevelEmpty(levelNdx))
144                         dest.allocLevel(levelNdx);
145
146                 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
147         }
148 }
149
150 template<>
151 void copySubresourceRange<tcu::Texture1DArray> (tcu::Texture1DArray& dest, const tcu::Texture1DArray& src, const VkImageSubresourceRange& subresourceRange)
152 {
153         DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
154         DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
155
156         DE_ASSERT(subresourceRange.layerCount == (deUint32)dest.getNumLayers());
157         DE_ASSERT(subresourceRange.baseArrayLayer + subresourceRange.layerCount <= (deUint32)src.getNumLayers());
158
159         for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
160         {
161                 const tcu::ConstPixelBufferAccess       srcLevel                (src.getLevel(subresourceRange.baseMipLevel + levelNdx));
162                 const deUint32                                          srcLayerOffset  = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getFormat().getPixelSize();
163                 const tcu::ConstPixelBufferAccess       srcLevelLayers  (srcLevel.getFormat(), srcLevel.getWidth(), subresourceRange.layerCount, 1, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset);
164
165                 if (dest.isLevelEmpty(levelNdx))
166                         dest.allocLevel(levelNdx);
167
168                 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
169         }
170 }
171
172 template<>
173 void copySubresourceRange<tcu::Texture3D>(tcu::Texture3D& dest, const tcu::Texture3D& src, const VkImageSubresourceRange& subresourceRange)
174 {
175         DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
176         DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
177
178         for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
179         {
180                 const tcu::ConstPixelBufferAccess       srcLevel(src.getLevel(subresourceRange.baseMipLevel + levelNdx));
181                 const tcu::ConstPixelBufferAccess       srcLevelLayers(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), (deUint8*)srcLevel.getDataPtr());
182
183                 if (dest.isLevelEmpty(levelNdx))
184                         dest.allocLevel(levelNdx);
185
186                 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
187         }
188 }
189
190 static MovePtr<Program> createRefProgram(const tcu::TextureFormat&                      renderTargetFormat,
191                                                                                   const tcu::Sampler&                           sampler,
192                                                                                   float                                                         samplerLod,
193                                                                                   const tcu::UVec4&                                     componentMapping,
194                                                                                   const TestTexture&                            testTexture,
195                                                                                   VkImageViewType                                       viewType,
196                                                                                   int                                                           layerCount,
197                                                                                   const VkImageSubresourceRange&        subresource)
198 {
199         MovePtr<Program>        program;
200         const VkImageType       imageType       = getCompatibleImageType(viewType);
201
202         switch (imageType)
203         {
204                 case VK_IMAGE_TYPE_1D:
205                         if (layerCount == 1)
206                         {
207                                 const tcu::Texture1D& texture = dynamic_cast<const TestTexture1D&>(testTexture).getTexture();
208                                 program = MovePtr<Program>(new SamplerProgram<tcu::Texture1D>(renderTargetFormat, texture, sampler, samplerLod, componentMapping));
209                         }
210                         else
211                         {
212                                 const tcu::Texture1DArray& texture = dynamic_cast<const TestTexture1DArray&>(testTexture).getTexture();
213
214                                 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers())
215                                 {
216                                         // Not all texture levels and layers are needed. Create new sub-texture.
217                                         const tcu::ConstPixelBufferAccess       baseLevel       = texture.getLevel(subresource.baseMipLevel);
218                                         tcu::Texture1DArray                                     textureView     (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount);
219
220                                         copySubresourceRange(textureView, texture, subresource);
221
222                                         program = MovePtr<Program>(new SamplerProgram<tcu::Texture1DArray>(renderTargetFormat, textureView, sampler, samplerLod, componentMapping));
223                                 }
224                                 else
225                                 {
226                                         program = MovePtr<Program>(new SamplerProgram<tcu::Texture1DArray>(renderTargetFormat, texture, sampler, samplerLod, componentMapping));
227                                 }
228                         }
229                         break;
230
231                 case VK_IMAGE_TYPE_2D:
232                         if (layerCount == 1)
233                         {
234                                 const tcu::Texture2D& texture = dynamic_cast<const TestTexture2D&>(testTexture).getTexture();
235                                 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2D>(renderTargetFormat, texture, sampler, samplerLod, componentMapping));
236                         }
237                         else
238                         {
239                                 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
240                                 {
241                                         if (layerCount == tcu::CUBEFACE_LAST)
242                                         {
243                                                 const tcu::TextureCube& texture = dynamic_cast<const TestTextureCube&>(testTexture).getTexture();
244                                                 program = MovePtr<Program>(new SamplerProgram<tcu::TextureCube>(renderTargetFormat, texture, sampler, samplerLod, componentMapping));
245                                         }
246                                         else
247                                         {
248                                                 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
249
250                                                 const tcu::TextureCubeArray& texture = dynamic_cast<const TestTextureCubeArray&>(testTexture).getTexture();
251
252                                                 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getDepth())
253                                                 {
254                                                         DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getDepth());
255
256                                                         // Not all texture levels and layers are needed. Create new sub-texture.
257                                                         const tcu::ConstPixelBufferAccess       baseLevel               = texture.getLevel(subresource.baseMipLevel);
258                                                         tcu::TextureCubeArray                           textureView             (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount);
259
260                                                         copySubresourceRange(textureView, texture, subresource);
261
262                                                         program = MovePtr<Program>(new SamplerProgram<tcu::TextureCubeArray>(renderTargetFormat, textureView, sampler, samplerLod, componentMapping));
263                                                 }
264                                                 else
265                                                 {
266                                                         // Use all array layers
267                                                         program = MovePtr<Program>(new SamplerProgram<tcu::TextureCubeArray>(renderTargetFormat, texture, sampler, samplerLod, componentMapping));
268                                                 }
269                                         }
270                                 }
271                                 else
272                                 {
273                                         const tcu::Texture2DArray& texture = dynamic_cast<const TestTexture2DArray&>(testTexture).getTexture();
274
275                                         if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers())
276                                         {
277                                                 DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getNumLayers());
278
279                                                 // Not all texture levels and layers are needed. Create new sub-texture.
280                                                 const tcu::ConstPixelBufferAccess       baseLevel       = texture.getLevel(subresource.baseMipLevel);
281                                                 tcu::Texture2DArray                                     textureView     (texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), subresource.layerCount);
282
283                                                 copySubresourceRange(textureView, texture, subresource);
284
285                                                 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2DArray>(renderTargetFormat, textureView, sampler, samplerLod, componentMapping));
286                                         }
287                                         else
288                                         {
289                                                 // Use all array layers
290                                                 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2DArray>(renderTargetFormat, texture, sampler, samplerLod, componentMapping));
291                                         }
292                                 }
293                         }
294                         break;
295
296                 case VK_IMAGE_TYPE_3D:
297                         {
298                                 const tcu::Texture3D& texture = dynamic_cast<const TestTexture3D&>(testTexture).getTexture();
299
300                                 if (subresource.baseMipLevel > 0)
301                                 {
302                                         // Not all texture levels are needed. Create new sub-texture.
303                                         const tcu::ConstPixelBufferAccess       baseLevel = texture.getLevel(subresource.baseMipLevel);
304                                         tcu::Texture3D                                          textureView(texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), baseLevel.getDepth());
305
306                                         copySubresourceRange(textureView, texture, subresource);
307
308                                         program = MovePtr<Program>(new SamplerProgram<tcu::Texture3D>(renderTargetFormat, textureView, sampler, samplerLod, componentMapping));
309                                 }
310                                 else
311                                 {
312                                         program = MovePtr<Program>(new SamplerProgram<tcu::Texture3D>(renderTargetFormat, texture, sampler, samplerLod, componentMapping));
313                                 }
314                         }
315                         break;
316
317                 default:
318                         DE_ASSERT(false);
319         }
320
321         return program;
322 }
323
324 } // anonymous
325
326 ImageSamplingInstance::ImageSamplingInstance (Context&                                                  context,
327                                                                                           const tcu::IVec2&                                     renderSize,
328                                                                                           VkImageViewType                                       imageViewType,
329                                                                                           VkFormat                                                      imageFormat,
330                                                                                           const tcu::IVec3&                                     imageSize,
331                                                                                           int                                                           layerCount,
332                                                                                           const VkComponentMapping&                     componentMapping,
333                                                                                           const VkImageSubresourceRange&        subresourceRange,
334                                                                                           const VkSamplerCreateInfo&            samplerParams,
335                                                                                           float                                                         samplerLod,
336                                                                                           const std::vector<Vertex4Tex4>&       vertices)
337         : vkt::TestInstance             (context)
338         , m_imageViewType               (imageViewType)
339         , m_imageSize                   (imageSize)
340         , m_layerCount                  (layerCount)
341         , m_componentMapping    (componentMapping)
342         , m_subresourceRange    (subresourceRange)
343         , m_samplerParams               (samplerParams)
344         , m_samplerLod                  (samplerLod)
345         , m_renderSize                  (renderSize)
346         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
347         , m_vertices                    (vertices)
348 {
349         const DeviceInterface&          vk                                              = context.getDeviceInterface();
350         const VkDevice                          vkDevice                                = context.getDevice();
351         const VkQueue                           queue                                   = context.getUniversalQueue();
352         const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
353         SimpleAllocator                         memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
354         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
355
356         if (!isSupportedSamplableFormat(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat))
357                 throw tcu::NotSupportedError(std::string("Unsupported format for sampling: ") + getFormatName(imageFormat));
358
359         // Create texture image, view and sampler
360         {
361                 VkImageCreateFlags                      imageFlags                      = 0u;
362
363                 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
364                         imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
365
366                 // Initialize texture data
367                 if (isCompressedFormat(imageFormat))
368                         m_texture = createTestTexture(mapVkCompressedFormat(imageFormat), imageViewType, imageSize, layerCount);
369                 else
370                         m_texture = createTestTexture(mapVkFormat(imageFormat), imageViewType, imageSize, layerCount);
371
372                 const VkImageCreateInfo imageParams =
373                 {
374                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // VkStructureType                      sType;
375                         DE_NULL,                                                                                                                // const void*                          pNext;
376                         imageFlags,                                                                                                             // VkImageCreateFlags           flags;
377                         getCompatibleImageType(m_imageViewType),                                                // VkImageType                          imageType;
378                         imageFormat,                                                                                                    // VkFormat                                     format;
379                         {                                                                                                                               // VkExtent3D                           extent;
380                                 m_imageSize.x(),
381                                 m_imageSize.y(),
382                                 m_imageSize.z()
383                         },
384                         (deUint32)m_texture->getNumLevels(),                                                    // deUint32                                     mipLevels;
385                         (deUint32)m_layerCount,                                                                                 // deUint32                                     arrayLayers;
386                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits        samples;
387                         VK_IMAGE_TILING_OPTIMAL,                                                                                // VkImageTiling                        tiling;
388                         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,   // VkImageUsageFlags            usage;
389                         VK_SHARING_MODE_EXCLUSIVE,                                                                              // VkSharingMode                        sharingMode;
390                         1u,                                                                                                                             // deUint32                                     queueFamilyIndexCount;
391                         &queueFamilyIndex,                                                                                              // const deUint32*                      pQueueFamilyIndices;
392                         VK_IMAGE_LAYOUT_UNDEFINED                                                                               // VkImageLayout                        initialLayout;
393                 };
394
395                 m_image                 = createImage(vk, vkDevice, &imageParams);
396                 m_imageAlloc    = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_image), MemoryRequirement::Any);
397                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_image, m_imageAlloc->getMemory(), m_imageAlloc->getOffset()));
398
399                 // Upload texture data
400                 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, *m_image);
401
402                 // Create image view and sampler
403                 const VkImageViewCreateInfo imageViewParams =
404                 {
405                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
406                         DE_NULL,                                                                        // const void*                          pNext;
407                         0u,                                                                                     // VkImageViewCreateFlags       flags;
408                         *m_image,                                                                       // VkImage                                      image;
409                         m_imageViewType,                                                        // VkImageViewType                      viewType;
410                         imageFormat,                                                            // VkFormat                                     format;
411                         m_componentMapping,                                                     // VkComponentMapping           components;
412                         m_subresourceRange,                                                     // VkImageSubresourceRange      subresourceRange;
413                 };
414
415                 m_imageView     = createImageView(vk, vkDevice, &imageViewParams);
416                 m_sampler       = createSampler(vk, vkDevice, &m_samplerParams);
417         }
418
419         // Create descriptor set for combined image and sampler
420         {
421                 DescriptorPoolBuilder descriptorPoolBuilder;
422                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u);
423                 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
424
425                 DescriptorSetLayoutBuilder setLayoutBuilder;
426                 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
427                 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
428
429                 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
430                 {
431                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
432                         DE_NULL,                                                                                        // const void*                                  pNext;
433                         *m_descriptorPool,                                                                      // VkDescriptorPool                             descriptorPool;
434                         1u,                                                                                                     // deUint32                                             setLayoutCount;
435                         &m_descriptorSetLayout.get()                                            // const VkDescriptorSetLayout* pSetLayouts;
436                 };
437
438                 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
439
440                 const VkDescriptorImageInfo descriptorImageInfo =
441                 {
442                         *m_sampler,                                                                     // VkSampler            sampler;
443                         *m_imageView,                                                           // VkImageView          imageView;
444                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        imageLayout;
445                 };
446
447                 DescriptorSetUpdateBuilder setUpdateBuilder;
448                 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo);
449                 setUpdateBuilder.update(vk, vkDevice);
450         }
451
452         // Create color image and view
453         {
454                 const VkImageCreateInfo colorImageParams =
455                 {
456                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
457                         DE_NULL,                                                                                                                                        // const void*                          pNext;
458                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
459                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
460                         m_colorFormat,                                                                                                                          // VkFormat                                     format;
461                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                           extent;
462                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
463                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
464                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
465                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
466                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
467                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
468                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
469                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
470                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
471                 };
472
473                 m_colorImage                    = createImage(vk, vkDevice, &colorImageParams);
474                 m_colorImageAlloc               = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
475                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
476
477                 const VkImageViewCreateInfo colorAttachmentViewParams =
478                 {
479                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
480                         DE_NULL,                                                                                        // const void*                          pNext;
481                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
482                         *m_colorImage,                                                                          // VkImage                                      image;
483                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
484                         m_colorFormat,                                                                          // VkFormat                                     format;
485                         componentMappingRGBA,                                                           // VkComponentMapping           components;
486                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }           // VkImageSubresourceRange      subresourceRange;
487                 };
488
489                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
490         }
491
492         // Create render pass
493         {
494                 const VkAttachmentDescription colorAttachmentDescription =
495                 {
496                         0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
497                         m_colorFormat,                                                                          // VkFormat                                                     format;
498                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
499                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
500                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
501                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
502                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
503                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
504                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
505                 };
506
507                 const VkAttachmentReference colorAttachmentReference =
508                 {
509                         0u,                                                                                                     // deUint32                     attachment;
510                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
511                 };
512
513                 const VkSubpassDescription subpassDescription =
514                 {
515                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
516                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
517                         0u,                                                                                                     // deUint32                                             inputAttachmentCount;
518                         DE_NULL,                                                                                        // const VkAttachmentReference* pInputAttachments;
519                         1u,                                                                                                     // deUint32                                             colorAttachmentCount;
520                         &colorAttachmentReference,                                                      // const VkAttachmentReference* pColorAttachments;
521                         DE_NULL,                                                                                        // const VkAttachmentReference* pResolveAttachments;
522                         DE_NULL,                                                                                        // const VkAttachmentReference* pDepthStencilAttachment;
523                         0u,                                                                                                     // deUint32                                             preserveAttachmentCount;
524                         DE_NULL                                                                                         // const VkAttachmentReference* pPreserveAttachments;
525                 };
526
527                 const VkRenderPassCreateInfo renderPassParams =
528                 {
529                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
530                         DE_NULL,                                                                                        // const void*                                          pNext;
531                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
532                         1u,                                                                                                     // deUint32                                                     attachmentCount;
533                         &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
534                         1u,                                                                                                     // deUint32                                                     subpassCount;
535                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
536                         0u,                                                                                                     // deUint32                                                     dependencyCount;
537                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
538                 };
539
540                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
541         }
542
543         // Create framebuffer
544         {
545                 const VkFramebufferCreateInfo framebufferParams =
546                 {
547                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                      sType;
548                         DE_NULL,                                                                                        // const void*                          pNext;
549                         0u,                                                                                                     // VkFramebufferCreateFlags     flags;
550                         *m_renderPass,                                                                          // VkRenderPass                         renderPass;
551                         1u,                                                                                                     // deUint32                                     attachmentCount;
552                         &m_colorAttachmentView.get(),                                           // const VkImageView*           pAttachments;
553                         (deUint32)m_renderSize.x(),                                                     // deUint32                                     width;
554                         (deUint32)m_renderSize.y(),                                                     // deUint32                                     height;
555                         1u                                                                                                      // deUint32                                     layers;
556                 };
557
558                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
559         }
560
561         // Create pipeline layout
562         {
563                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
564                 {
565                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
566                         DE_NULL,                                                                                        // const void*                                  pNext;
567                         0u,                                                                                                     // VkPipelineLayoutCreateFlags  flags;
568                         1u,                                                                                                     // deUint32                                             setLayoutCount;
569                         &m_descriptorSetLayout.get(),                                           // const VkDescriptorSetLayout* pSetLayouts;
570                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
571                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
572                 };
573
574                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
575         }
576
577         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
578         m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
579
580         // Create pipeline
581         {
582                 const VkPipelineShaderStageCreateInfo shaderStages[2] =
583                 {
584                         {
585                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
586                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
587                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
588                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
589                                 *m_vertexShaderModule,                                                                          // VkShaderModule                                               module;
590                                 "main",                                                                                                         // const char*                                                  pName;
591                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
592                         },
593                         {
594                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
595                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
596                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
597                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
598                                 *m_fragmentShaderModule,                                                                        // VkShaderModule                                               module;
599                                 "main",                                                                                                         // const char*                                                  pName;
600                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
601                         }
602                 };
603
604                 const VkVertexInputBindingDescription vertexInputBindingDescription =
605                 {
606                         0u,                                                                     // deUint32                                     binding;
607                         sizeof(Vertex4Tex4),                            // deUint32                                     strideInBytes;
608                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputStepRate        inputRate;
609                 };
610
611                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
612                 {
613                         {
614                                 0u,                                                                             // deUint32     location;
615                                 0u,                                                                             // deUint32     binding;
616                                 VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
617                                 0u                                                                              // deUint32     offset;
618                         },
619                         {
620                                 1u,                                                                             // deUint32     location;
621                                 0u,                                                                             // deUint32     binding;
622                                 VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
623                                 DE_OFFSET_OF(Vertex4Tex4, texCoord),    // deUint32     offset;
624                         }
625                 };
626
627                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
628                 {
629                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
630                         DE_NULL,                                                                                                                // const void*                                                          pNext;
631                         0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
632                         1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
633                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
634                         2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
635                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
636                 };
637
638                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
639                 {
640                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
641                         DE_NULL,                                                                                                                // const void*                                                          pNext;
642                         0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
643                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
644                         false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
645                 };
646
647                 const VkViewport viewport =
648                 {
649                         0.0f,                                           // float        x;
650                         0.0f,                                           // float        y;
651                         (float)m_renderSize.x(),        // float        width;
652                         (float)m_renderSize.y(),        // float        height;
653                         0.0f,                                           // float        minDepth;
654                         1.0f                                            // float        maxDepth;
655                 };
656
657                 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
658
659                 const VkPipelineViewportStateCreateInfo viewportStateParams =
660                 {
661                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
662                         DE_NULL,                                                                                                                // const void*                                                  pNext;
663                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
664                         1u,                                                                                                                             // deUint32                                                             viewportCount;
665                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
666                         1u,                                                                                                                             // deUint32                                                             scissorCount;
667                         &scissor                                                                                                                // const VkRect2D*                                              pScissors;
668                 };
669
670                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
671                 {
672                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
673                         DE_NULL,                                                                                                                // const void*                                                          pNext;
674                         0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
675                         false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
676                         false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
677                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
678                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
679                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
680                         false,                                                                                                                  // VkBool32                                                                     depthBiasEnable;
681                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
682                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
683                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
684                         1.0f                                                                                                                    // float                                                                        lineWidth;
685                 };
686
687                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
688                 {
689                         false,                                                                                                          // VkBool32                                     blendEnable;
690                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcColorBlendFactor;
691                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstColorBlendFactor;
692                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
693                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcAlphaBlendFactor;
694                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstAlphaBlendFactor;
695                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
696                         VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |           // VkColorComponentFlags        colorWriteMask;
697                                 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
698                 };
699
700                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
701                 {
702                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
703                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
704                         0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
705                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
706                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
707                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
708                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
709                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
710                 };
711
712                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
713                 {
714                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
715                         DE_NULL,                                                                                                        // const void*                                                          pNext;
716                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
717                         VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
718                         false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
719                         0.0f,                                                                                                           // float                                                                        minSampleShading;
720                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
721                         false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
722                         false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
723                 };
724
725                 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
726                 {
727                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
728                         DE_NULL,                                                                                                        // const void*                                                          pNext;
729                         0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
730                         false,                                                                                                          // VkBool32                                                                     depthTestEnable;
731                         false,                                                                                                          // VkBool32                                                                     depthWriteEnable;
732                         VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
733                         false,                                                                                                          // VkBool32                                                                     depthBoundsTestEnable;
734                         false,                                                                                                          // VkBool32                                                                     stencilTestEnable;
735                         {                                                                                                                       // VkStencilOpState                                                     front;
736                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  failOp;
737                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  passOp;
738                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  depthFailOp;
739                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
740                                 0u,                                             // deUint32             compareMask;
741                                 0u,                                             // deUint32             writeMask;
742                                 0u                                              // deUint32             reference;
743                         },
744                         {                                                                                                                       // VkStencilOpState     back;
745                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  failOp;
746                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  passOp;
747                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  depthFailOp;
748                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
749                                 0u,                                             // deUint32             compareMask;
750                                 0u,                                             // deUint32             writeMask;
751                                 0u                                              // deUint32             reference;
752                         },
753                         -1.0f,                                                                                                          // float                        minDepthBounds;
754                         +1.0f                                                                                                           // float                        maxDepthBounds;
755                 };
756
757                 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
758                 {
759                         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,           // VkStructureType                                              sType;
760                         DE_NULL,                                                                                                        // const void*                                                  pNext;
761                         0u,                                                                                                                     // VkPipelineDynamicStateCreateFlags    flags;
762                         0u,                                                                                                                     // deUint32                                                             dynamicStateCount;
763                         DE_NULL                                                                                                         // const VkDynamicState*                                pDynamicStates;
764                 };
765
766                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
767                 {
768                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
769                         DE_NULL,                                                                                        // const void*                                                                          pNext;
770                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
771                         2u,                                                                                                     // deUint32                                                                                     stageCount;
772                         shaderStages,                                                                           // const VkPipelineShaderStageCreateInfo*                       pStages;
773                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
774                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
775                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
776                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
777                         &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
778                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
779                         &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
780                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
781                         &dynamicStateParams,                                                            // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
782                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
783                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
784                         0u,                                                                                                     // deUint32                                                                                     subpass;
785                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
786                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
787                 };
788
789                 m_graphicsPipeline      = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
790         }
791
792         // Create vertex buffer
793         {
794                 const VkDeviceSize                      vertexBufferSize        = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
795                 const VkBufferCreateInfo        vertexBufferParams      =
796                 {
797                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
798                         DE_NULL,                                                                        // const void*                  pNext;
799                         0u,                                                                                     // VkBufferCreateFlags  flags;
800                         vertexBufferSize,                                                       // VkDeviceSize                 size;
801                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
802                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
803                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
804                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
805                 };
806
807                 DE_ASSERT(vertexBufferSize > 0);
808
809                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
810                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
811
812                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
813
814                 // Load vertices into vertex buffer
815                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
816                 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
817         }
818
819         // Create command pool
820         {
821                 const VkCommandPoolCreateInfo cmdPoolParams =
822                 {
823                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                              sType;
824                         DE_NULL,                                                                                // const void*                                  pNext;
825                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags     flags;
826                         queueFamilyIndex                                                                // deUint32                                     queueFamilyIndex;
827                 };
828
829                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
830         }
831
832         // Create command buffer
833         {
834                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
835                 {
836                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
837                         DE_NULL,                                                                                // const void*                          pNext;
838                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
839                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
840                         1u,                                                                                             // deUint32                                     bufferCount;
841                 };
842
843                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
844                 {
845                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
846                         DE_NULL,                                                                                // const void*                                          pNext;
847                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
848                         DE_NULL,                                                                                // VkRenderPass                                         renderPass;
849                         0u,                                                                                             // deUint32                                                     subpass;
850                         DE_NULL,                                                                                // VkFramebuffer                                        framebuffer;
851                         false,                                                                                  // VkBool32                                                     occlusionQueryEnable;
852                         0u,                                                                                             // VkQueryControlFlags                          queryFlags;
853                         0u                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
854                 };
855
856                 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
857
858                 const VkRenderPassBeginInfo renderPassBeginInfo =
859                 {
860                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
861                         DE_NULL,                                                                                                // const void*                  pNext;
862                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
863                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
864                         { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } },   // VkRect2D                             renderArea;
865                         1,                                                                                                              // deUint32                             clearValueCount;
866                         &attachmentClearValue                                                                   // const VkClearValue*  pClearValues;
867                 };
868
869                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
870
871                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
872                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
873
874                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
875
876                 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
877
878                 const VkDeviceSize vertexBufferOffset = 0;
879                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
880                 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
881
882                 vk.cmdEndRenderPass(*m_cmdBuffer);
883                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
884         }
885
886         // Create fence
887         {
888                 const VkFenceCreateInfo fenceParams =
889                 {
890                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
891                         DE_NULL,                                                                // const void*                  pNext;
892                         0u                                                                              // VkFenceCreateFlags   flags;
893                 };
894
895                 m_fence = createFence(vk, vkDevice, &fenceParams);
896         }
897 }
898
899 ImageSamplingInstance::~ImageSamplingInstance (void)
900 {
901 }
902
903 tcu::TestStatus ImageSamplingInstance::iterate (void)
904 {
905         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
906         const VkDevice                          vkDevice        = m_context.getDevice();
907         const VkQueue                           queue           = m_context.getUniversalQueue();
908         const VkSubmitInfo                      submitInfo      =
909         {
910                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
911                 DE_NULL,                                                // const void*                          pNext;
912                 0u,                                                             // deUint32                                     waitSemaphoreCount;
913                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
914                 1u,                                                             // deUint32                                     commandBufferCount;
915                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
916                 0u,                                                             // deUint32                                     signalSemaphoreCount;
917                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
918         };
919
920         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
921         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
922         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
923
924         return verifyImage();
925 }
926
927 tcu::TestStatus ImageSamplingInstance::verifyImage (void)
928 {
929         const tcu::TextureFormat                colorFormat                             = mapVkFormat(m_colorFormat);
930         const tcu::TextureFormat                depthStencilFormat              = tcu::TextureFormat(); // Undefined depth/stencil format.
931         const tcu::Sampler                              sampler                                 = mapVkSampler(m_samplerParams);
932         const tcu::UVec4                                componentMapping                = mapVkComponentMapping(m_componentMapping);
933         float                                                   samplerLod;
934         bool                                                    compareOk;
935         MovePtr<Program>                                program;
936         MovePtr<ReferenceRenderer>              refRenderer;
937
938         // Set up LOD of reference sampler
939         samplerLod = de::max(m_samplerParams.minLod, de::min(m_samplerParams.maxLod, m_samplerParams.mipLodBias + m_samplerLod));
940
941         // Create reference program that uses image subresource range
942         program = createRefProgram(colorFormat, sampler, samplerLod, componentMapping, *m_texture, m_imageViewType, m_layerCount, m_subresourceRange);
943         const rr::Program referenceProgram = program->getReferenceProgram();
944
945         // Render reference image
946         refRenderer = MovePtr<ReferenceRenderer>(new ReferenceRenderer(m_renderSize.x(), m_renderSize.y(), 1, colorFormat, depthStencilFormat, &referenceProgram));
947         const rr::RenderState renderState(refRenderer->getViewportState());
948         refRenderer->draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
949
950         // Compare result with reference image
951         {
952                 const DeviceInterface&          vk                                                      = m_context.getDeviceInterface();
953                 const VkDevice                          vkDevice                                        = m_context.getDevice();
954                 const VkQueue                           queue                                           = m_context.getUniversalQueue();
955                 const deUint32                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
956                 SimpleAllocator                         memAlloc                                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
957                 MovePtr<tcu::TextureLevel>      result                                          = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_colorImage, m_colorFormat, m_renderSize);
958
959                 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
960                                                                                                                           "IntImageCompare",
961                                                                                                                           "Image comparison",
962                                                                                                                           refRenderer->getAccess(),
963                                                                                                                           result->getAccess(),
964                                                                                                                           tcu::UVec4(4, 4, 4, 4),
965                                                                                                                           tcu::IVec3(1, 1, 0),
966                                                                                                                           true,
967                                                                                                                           tcu::COMPARE_LOG_RESULT);
968         }
969
970         if (compareOk)
971                 return tcu::TestStatus::pass("Result image matches reference");
972         else
973                 return tcu::TestStatus::fail("Image mismatch");
974 }
975
976 } // pipeline
977 } // vkt