Merge "Improve VK_MAKE_VERSION and VK_BIT macros" into nyc-dev
[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_imageFormat                 (imageFormat)
344         , m_imageSize                   (imageSize)
345         , m_layerCount                  (layerCount)
346         , m_componentMapping    (componentMapping)
347         , m_subresourceRange    (subresourceRange)
348         , m_samplerParams               (samplerParams)
349         , m_samplerLod                  (samplerLod)
350         , m_renderSize                  (renderSize)
351         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
352         , m_vertices                    (vertices)
353 {
354         const DeviceInterface&          vk                                              = context.getDeviceInterface();
355         const VkDevice                          vkDevice                                = context.getDevice();
356         const VkQueue                           queue                                   = context.getUniversalQueue();
357         const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
358         SimpleAllocator                         memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
359         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
360
361         if (!isSupportedSamplableFormat(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat))
362                 throw tcu::NotSupportedError(std::string("Unsupported format for sampling: ") + getFormatName(imageFormat));
363
364         if ((samplerParams.minFilter == VK_FILTER_LINEAR ||
365                  samplerParams.magFilter == VK_FILTER_LINEAR ||
366                  samplerParams.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR) &&
367                 !isLinearFilteringSupported(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat, VK_IMAGE_TILING_OPTIMAL))
368                 throw tcu::NotSupportedError(std::string("Unsupported format for linear filtering: ") + getFormatName(imageFormat));
369
370         if (isCompressedFormat(imageFormat) && imageViewType == VK_IMAGE_VIEW_TYPE_3D)
371         {
372                 // \todo [2016-01-22 pyry] Mandate VK_ERROR_FORMAT_NOT_SUPPORTED
373                 try
374                 {
375                         const VkImageFormatProperties   formatProperties        = getPhysicalDeviceImageFormatProperties(context.getInstanceInterface(),
376                                                                                                                                                                                                                  context.getPhysicalDevice(),
377                                                                                                                                                                                                                  imageFormat,
378                                                                                                                                                                                                                  VK_IMAGE_TYPE_3D,
379                                                                                                                                                                                                                  VK_IMAGE_TILING_OPTIMAL,
380                                                                                                                                                                                                                  VK_IMAGE_USAGE_SAMPLED_BIT,
381                                                                                                                                                                                                                  (VkImageCreateFlags)0);
382
383                         if (formatProperties.maxExtent.width == 0 &&
384                                 formatProperties.maxExtent.height == 0 &&
385                                 formatProperties.maxExtent.depth == 0)
386                                 TCU_THROW(NotSupportedError, "3D compressed format not supported");
387                 }
388                 catch (const Error&)
389                 {
390                         TCU_THROW(NotSupportedError, "3D compressed format not supported");
391                 }
392         }
393
394         // Create texture image, view and sampler
395         {
396                 VkImageCreateFlags                      imageFlags                      = 0u;
397
398                 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
399                         imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
400
401                 // Initialize texture data
402                 if (isCompressedFormat(imageFormat))
403                         m_texture = createTestTexture(mapVkCompressedFormat(imageFormat), imageViewType, imageSize, layerCount);
404                 else
405                         m_texture = createTestTexture(mapVkFormat(imageFormat), imageViewType, imageSize, layerCount);
406
407                 const VkImageCreateInfo imageParams =
408                 {
409                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // VkStructureType                      sType;
410                         DE_NULL,                                                                                                                // const void*                          pNext;
411                         imageFlags,                                                                                                             // VkImageCreateFlags           flags;
412                         getCompatibleImageType(m_imageViewType),                                                // VkImageType                          imageType;
413                         imageFormat,                                                                                                    // VkFormat                                     format;
414                         {                                                                                                                               // VkExtent3D                           extent;
415                                 (deUint32)m_imageSize.x(),
416                                 (deUint32)m_imageSize.y(),
417                                 (deUint32)m_imageSize.z()
418                         },
419                         (deUint32)m_texture->getNumLevels(),                                                    // deUint32                                     mipLevels;
420                         (deUint32)m_layerCount,                                                                                 // deUint32                                     arrayLayers;
421                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits        samples;
422                         VK_IMAGE_TILING_OPTIMAL,                                                                                // VkImageTiling                        tiling;
423                         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,   // VkImageUsageFlags            usage;
424                         VK_SHARING_MODE_EXCLUSIVE,                                                                              // VkSharingMode                        sharingMode;
425                         1u,                                                                                                                             // deUint32                                     queueFamilyIndexCount;
426                         &queueFamilyIndex,                                                                                              // const deUint32*                      pQueueFamilyIndices;
427                         VK_IMAGE_LAYOUT_UNDEFINED                                                                               // VkImageLayout                        initialLayout;
428                 };
429
430                 m_image                 = createImage(vk, vkDevice, &imageParams);
431                 m_imageAlloc    = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_image), MemoryRequirement::Any);
432                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_image, m_imageAlloc->getMemory(), m_imageAlloc->getOffset()));
433
434                 // Upload texture data
435                 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, *m_image);
436
437                 // Create image view and sampler
438                 const VkImageViewCreateInfo imageViewParams =
439                 {
440                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
441                         DE_NULL,                                                                        // const void*                          pNext;
442                         0u,                                                                                     // VkImageViewCreateFlags       flags;
443                         *m_image,                                                                       // VkImage                                      image;
444                         m_imageViewType,                                                        // VkImageViewType                      viewType;
445                         imageFormat,                                                            // VkFormat                                     format;
446                         m_componentMapping,                                                     // VkComponentMapping           components;
447                         m_subresourceRange,                                                     // VkImageSubresourceRange      subresourceRange;
448                 };
449
450                 m_imageView     = createImageView(vk, vkDevice, &imageViewParams);
451                 m_sampler       = createSampler(vk, vkDevice, &m_samplerParams);
452         }
453
454         // Create descriptor set for combined image and sampler
455         {
456                 DescriptorPoolBuilder descriptorPoolBuilder;
457                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u);
458                 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
459
460                 DescriptorSetLayoutBuilder setLayoutBuilder;
461                 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
462                 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
463
464                 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
465                 {
466                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
467                         DE_NULL,                                                                                        // const void*                                  pNext;
468                         *m_descriptorPool,                                                                      // VkDescriptorPool                             descriptorPool;
469                         1u,                                                                                                     // deUint32                                             setLayoutCount;
470                         &m_descriptorSetLayout.get()                                            // const VkDescriptorSetLayout* pSetLayouts;
471                 };
472
473                 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
474
475                 const VkDescriptorImageInfo descriptorImageInfo =
476                 {
477                         *m_sampler,                                                                     // VkSampler            sampler;
478                         *m_imageView,                                                           // VkImageView          imageView;
479                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        imageLayout;
480                 };
481
482                 DescriptorSetUpdateBuilder setUpdateBuilder;
483                 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo);
484                 setUpdateBuilder.update(vk, vkDevice);
485         }
486
487         // Create color image and view
488         {
489                 const VkImageCreateInfo colorImageParams =
490                 {
491                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
492                         DE_NULL,                                                                                                                                        // const void*                          pNext;
493                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
494                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
495                         m_colorFormat,                                                                                                                          // VkFormat                                     format;
496                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                         // VkExtent3D                           extent;
497                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
498                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
499                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
500                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
501                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
502                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
503                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
504                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
505                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
506                 };
507
508                 m_colorImage                    = createImage(vk, vkDevice, &colorImageParams);
509                 m_colorImageAlloc               = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
510                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
511
512                 const VkImageViewCreateInfo colorAttachmentViewParams =
513                 {
514                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
515                         DE_NULL,                                                                                        // const void*                          pNext;
516                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
517                         *m_colorImage,                                                                          // VkImage                                      image;
518                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
519                         m_colorFormat,                                                                          // VkFormat                                     format;
520                         componentMappingRGBA,                                                           // VkComponentMapping           components;
521                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }           // VkImageSubresourceRange      subresourceRange;
522                 };
523
524                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
525         }
526
527         // Create render pass
528         {
529                 const VkAttachmentDescription colorAttachmentDescription =
530                 {
531                         0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
532                         m_colorFormat,                                                                          // VkFormat                                                     format;
533                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
534                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
535                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
536                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
537                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
538                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
539                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
540                 };
541
542                 const VkAttachmentReference colorAttachmentReference =
543                 {
544                         0u,                                                                                                     // deUint32                     attachment;
545                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
546                 };
547
548                 const VkSubpassDescription subpassDescription =
549                 {
550                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
551                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
552                         0u,                                                                                                     // deUint32                                             inputAttachmentCount;
553                         DE_NULL,                                                                                        // const VkAttachmentReference* pInputAttachments;
554                         1u,                                                                                                     // deUint32                                             colorAttachmentCount;
555                         &colorAttachmentReference,                                                      // const VkAttachmentReference* pColorAttachments;
556                         DE_NULL,                                                                                        // const VkAttachmentReference* pResolveAttachments;
557                         DE_NULL,                                                                                        // const VkAttachmentReference* pDepthStencilAttachment;
558                         0u,                                                                                                     // deUint32                                             preserveAttachmentCount;
559                         DE_NULL                                                                                         // const VkAttachmentReference* pPreserveAttachments;
560                 };
561
562                 const VkRenderPassCreateInfo renderPassParams =
563                 {
564                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
565                         DE_NULL,                                                                                        // const void*                                          pNext;
566                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
567                         1u,                                                                                                     // deUint32                                                     attachmentCount;
568                         &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
569                         1u,                                                                                                     // deUint32                                                     subpassCount;
570                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
571                         0u,                                                                                                     // deUint32                                                     dependencyCount;
572                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
573                 };
574
575                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
576         }
577
578         // Create framebuffer
579         {
580                 const VkFramebufferCreateInfo framebufferParams =
581                 {
582                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                      sType;
583                         DE_NULL,                                                                                        // const void*                          pNext;
584                         0u,                                                                                                     // VkFramebufferCreateFlags     flags;
585                         *m_renderPass,                                                                          // VkRenderPass                         renderPass;
586                         1u,                                                                                                     // deUint32                                     attachmentCount;
587                         &m_colorAttachmentView.get(),                                           // const VkImageView*           pAttachments;
588                         (deUint32)m_renderSize.x(),                                                     // deUint32                                     width;
589                         (deUint32)m_renderSize.y(),                                                     // deUint32                                     height;
590                         1u                                                                                                      // deUint32                                     layers;
591                 };
592
593                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
594         }
595
596         // Create pipeline layout
597         {
598                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
599                 {
600                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
601                         DE_NULL,                                                                                        // const void*                                  pNext;
602                         0u,                                                                                                     // VkPipelineLayoutCreateFlags  flags;
603                         1u,                                                                                                     // deUint32                                             setLayoutCount;
604                         &m_descriptorSetLayout.get(),                                           // const VkDescriptorSetLayout* pSetLayouts;
605                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
606                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
607                 };
608
609                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
610         }
611
612         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
613         m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
614
615         // Create pipeline
616         {
617                 const VkPipelineShaderStageCreateInfo shaderStages[2] =
618                 {
619                         {
620                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
621                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
622                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
623                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
624                                 *m_vertexShaderModule,                                                                          // VkShaderModule                                               module;
625                                 "main",                                                                                                         // const char*                                                  pName;
626                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
627                         },
628                         {
629                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
630                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
631                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
632                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
633                                 *m_fragmentShaderModule,                                                                        // VkShaderModule                                               module;
634                                 "main",                                                                                                         // const char*                                                  pName;
635                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
636                         }
637                 };
638
639                 const VkVertexInputBindingDescription vertexInputBindingDescription =
640                 {
641                         0u,                                                                     // deUint32                                     binding;
642                         sizeof(Vertex4Tex4),                            // deUint32                                     strideInBytes;
643                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputStepRate        inputRate;
644                 };
645
646                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
647                 {
648                         {
649                                 0u,                                                                             // deUint32     location;
650                                 0u,                                                                             // deUint32     binding;
651                                 VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
652                                 0u                                                                              // deUint32     offset;
653                         },
654                         {
655                                 1u,                                                                             // deUint32     location;
656                                 0u,                                                                             // deUint32     binding;
657                                 VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
658                                 DE_OFFSET_OF(Vertex4Tex4, texCoord),    // deUint32     offset;
659                         }
660                 };
661
662                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
663                 {
664                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
665                         DE_NULL,                                                                                                                // const void*                                                          pNext;
666                         0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
667                         1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
668                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
669                         2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
670                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
671                 };
672
673                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
674                 {
675                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
676                         DE_NULL,                                                                                                                // const void*                                                          pNext;
677                         0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
678                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
679                         false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
680                 };
681
682                 const VkViewport viewport =
683                 {
684                         0.0f,                                           // float        x;
685                         0.0f,                                           // float        y;
686                         (float)m_renderSize.x(),        // float        width;
687                         (float)m_renderSize.y(),        // float        height;
688                         0.0f,                                           // float        minDepth;
689                         1.0f                                            // float        maxDepth;
690                 };
691
692                 const VkRect2D scissor = { { 0, 0 }, { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } };
693
694                 const VkPipelineViewportStateCreateInfo viewportStateParams =
695                 {
696                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
697                         DE_NULL,                                                                                                                // const void*                                                  pNext;
698                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
699                         1u,                                                                                                                             // deUint32                                                             viewportCount;
700                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
701                         1u,                                                                                                                             // deUint32                                                             scissorCount;
702                         &scissor                                                                                                                // const VkRect2D*                                              pScissors;
703                 };
704
705                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
706                 {
707                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
708                         DE_NULL,                                                                                                                // const void*                                                          pNext;
709                         0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
710                         false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
711                         false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
712                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
713                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
714                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
715                         false,                                                                                                                  // VkBool32                                                                     depthBiasEnable;
716                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
717                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
718                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
719                         1.0f                                                                                                                    // float                                                                        lineWidth;
720                 };
721
722                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
723                 {
724                         false,                                                                                                          // VkBool32                                     blendEnable;
725                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcColorBlendFactor;
726                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstColorBlendFactor;
727                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
728                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcAlphaBlendFactor;
729                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstAlphaBlendFactor;
730                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
731                         VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |           // VkColorComponentFlags        colorWriteMask;
732                                 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
733                 };
734
735                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
736                 {
737                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
738                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
739                         0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
740                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
741                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
742                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
743                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
744                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
745                 };
746
747                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
748                 {
749                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
750                         DE_NULL,                                                                                                        // const void*                                                          pNext;
751                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
752                         VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
753                         false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
754                         0.0f,                                                                                                           // float                                                                        minSampleShading;
755                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
756                         false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
757                         false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
758                 };
759
760                 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
761                 {
762                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
763                         DE_NULL,                                                                                                        // const void*                                                          pNext;
764                         0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
765                         false,                                                                                                          // VkBool32                                                                     depthTestEnable;
766                         false,                                                                                                          // VkBool32                                                                     depthWriteEnable;
767                         VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
768                         false,                                                                                                          // VkBool32                                                                     depthBoundsTestEnable;
769                         false,                                                                                                          // VkBool32                                                                     stencilTestEnable;
770                         {                                                                                                                       // VkStencilOpState                                                     front;
771                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  failOp;
772                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  passOp;
773                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  depthFailOp;
774                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
775                                 0u,                                             // deUint32             compareMask;
776                                 0u,                                             // deUint32             writeMask;
777                                 0u                                              // deUint32             reference;
778                         },
779                         {                                                                                                                       // VkStencilOpState     back;
780                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  failOp;
781                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  passOp;
782                                 VK_STENCIL_OP_ZERO,             // VkStencilOp  depthFailOp;
783                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
784                                 0u,                                             // deUint32             compareMask;
785                                 0u,                                             // deUint32             writeMask;
786                                 0u                                              // deUint32             reference;
787                         },
788                         -1.0f,                                                                                                          // float                        minDepthBounds;
789                         +1.0f                                                                                                           // float                        maxDepthBounds;
790                 };
791
792                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
793                 {
794                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
795                         DE_NULL,                                                                                        // const void*                                                                          pNext;
796                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
797                         2u,                                                                                                     // deUint32                                                                                     stageCount;
798                         shaderStages,                                                                           // const VkPipelineShaderStageCreateInfo*                       pStages;
799                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
800                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
801                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
802                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
803                         &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
804                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
805                         &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
806                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
807                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
808                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
809                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
810                         0u,                                                                                                     // deUint32                                                                                     subpass;
811                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
812                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
813                 };
814
815                 m_graphicsPipeline      = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
816         }
817
818         // Create vertex buffer
819         {
820                 const VkDeviceSize                      vertexBufferSize        = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
821                 const VkBufferCreateInfo        vertexBufferParams      =
822                 {
823                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
824                         DE_NULL,                                                                        // const void*                  pNext;
825                         0u,                                                                                     // VkBufferCreateFlags  flags;
826                         vertexBufferSize,                                                       // VkDeviceSize                 size;
827                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
828                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
829                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
830                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
831                 };
832
833                 DE_ASSERT(vertexBufferSize > 0);
834
835                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
836                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
837
838                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
839
840                 // Load vertices into vertex buffer
841                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
842                 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
843         }
844
845         // Create command pool
846         {
847                 const VkCommandPoolCreateInfo cmdPoolParams =
848                 {
849                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                              sType;
850                         DE_NULL,                                                                                // const void*                                  pNext;
851                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags     flags;
852                         queueFamilyIndex                                                                // deUint32                                     queueFamilyIndex;
853                 };
854
855                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
856         }
857
858         // Create command buffer
859         {
860                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
861                 {
862                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
863                         DE_NULL,                                                                                // const void*                          pNext;
864                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
865                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
866                         1u,                                                                                             // deUint32                                     bufferCount;
867                 };
868
869                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
870                 {
871                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
872                         DE_NULL,                                                                                // const void*                                          pNext;
873                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
874                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
875                 };
876
877                 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
878
879                 const VkRenderPassBeginInfo renderPassBeginInfo =
880                 {
881                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
882                         DE_NULL,                                                                                                // const void*                  pNext;
883                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
884                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
885                         {
886                                 { 0, 0 },
887                                 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
888                         },                                                                                                              // VkRect2D                             renderArea;
889                         1,                                                                                                              // deUint32                             clearValueCount;
890                         &attachmentClearValue                                                                   // const VkClearValue*  pClearValues;
891                 };
892
893                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
894
895                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
896                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
897
898                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
899
900                 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
901
902                 const VkDeviceSize vertexBufferOffset = 0;
903                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
904                 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
905
906                 vk.cmdEndRenderPass(*m_cmdBuffer);
907                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
908         }
909
910         // Create fence
911         {
912                 const VkFenceCreateInfo fenceParams =
913                 {
914                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
915                         DE_NULL,                                                                // const void*                  pNext;
916                         0u                                                                              // VkFenceCreateFlags   flags;
917                 };
918
919                 m_fence = createFence(vk, vkDevice, &fenceParams);
920         }
921 }
922
923 ImageSamplingInstance::~ImageSamplingInstance (void)
924 {
925 }
926
927 tcu::TestStatus ImageSamplingInstance::iterate (void)
928 {
929         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
930         const VkDevice                          vkDevice        = m_context.getDevice();
931         const VkQueue                           queue           = m_context.getUniversalQueue();
932         const VkSubmitInfo                      submitInfo      =
933         {
934                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
935                 DE_NULL,                                                // const void*                          pNext;
936                 0u,                                                             // deUint32                                     waitSemaphoreCount;
937                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
938                 DE_NULL,
939                 1u,                                                             // deUint32                                     commandBufferCount;
940                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
941                 0u,                                                             // deUint32                                     signalSemaphoreCount;
942                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
943         };
944
945         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
946         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
947         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
948
949         return verifyImage();
950 }
951
952 tcu::TestStatus ImageSamplingInstance::verifyImage (void)
953 {
954         const tcu::TextureFormat                colorFormat                             = mapVkFormat(m_colorFormat);
955         const tcu::TextureFormat                depthStencilFormat              = tcu::TextureFormat(); // Undefined depth/stencil format.
956         const tcu::Sampler                              sampler                                 = mapVkSampler(m_samplerParams);
957         const tcu::UVec4                                componentMapping                = mapVkComponentMapping(m_componentMapping);
958         float                                                   samplerLod;
959         bool                                                    compareOk;
960         MovePtr<Program>                                program;
961         MovePtr<ReferenceRenderer>              refRenderer;
962
963         // Set up LOD of reference sampler
964         samplerLod = de::max(m_samplerParams.minLod, de::min(m_samplerParams.maxLod, m_samplerParams.mipLodBias + m_samplerLod));
965
966         // Create reference program that uses image subresource range
967         program = createRefProgram(colorFormat, sampler, samplerLod, componentMapping, *m_texture, m_imageViewType, m_layerCount, m_subresourceRange);
968         const rr::Program referenceProgram = program->getReferenceProgram();
969
970         // Render reference image
971         refRenderer = MovePtr<ReferenceRenderer>(new ReferenceRenderer(m_renderSize.x(), m_renderSize.y(), 1, colorFormat, depthStencilFormat, &referenceProgram));
972         const rr::RenderState renderState(refRenderer->getViewportState());
973         refRenderer->draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
974
975         // Compare result with reference image
976         {
977                 const DeviceInterface&          vk                                                      = m_context.getDeviceInterface();
978                 const VkDevice                          vkDevice                                        = m_context.getDevice();
979                 const VkQueue                           queue                                           = m_context.getUniversalQueue();
980                 const deUint32                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
981                 SimpleAllocator                         memAlloc                                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
982                 MovePtr<tcu::TextureLevel>      result                                          = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_colorImage, m_colorFormat, m_renderSize);
983                 tcu::UVec4                                      threshold                                       = tcu::UVec4(4, 4, 4, 4);
984
985                 if ((m_imageFormat == vk::VK_FORMAT_EAC_R11G11_SNORM_BLOCK) || (m_imageFormat == vk::VK_FORMAT_EAC_R11_SNORM_BLOCK))
986                         threshold = tcu::UVec4(8, 8, 8, 8);
987
988                 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
989                                                                                                                           "IntImageCompare",
990                                                                                                                           "Image comparison",
991                                                                                                                           refRenderer->getAccess(),
992                                                                                                                           result->getAccess(),
993                                                                                                                           threshold,
994                                                                                                                           tcu::IVec3(1, 1, 0),
995                                                                                                                           true,
996                                                                                                                           tcu::COMPARE_LOG_RESULT);
997         }
998
999         if (compareOk)
1000                 return tcu::TestStatus::pass("Result image matches reference");
1001         else
1002                 return tcu::TestStatus::fail("Image mismatch");
1003 }
1004
1005 } // pipeline
1006 } // vkt