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