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