Merge vk-gl-cts/vulkan-cts-1.0.2 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / texture / vktTextureTestUtil.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Texture test utilities.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktTextureTestUtil.hpp"
27
28 #include "deFilePath.hpp"
29 #include "deMath.h"
30 #include "tcuCompressedTexture.hpp"
31 #include "tcuImageIO.hpp"
32 #include "tcuStringTemplate.hpp"
33 #include "tcuTestLog.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkImageUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include <map>
41 #include <string>
42 #include <vector>
43
44 using tcu::TestLog;
45
46 using namespace vk;
47 using namespace glu::TextureTestUtil;
48
49 namespace vkt
50 {
51 namespace texture
52 {
53 namespace util
54 {
55
56 struct ShaderParameters {
57         float           bias;                           //!< User-supplied bias.
58         float           ref;                            //!< Reference value for shadow lookups.
59         tcu::Vec2       padding;                        //!< Shader uniform padding.
60         tcu::Vec4       colorScale;                     //!< Scale for texture color values.
61         tcu::Vec4       colorBias;                      //!< Bias for texture color values.
62 };
63
64 const char* getProgramName(Program program)
65 {
66         switch (program)
67         {
68                 case PROGRAM_2D_FLOAT:                  return "2D_FLOAT";
69                 case PROGRAM_2D_INT:                    return "2D_INT";
70                 case PROGRAM_2D_UINT:                   return "2D_UINT";
71                 case PROGRAM_2D_SHADOW:                 return "2D_SHADOW";
72                 case PROGRAM_2D_FLOAT_BIAS:             return "2D_FLOAT_BIAS";
73                 case PROGRAM_2D_INT_BIAS:               return "2D_INT_BIAS";
74                 case PROGRAM_2D_UINT_BIAS:              return "2D_UINT_BIAS";
75                 case PROGRAM_2D_SHADOW_BIAS:    return "2D_SHADOW_BIAS";
76                 case PROGRAM_1D_FLOAT:                  return "1D_FLOAT";
77                 case PROGRAM_1D_INT:                    return "1D_INT";
78                 case PROGRAM_1D_UINT:                   return "1D_UINT";
79                 case PROGRAM_1D_SHADOW:                 return "1D_SHADOW";
80                 case PROGRAM_1D_FLOAT_BIAS:             return "1D_FLOAT_BIAS";
81                 case PROGRAM_1D_INT_BIAS:               return "1D_INT_BIAS";
82                 case PROGRAM_1D_UINT_BIAS:              return "1D_UINT_BIAS";
83                 case PROGRAM_1D_SHADOW_BIAS:    return "1D_SHADOW_BIAS";
84                 case PROGRAM_CUBE_FLOAT:                return "CUBE_FLOAT";
85                 case PROGRAM_CUBE_INT:                  return "CUBE_INT";
86                 case PROGRAM_CUBE_UINT:                 return "CUBE_UINT";
87                 case PROGRAM_CUBE_SHADOW:               return "CUBE_SHADOW";
88                 case PROGRAM_CUBE_FLOAT_BIAS:   return "CUBE_FLOAT_BIAS";
89                 case PROGRAM_CUBE_INT_BIAS:             return "CUBE_INT_BIAS";
90                 case PROGRAM_CUBE_UINT_BIAS:    return "CUBE_UINT_BIAS";
91                 case PROGRAM_CUBE_SHADOW_BIAS:  return "CUBE_SHADOW_BIAS";
92                 case PROGRAM_2D_ARRAY_FLOAT:    return "2D_ARRAY_FLOAT";
93                 case PROGRAM_2D_ARRAY_INT:              return "2D_ARRAY_INT";
94                 case PROGRAM_2D_ARRAY_UINT:             return "2D_ARRAY_UINT";
95                 case PROGRAM_2D_ARRAY_SHADOW:   return "2D_ARRAY_SHADOW";
96                 case PROGRAM_3D_FLOAT:                  return "3D_FLOAT";
97                 case PROGRAM_3D_INT:                    return "3D_INT";
98                 case PROGRAM_3D_UINT:                   return "3D_UINT";
99                 case PROGRAM_3D_FLOAT_BIAS:             return "3D_FLOAT_BIAS";
100                 case PROGRAM_3D_INT_BIAS:               return "3D_INT_BIAS";
101                 case PROGRAM_3D_UINT_BIAS:              return "3D_UINT_BIAS";
102                 case PROGRAM_CUBE_ARRAY_FLOAT:  return "CUBE_ARRAY_FLOAT";
103                 case PROGRAM_CUBE_ARRAY_INT:    return "CUBE_ARRAY_INT";
104                 case PROGRAM_CUBE_ARRAY_UINT:   return "CUBE_ARRAY_UINT";
105                 case PROGRAM_CUBE_ARRAY_SHADOW: return "CUBE_ARRAY_SHADOW";
106                 case PROGRAM_1D_ARRAY_FLOAT:    return "1D_ARRAY_FLOAT";
107                 case PROGRAM_1D_ARRAY_INT:              return "1D_ARRAY_INT";
108                 case PROGRAM_1D_ARRAY_UINT:             return "1D_ARRAY_UINT";
109                 case PROGRAM_1D_ARRAY_SHADOW:   return "1D_ARRAY_SHADOW";
110                 case PROGRAM_BUFFER_FLOAT:              return "BUFFER_FLOAT";
111                 case PROGRAM_BUFFER_INT:                return "BUFFER_INT";
112                 case PROGRAM_BUFFER_UINT:               return "BUFFER_UINT";
113                 default:
114                         DE_ASSERT(false);
115         }
116         return NULL;
117 }
118
119 VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
120 {
121         switch (type)
122         {
123                 case TextureBinding::TYPE_2D:                   return VK_IMAGE_VIEW_TYPE_2D;
124                 case TextureBinding::TYPE_2D_ARRAY:             return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
125                 case TextureBinding::TYPE_CUBE_MAP:             return VK_IMAGE_VIEW_TYPE_CUBE;
126                 case TextureBinding::TYPE_3D:                   return VK_IMAGE_VIEW_TYPE_3D;
127                 default:
128                         DE_ASSERT(false);
129         }
130
131         return VK_IMAGE_VIEW_TYPE_2D;
132 }
133
134 VkImageType imageViewTypeToImageType (VkImageViewType type)
135 {
136         switch (type)
137         {
138                 case VK_IMAGE_VIEW_TYPE_2D:
139                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
140                 case VK_IMAGE_VIEW_TYPE_CUBE:                   return VK_IMAGE_TYPE_2D;
141                 case VK_IMAGE_VIEW_TYPE_3D:                             return VK_IMAGE_TYPE_3D;
142                 default:
143                         DE_ASSERT(false);
144         }
145
146         return VK_IMAGE_TYPE_2D;
147 }
148
149 void initializePrograms(vk::SourceCollections& programCollection, glu::Precision texCoordPrecision, const std::vector<Program>& programs)
150 {
151         static const char* vertShaderTemplate =
152                 "${VTX_HEADER}"
153                 "layout(location = 0) ${VTX_IN} highp vec4 a_position;\n"
154                 "layout(location = 1) ${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n"
155                 "layout(location = 0) ${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
156                 "${VTX_OUT} gl_PerVertex { vec4 gl_Position; };\n"
157                 "\n"
158                 "void main (void)\n"
159                 "{\n"
160                 "       gl_Position = a_position;\n"
161                 "       v_texCoord = a_texCoord;\n"
162                 "}\n";
163
164         static const char* fragShaderTemplate =
165                 "${FRAG_HEADER}"
166                 "layout(location = 0) ${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
167                 "layout(location = 0) out mediump vec4 ${FRAG_COLOR};\n"
168                 "layout (set=0, binding=0, std140) uniform Block \n"
169                 "{\n"
170                 "  ${PRECISION} float u_bias;\n"
171                 "  ${PRECISION} float u_ref;\n"
172                 "  ${PRECISION} vec4 u_colorScale;\n"
173                 "  ${PRECISION} vec4 u_colorBias;\n"
174                 "};\n\n"
175                 "layout (set=1, binding=0) uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n"
176                 "void main (void)\n"
177                 "{\n"
178                 "       ${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n"
179                 "}\n";
180
181         tcu::StringTemplate                                     vertexSource    (vertShaderTemplate);
182         tcu::StringTemplate                                     fragmentSource  (fragShaderTemplate);
183
184         for (std::vector<Program>::const_iterator programIt = programs.begin(); programIt != programs.end(); ++programIt)
185         {
186                 Program                                                         program = *programIt;
187                 std::map<std::string, std::string>      params;
188
189                 bool    isCube          = de::inRange<int>(program, PROGRAM_CUBE_FLOAT, PROGRAM_CUBE_SHADOW_BIAS);
190                 bool    isArray         = de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW)
191                                                                 || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW);
192
193                 bool    is1D            = de::inRange<int>(program, PROGRAM_1D_FLOAT, PROGRAM_1D_SHADOW_BIAS)
194                                                                 || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW)
195                                                                 || de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
196
197                 bool    is2D            = de::inRange<int>(program, PROGRAM_2D_FLOAT, PROGRAM_2D_SHADOW_BIAS)
198                                                                 || de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW);
199
200                 bool    is3D            = de::inRange<int>(program, PROGRAM_3D_FLOAT, PROGRAM_3D_UINT_BIAS);
201                 bool    isCubeArray     = de::inRange<int>(program, PROGRAM_CUBE_ARRAY_FLOAT, PROGRAM_CUBE_ARRAY_SHADOW);
202
203                 const std::string       version = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450);
204
205                 params["FRAG_HEADER"]   = version + "\n";
206                 params["VTX_HEADER"]    = version + "\n";
207                 params["VTX_IN"]                = "in";
208                 params["VTX_OUT"]               = "out";
209                 params["FRAG_IN"]               = "in";
210                 params["FRAG_COLOR"]    = "dEQP_FragColor";
211
212                 params["PRECISION"]             = glu::getPrecisionName(texCoordPrecision);
213
214                 if (isCubeArray)
215                         params["TEXCOORD_TYPE"] = "vec4";
216                 else if (isCube || (is2D && isArray) || is3D)
217                         params["TEXCOORD_TYPE"] = "vec3";
218                 else if ((is1D && isArray) || is2D)
219                         params["TEXCOORD_TYPE"] = "vec2";
220                 else if (is1D)
221                         params["TEXCOORD_TYPE"] = "float";
222                 else
223                         DE_ASSERT(DE_FALSE);
224
225                 const char*     sampler = DE_NULL;
226                 const char*     lookup  = DE_NULL;
227
228                 switch (program)
229                 {
230                         case PROGRAM_2D_FLOAT:                  sampler = "sampler2D";                          lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
231                         case PROGRAM_2D_INT:                    sampler = "isampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
232                         case PROGRAM_2D_UINT:                   sampler = "usampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
233                         case PROGRAM_2D_SHADOW:                 sampler = "sampler2DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
234                         case PROGRAM_2D_FLOAT_BIAS:             sampler = "sampler2D";                          lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
235                         case PROGRAM_2D_INT_BIAS:               sampler = "isampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
236                         case PROGRAM_2D_UINT_BIAS:              sampler = "usampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
237                         case PROGRAM_2D_SHADOW_BIAS:    sampler = "sampler2DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";    break;
238                         case PROGRAM_1D_FLOAT:                  sampler = "sampler1D";                          lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
239                         case PROGRAM_1D_INT:                    sampler = "isampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
240                         case PROGRAM_1D_UINT:                   sampler = "usampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
241                         case PROGRAM_1D_SHADOW:                 sampler = "sampler1DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref)), 0.0, 0.0, 1.0)";               break;
242                         case PROGRAM_1D_FLOAT_BIAS:             sampler = "sampler1D";                          lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
243                         case PROGRAM_1D_INT_BIAS:               sampler = "isampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
244                         case PROGRAM_1D_UINT_BIAS:              sampler = "usampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
245                         case PROGRAM_1D_SHADOW_BIAS:    sampler = "sampler1DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref), u_bias), 0.0, 0.0, 1.0)";       break;
246                         case PROGRAM_CUBE_FLOAT:                sampler = "samplerCube";                        lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
247                         case PROGRAM_CUBE_INT:                  sampler = "isamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
248                         case PROGRAM_CUBE_UINT:                 sampler = "usamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
249                         case PROGRAM_CUBE_SHADOW:               sampler = "samplerCubeShadow";          lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
250                         case PROGRAM_CUBE_FLOAT_BIAS:   sampler = "samplerCube";                        lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
251                         case PROGRAM_CUBE_INT_BIAS:             sampler = "isamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
252                         case PROGRAM_CUBE_UINT_BIAS:    sampler = "usamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
253                         case PROGRAM_CUBE_SHADOW_BIAS:  sampler = "samplerCubeShadow";          lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";    break;
254                         case PROGRAM_2D_ARRAY_FLOAT:    sampler = "sampler2DArray";                     lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
255                         case PROGRAM_2D_ARRAY_INT:              sampler = "isampler2DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
256                         case PROGRAM_2D_ARRAY_UINT:             sampler = "usampler2DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
257                         case PROGRAM_2D_ARRAY_SHADOW:   sampler = "sampler2DArrayShadow";       lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
258                         case PROGRAM_3D_FLOAT:                  sampler = "sampler3D";                          lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
259                         case PROGRAM_3D_INT:                    sampler = "isampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
260                         case PROGRAM_3D_UINT:                   sampler = "usampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
261                         case PROGRAM_3D_FLOAT_BIAS:             sampler = "sampler3D";                          lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
262                         case PROGRAM_3D_INT_BIAS:               sampler = "isampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
263                         case PROGRAM_3D_UINT_BIAS:              sampler = "usampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
264                         case PROGRAM_CUBE_ARRAY_FLOAT:  sampler = "samplerCubeArray";           lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
265                         case PROGRAM_CUBE_ARRAY_INT:    sampler = "isamplerCubeArray";          lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
266                         case PROGRAM_CUBE_ARRAY_UINT:   sampler = "usamplerCubeArray";          lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
267                         case PROGRAM_CUBE_ARRAY_SHADOW: sampler = "samplerCubeArrayShadow";     lookup = "vec4(texture(u_sampler, v_texCoord, u_ref), 0.0, 0.0, 1.0)";                  break;
268                         case PROGRAM_1D_ARRAY_FLOAT:    sampler = "sampler1DArray";                     lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
269                         case PROGRAM_1D_ARRAY_INT:              sampler = "isampler1DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
270                         case PROGRAM_1D_ARRAY_UINT:             sampler = "usampler1DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
271                         case PROGRAM_1D_ARRAY_SHADOW:   sampler = "sampler1DArrayShadow";       lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
272                         case PROGRAM_BUFFER_FLOAT:              sampler = "samplerBuffer";                      lookup = "texelFetch(u_sampler, int(v_texCoord))";                                                                              break;
273                         case PROGRAM_BUFFER_INT:                sampler = "isamplerBuffer";                     lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";                                                                break;
274                         case PROGRAM_BUFFER_UINT:               sampler = "usamplerBuffer";                     lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";                                                                break;
275                         default:
276                                 DE_ASSERT(false);
277                 }
278
279                 params["SAMPLER_TYPE"]  = sampler;
280                 params["LOOKUP"]                = lookup;
281
282                 programCollection.glslSources.add("vertext_" + std::string(getProgramName(program))) << glu::VertexSource(vertexSource.specialize(params));
283                 programCollection.glslSources.add("fragment_" + std::string(getProgramName(program))) << glu::FragmentSource(fragmentSource.specialize(params));
284         }
285 }
286
287 TextureBinding::TextureBinding (Context& context)
288         : m_context                     (context)
289 {
290 }
291
292 TextureBinding::TextureBinding (Context& context, const TestTextureSp& textureData, const TextureBinding::Type type)
293         : m_context                     (context)
294         , m_type                        (type)
295         , m_textureData         (textureData)
296 {
297         updateTextureData(m_textureData, m_type);
298 }
299
300 void TextureBinding::updateTextureData (const TestTextureSp& textureData, const TextureBinding::Type textureType)
301 {
302         const DeviceInterface&                                          vkd                                             = m_context.getDeviceInterface();
303         const VkDevice                                                          vkDevice                                = m_context.getDevice();
304         const VkQueue                                                           queue                                   = m_context.getUniversalQueue();
305         const deUint32                                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
306         Allocator&                                                                      allocator                               = m_context.getDefaultAllocator();
307
308         m_type                  = textureType;
309         m_textureData   = textureData;
310
311         const bool                                                                      isCube                                  = m_type == TYPE_CUBE_MAP;
312         const VkImageCreateFlags                                        imageCreateFlags                = isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
313         const VkImageViewType                                           imageViewType                   = textureTypeToImageViewType(textureType);
314         const VkImageType                                                       imageType                               = imageViewTypeToImageType(imageViewType);
315         const VkImageTiling                                                     imageTiling                             = VK_IMAGE_TILING_OPTIMAL;
316         const VkImageUsageFlags                                         imageUsageFlags                 = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
317         const VkFormat                                                          format                                  = textureData->isCompressed() ? mapCompressedTextureFormat(textureData->getCompressedLevel(0, 0).getFormat()) : mapTextureFormat(textureData->getTextureFormat());
318         const tcu::UVec3                                                        textureDimension                = textureData->getTextureDimension();
319         const deUint32                                                          mipLevels                               = textureData->getNumLevels();
320         const deUint32                                                          arraySize                               = textureData->getArraySize();
321         vk::VkImageFormatProperties                                     imageFormatProperties;
322         const VkResult                                                          imageFormatQueryResult  = m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties);
323
324         if (imageFormatQueryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
325         {
326                 TCU_THROW(NotSupportedError, (std::string("Format not supported: ") + vk::getFormatName(format)).c_str());
327         }
328         else
329                 VK_CHECK(imageFormatQueryResult);
330
331         if (imageFormatProperties.maxArrayLayers < arraySize)
332                 TCU_THROW(NotSupportedError, ("Maximum array layers number for this format is not enough for this test."));
333
334         if (imageFormatProperties.maxMipLevels < mipLevels)
335                 TCU_THROW(NotSupportedError, ("Maximum mimap level number for this format is not enough for this test."));
336
337         if (imageFormatProperties.maxExtent.width < textureDimension.x() ||
338                 imageFormatProperties.maxExtent.height < textureDimension.y() ||
339                 imageFormatProperties.maxExtent.depth < textureDimension.z())
340         {
341                 TCU_THROW(NotSupportedError, ("Maximum image dimension for this format is not enough for this test."));
342         }
343
344         // Create image
345         const VkImageCreateInfo                                         imageParams                             =
346         {
347                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // VkStructureType                      sType;
348                 DE_NULL,                                                                                                                // const void*                          pNext;
349                 imageCreateFlags,                                                                                               // VkImageCreateFlags           flags;
350                 imageType,                                                                                                              // VkImageType                          imageType;
351                 format,                                                                                                                 // VkFormat                                     format;
352                 {                                                                                                                               // VkExtent3D                           extent;
353                         (deUint32)textureDimension.x(),
354                         (deUint32)textureDimension.y(),
355                         (deUint32)textureDimension.z()
356                 },
357                 mipLevels,                                                                                                              // deUint32                                     mipLevels;
358                 arraySize,                                                                                                              // deUint32                                     arrayLayers;
359                 VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits        samples;
360                 imageTiling,                                                                                                    // VkImageTiling                        tiling;
361                 imageUsageFlags,                                                                                                // VkImageUsageFlags            usage;
362                 VK_SHARING_MODE_EXCLUSIVE,                                                                              // VkSharingMode                        sharingMode;
363                 1u,                                                                                                                             // deUint32                                     queueFamilyIndexCount;
364                 &queueFamilyIndex,                                                                                              // const deUint32*                      pQueueFamilyIndices;
365                 VK_IMAGE_LAYOUT_UNDEFINED                                                                               // VkImageLayout                        initialLayout;
366         };
367
368         m_textureImage                  = createImage(vkd, vkDevice, &imageParams);
369         m_textureImageMemory    = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_textureImage), MemoryRequirement::Any);
370         VK_CHECK(vkd.bindImageMemory(vkDevice, *m_textureImage, m_textureImageMemory->getMemory(), m_textureImageMemory->getOffset()));
371
372         updateTextureViewMipLevels(0, mipLevels - 1);
373
374         pipeline::uploadTestTexture(vkd, vkDevice, queue, queueFamilyIndex, allocator, *m_textureData, *m_textureImage);
375 }
376
377 void TextureBinding::updateTextureViewMipLevels (deUint32 baseLevel, deUint32 maxLevel)
378 {
379         const DeviceInterface&                                          vkd                                             = m_context.getDeviceInterface();
380         const VkDevice                                                          vkDevice                                = m_context.getDevice();
381         const vk::VkImageViewType                                       imageViewType                   = textureTypeToImageViewType(m_type);
382         const vk::VkFormat                                                      format                                  = m_textureData->isCompressed() ? mapCompressedTextureFormat(m_textureData->getCompressedLevel(0, 0).getFormat()) : mapTextureFormat(m_textureData->getTextureFormat());
383         const bool                                                                      isShadowTexture                 = tcu::hasDepthComponent(m_textureData->getTextureFormat().order);
384         const VkImageAspectFlags                                        aspectMask                              = isShadowTexture ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
385         const deUint32                                                          layerCount                              = m_textureData->getArraySize();
386         const vk::VkImageViewCreateInfo                         viewParams                              =
387         {
388                 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,   // VkStructureType                      sType;
389                 NULL,                                                                                   // const voide*                         pNext;
390                 0u,                                                                                             // VkImageViewCreateFlags       flags;
391                 *m_textureImage,                                                                // VkImage                                      image;
392                 imageViewType,                                                                  // VkImageViewType                      viewType;
393                 format,                                                                                 // VkFormat                                     format;
394                 makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
395                 {
396                         aspectMask,                                                                     // VkImageAspectFlags   aspectMask;
397                         baseLevel,                                                                      // deUint32                             baseMipLevel;
398                         maxLevel-baseLevel+1,                                           // deUint32                             levelCount;
399                         0,                                                                                      // deUint32                             baseArrayLayer;
400                         layerCount                                                                      // deUint32                             layerCount;
401                 },                                                                                              // VkImageSubresourceRange      subresourceRange;
402         };
403
404         m_textureImageView              = createImageView(vkd, vkDevice, &viewParams);
405 }
406
407 const deUint16          TextureRenderer::s_vertexIndices[6] = { 0, 1, 2, 2, 1, 3 };
408 const VkDeviceSize      TextureRenderer::s_vertexIndexBufferSize = sizeof(TextureRenderer::s_vertexIndices);
409
410 TextureRenderer::TextureRenderer (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderWidth, deUint32 renderHeight)
411         : m_context                                     (context)
412         , m_log                                         (context.getTestContext().getLog())
413         , m_renderWidth                         (renderWidth)
414         , m_renderHeight                        (renderHeight)
415         , m_sampleCount                         (sampleCount)
416         , m_multisampling                       (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
417         , m_imageFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
418         , m_textureFormat                       (vk::mapVkFormat(m_imageFormat))
419         , m_uniformBufferSize           (sizeof(ShaderParameters))
420         , m_resultBufferSize            (renderWidth * renderHeight * m_textureFormat.getPixelSize())
421         , m_viewportOffsetX                     (0.0f)
422         , m_viewportOffsetY                     (0.0f)
423         , m_viewportWidth                       ((float)renderWidth)
424         , m_viewportHeight                      ((float)renderHeight)
425 {
426         const DeviceInterface&                                          vkd                                             = m_context.getDeviceInterface();
427         const VkDevice                                                          vkDevice                                = m_context.getDevice();
428         const deUint32                                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
429         Allocator&                                                                      allocator                               = m_context.getDefaultAllocator();
430
431         // Command Pool
432         m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
433
434         // Image
435         {
436                 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
437                 VkImageFormatProperties properties;
438
439                 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
440                                                                                                                                                                          m_imageFormat,
441                                                                                                                                                                          VK_IMAGE_TYPE_2D,
442                                                                                                                                                                          VK_IMAGE_TILING_OPTIMAL,
443                                                                                                                                                                          imageUsage,
444                                                                                                                                                                          0,
445                                                                                                                                                                          &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
446                 {
447                         TCU_THROW(NotSupportedError, "Format not supported");
448                 }
449
450                 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
451                 {
452                         TCU_THROW(NotSupportedError, "Format not supported");
453                 }
454
455                 const VkImageCreateInfo                                 imageCreateInfo                 =
456                 {
457                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType;
458                         DE_NULL,                                                                        // const void*                          pNext;
459                         0u,                                                                                     // VkImageCreateFlags           flags;
460                         VK_IMAGE_TYPE_2D,                                                       // VkImageType                          imageType;
461                         m_imageFormat,                                                          // VkFormat                                     format;
462                         { m_renderWidth, m_renderHeight, 1u },          // VkExtent3D                           extent;
463                         1u,                                                                                     // deUint32                                     mipLevels;
464                         1u,                                                                                     // deUint32                                     arrayLayers;
465                         m_sampleCount,                                                          // VkSampleCountFlagBits        samples;
466                         VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling;
467                         imageUsage,                                                                     // VkImageUsageFlags            usage;
468                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode;
469                         1u,                                                                                     // deUint32                                     queueFamilyIndexCount;
470                         &queueFamilyIndex,                                                      // const deUint32*                      pQueueFamilyIndices;
471                         VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout;
472                 };
473
474                 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
475
476                 m_imageMemory   = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
477                 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
478         }
479
480         // Image View
481         {
482                 const VkImageViewCreateInfo                             imageViewCreateInfo             =
483                 {
484                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                              sType;
485                         DE_NULL,                                                                        // const void*                                  pNext;
486                         0u,                                                                                     // VkImageViewCreateFlags               flags;
487                         *m_image,                                                                       // VkImage                                              image;
488                         VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                              viewType;
489                         m_imageFormat,                                                          // VkFormat                                             format;
490                         makeComponentMappingRGBA(),                                     // VkComponentMapping                   components;
491                         {
492                                 VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags                   aspectMask;
493                                 0u,                                                                                     // deUint32                                             baseMipLevel;
494                                 1u,                                                                                     // deUint32                                             mipLevels;
495                                 0u,                                                                                     // deUint32                                             baseArrayLayer;
496                                 1u,                                                                                     // deUint32                                             arraySize;
497                         },                                                                                      // VkImageSubresourceRange              subresourceRange;
498                 };
499
500                 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
501         }
502
503         if (m_multisampling)
504         {
505                 {
506                         // Resolved Image
507                         const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
508                         VkImageFormatProperties properties;
509
510                         if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
511                                                                                                                                                                                  m_imageFormat,
512                                                                                                                                                                                  VK_IMAGE_TYPE_2D,
513                                                                                                                                                                                  VK_IMAGE_TILING_OPTIMAL,
514                                                                                                                                                                                  imageUsage,
515                                                                                                                                                                                  0,
516                                                                                                                                                                                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
517                         {
518                                 TCU_THROW(NotSupportedError, "Format not supported");
519                         }
520
521                         const VkImageCreateInfo                                 imageCreateInfo                 =
522                         {
523                                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType;
524                                 DE_NULL,                                                                        // const void*                          pNext;
525                                 0u,                                                                                     // VkImageCreateFlags           flags;
526                                 VK_IMAGE_TYPE_2D,                                                       // VkImageType                          imageType;
527                                 m_imageFormat,                                                          // VkFormat                                     format;
528                                 { m_renderWidth, m_renderHeight, 1u },          // VkExtent3D                           extent;
529                                 1u,                                                                                     // deUint32                                     mipLevels;
530                                 1u,                                                                                     // deUint32                                     arrayLayers;
531                                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits        samples;
532                                 VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling;
533                                 imageUsage,                                                                     // VkImageUsageFlags            usage;
534                                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode;
535                                 1u,                                                                                     // deUint32                                     queueFamilyIndexCount;
536                                 &queueFamilyIndex,                                                      // const deUint32*                      pQueueFamilyIndices;
537                                 VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout;
538                         };
539
540                         m_resolvedImage                 = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
541                         m_resolvedImageMemory   = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
542                         VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
543                 }
544
545                 // Resolved Image View
546                 {
547                         const VkImageViewCreateInfo                             imageViewCreateInfo             =
548                         {
549                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                              sType;
550                                 DE_NULL,                                                                        // const void*                                  pNext;
551                                 0u,                                                                                     // VkImageViewCreateFlags               flags;
552                                 *m_resolvedImage,                                                       // VkImage                                              image;
553                                 VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                              viewType;
554                                 m_imageFormat,                                                          // VkFormat                                             format;
555                                 makeComponentMappingRGBA(),                                     // VkComponentMapping                   components;
556                                 {
557                                         VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags                   aspectMask;
558                                         0u,                                                                                     // deUint32                                             baseMipLevel;
559                                         1u,                                                                                     // deUint32                                             mipLevels;
560                                         0u,                                                                                     // deUint32                                             baseArrayLayer;
561                                         1u,                                                                                     // deUint32                                             arraySize;
562                                 },                                                                                      // VkImageSubresourceRange              subresourceRange;
563                         };
564
565                         m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
566                 }
567         }
568
569         // Render Pass
570         {
571                 const VkImageLayout                                             imageLayout                             = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
572                 const VkAttachmentDescription                   attachmentDesc[]                =
573                 {
574                         {
575                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
576                                 m_imageFormat,                                                                          // VkFormat                                                     format;
577                                 m_sampleCount,                                                                          // VkSampleCountFlagBits                        samples;
578                                 VK_ATTACHMENT_LOAD_OP_LOAD,                                                                                             // VkAttachmentLoadOp                           loadOp;
579                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
580                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
581                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
582                                 imageLayout,                                                                            // VkImageLayout                                        initialLayout;
583                                 imageLayout,                                                                            // VkImageLayout                                        finalLayout;
584                         },
585                         {
586                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
587                                 m_imageFormat,                                                                          // VkFormat                                                     format;
588                                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
589                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           loadOp;
590                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
591                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
592                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
593                                 imageLayout,                                                                            // VkImageLayout                                        initialLayout;
594                                 imageLayout,                                                                            // VkImageLayout                                        finalLayout;
595                         }
596                 };
597
598                 const VkAttachmentReference                             attachmentRef                   =
599                 {
600                         0u,                                                                                                     // deUint32                                                     attachment;
601                         imageLayout,                                                                            // VkImageLayout                                        layout;
602                 };
603
604                 const VkAttachmentReference                             resolveAttachmentRef    =
605                 {
606                         1u,                                                                                                     // deUint32                                                     attachment;
607                         imageLayout,                                                                            // VkImageLayout                                        layout;
608                 };
609
610                 const VkSubpassDescription                              subpassDesc                             =
611                 {
612                         0u,                                                                                                     // VkSubpassDescriptionFlags            flags;
613                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
614                         0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
615                         DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
616                         1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
617                         &attachmentRef,                                                                         // const VkAttachmentReference*         pColorAttachments;
618                         m_multisampling ? &resolveAttachmentRef : DE_NULL,      // const VkAttachmentReference*         pResolveAttachments;
619                         DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
620                         0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
621                         DE_NULL,                                                                                        // const VkAttachmentReference*         pPreserveAttachments;
622                 };
623
624                 const VkRenderPassCreateInfo                    renderPassCreateInfo    =
625                 {
626                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
627                         DE_NULL,                                                                                        // const void*                                          pNext;
628                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
629                         m_multisampling ? 2u : 1u,                                                      // deUint32                                                     attachmentCount;
630                         attachmentDesc,                                                                         // const VkAttachmentDescription*       pAttachments;
631                         1u,                                                                                                     // deUint32                                                     subpassCount;
632                         &subpassDesc,                                                                           // const VkSubpassDescription*          pSubpasses;
633                         0u,                                                                                                     // deUint32                                                     dependencyCount;
634                         DE_NULL,                                                                                        // const VkSubpassDependency*           pDependencies;
635                 };
636
637                 m_renderPass =  createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
638         }
639
640         // Vertex index buffer
641         {
642                 const VkBufferCreateInfo                        indexBufferParams               =
643                 {
644                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
645                         DE_NULL,                                                                        // const void*                  pNext;
646                         0u,                                                                                     // VkBufferCreateFlags  flags;
647                         s_vertexIndexBufferSize,                                        // VkDeviceSize                 size;
648                         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,                       // VkBufferUsageFlags   usage;
649                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
650                         1u,                                                                                     // deUint32                             queueFamilyCount;
651                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
652                 };
653
654                 m_vertexIndexBuffer                     = createBuffer(vkd, vkDevice, &indexBufferParams);
655                 m_vertexIndexBufferMemory       = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_vertexIndexBuffer), MemoryRequirement::HostVisible);
656
657                 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_vertexIndexBuffer, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset()));
658
659                 // Load vertices into vertex buffer
660                 deMemcpy(m_vertexIndexBufferMemory->getHostPtr(), s_vertexIndices, s_vertexIndexBufferSize);
661                 flushMappedMemoryRange(vkd, vkDevice, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset(), VK_WHOLE_SIZE);
662         }
663
664         // FrameBuffer
665         {
666                 const VkImageView                                               attachments[]                   =
667                 {
668                         *m_imageView,
669                         *m_resolvedImageView,
670                 };
671
672                 const VkFramebufferCreateInfo                   framebufferCreateInfo   =
673                 {
674                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
675                         DE_NULL,                                                                        // const void*                          pNext;
676                         0u,                                                                                     // VkFramebufferCreateFlags     flags;
677                         *m_renderPass,                                                          // VkRenderPass                         renderPass;
678                         m_multisampling ? 2u : 1u,                                      // deUint32                                     attachmentCount;
679                         attachments,                                                            // const VkImageView*           pAttachments;
680                         m_renderWidth,                                                          // deUint32                                     width;
681                         m_renderHeight,                                                         // deUint32                                     height;
682                         1u,                                                                                     // deUint32                                     layers;
683                 };
684
685                 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
686         }
687
688         // Uniform Buffer
689         {
690                 const VkBufferCreateInfo                                bufferCreateInfo                =
691                 {
692                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
693                         DE_NULL,                                                                        // const void*                  pNext;
694                         0u,                                                                                     // VkBufferCreateFlags  flags;
695                         m_uniformBufferSize,                                            // VkDeviceSize                 size;
696                         VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
697                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
698                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
699                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
700                 };
701
702                 m_uniformBuffer                 = createBuffer(vkd, vkDevice, &bufferCreateInfo);
703                 m_uniformBufferMemory   = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
704
705                 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
706         }
707
708         // DescriptorPool
709         {
710                 DescriptorPoolBuilder                                   descriptorPoolBuilder;
711
712                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
713                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
714                 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
715         }
716
717         // Fence
718         m_fence = createFence(vkd, vkDevice);
719
720         // Result Buffer
721         {
722                 const VkBufferCreateInfo                                bufferCreateInfo                =
723                 {
724                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
725                         DE_NULL,                                                                        // const void*                  pNext;
726                         0u,                                                                                     // VkBufferCreateFlags  flags;
727                         m_resultBufferSize,                                                     // VkDeviceSize                 size;
728                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
729                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
730                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
731                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
732                 };
733
734                 m_resultBuffer                  = createBuffer(vkd, vkDevice, &bufferCreateInfo);
735                 m_resultBufferMemory    = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
736
737                 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
738         }
739
740         clearImage(*m_image);
741         if(m_multisampling)
742                 clearImage(*m_resolvedImage);
743 }
744
745 TextureRenderer::~TextureRenderer (void)
746 {
747 }
748
749 void TextureRenderer::clearImage(VkImage image)
750 {
751         const DeviceInterface&                  vkd                                     = m_context.getDeviceInterface();
752         const VkDevice                                  vkDevice                        = m_context.getDevice();
753         Move<VkCommandBuffer>                   commandBuffer;
754         const VkQueue                                   queue                           = m_context.getUniversalQueue();
755
756         const VkImageSubresourceRange   subResourcerange        =
757         {
758                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
759                 0,                                                              // deUint32                             baseMipLevel;
760                 1,                                                              // deUint32                             levelCount;
761                 0,                                                              // deUint32                             baseArrayLayer;
762                 1                                                               // deUint32                             layerCount;
763         };
764
765         commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
766
767         const VkCommandBufferBeginInfo          cmdBufferBeginInfo              =
768         {
769                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                                      sType;
770                 DE_NULL,                                                                                // const void*                                                          pNext;
771                 0u,                                                                                             // VkCmdBufferOptimizeFlags                                     flags;
772                 DE_NULL                                                                                 // const VkCommandBufferInheritanceInfo*        pInheritanceInfo;
773         };
774
775         VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
776
777         addImageTransitionBarrier(*commandBuffer, image,
778                                                           VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,                            // VkPipelineStageFlags         srcStageMask
779                                                           VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,                           // VkPipelineStageFlags         dstStageMask
780                                                           0,                                                                                            // VkAccessFlags                        srcAccessMask
781                                                           VK_ACCESS_TRANSFER_WRITE_BIT,                                         // VkAccessFlags                        dstAccessMask
782                                                           VK_IMAGE_LAYOUT_UNDEFINED,                                            // VkImageLayout                        oldLayout;
783                                                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);                        // VkImageLayout                        newLayout;
784
785         VkClearColorValue color = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color;
786         vkd.cmdClearColorImage(*commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subResourcerange);
787
788         addImageTransitionBarrier(*commandBuffer, image,
789                                                           VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,                            // VkPipelineStageFlags         srcStageMask
790                                                           VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,                           // VkPipelineStageFlags         dstStageMask
791                                                           VK_ACCESS_TRANSFER_WRITE_BIT,                                         // VkAccessFlags                        srcAccessMask
792                                                           VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                         // VkAccessFlags                        dstAccessMask
793                                                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                         // VkImageLayout                        oldLayout;
794                                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);            // VkImageLayout                        newLayout;
795
796         VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
797
798         const VkSubmitInfo                                      submitInfo                              =
799         {
800                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                              sType;
801                 DE_NULL,                                                                // const void*                                  pNext;
802                 0u,                                                                             // deUint32                                             waitSemaphoreCount;
803                 DE_NULL,                                                                // const VkSemaphore*                   pWaitSemaphores;
804                 DE_NULL,                                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
805                 1u,                                                                             // deUint32                                             commandBufferCount;
806                 &commandBuffer.get(),                                   // const VkCommandBuffer*               pCommandBuffers;
807                 0u,                                                                             // deUint32                                             signalSemaphoreCount;
808                 DE_NULL,                                                                // const VkSemaphore*                   pSignalSemaphores;
809         };
810
811         VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
812         VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
813         VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
814 }
815
816 void TextureRenderer::add2DTexture (const TestTexture2DSp& texture)
817 {
818         m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D)));
819 }
820
821 void TextureRenderer::addCubeTexture (const TestTextureCubeSp& texture)
822 {
823         m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_CUBE_MAP)));
824 }
825
826 void TextureRenderer::add2DArrayTexture (const TestTexture2DArraySp& texture)
827 {
828         m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D_ARRAY)));
829 }
830
831 void TextureRenderer::add3DTexture (const TestTexture3DSp& texture)
832 {
833         m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_3D)));
834 }
835
836 const pipeline::TestTexture2D& TextureRenderer::get2DTexture (int textureIndex) const
837 {
838         DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
839         DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D);
840
841         return dynamic_cast<const pipeline::TestTexture2D&>(m_textureBindings[textureIndex]->getTestTexture());
842 }
843
844 const pipeline::TestTextureCube& TextureRenderer::getCubeTexture (int textureIndex) const
845 {
846         DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
847         DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_CUBE_MAP);
848
849         return dynamic_cast<const pipeline::TestTextureCube&>(m_textureBindings[textureIndex]->getTestTexture());
850 }
851
852 const pipeline::TestTexture2DArray& TextureRenderer::get2DArrayTexture (int textureIndex) const
853 {
854         DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
855         DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D_ARRAY);
856
857         return dynamic_cast<const pipeline::TestTexture2DArray&>(m_textureBindings[textureIndex]->getTestTexture());
858 }
859
860 const pipeline::TestTexture3D& TextureRenderer::get3DTexture (int textureIndex) const
861 {
862         DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
863         DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_3D);
864
865         return dynamic_cast<const pipeline::TestTexture3D&>(m_textureBindings[textureIndex]->getTestTexture());
866 }
867
868 void TextureRenderer::setViewport (float viewportX, float viewportY, float viewportW, float viewportH)
869 {
870         m_viewportHeight = viewportH;
871         m_viewportWidth = viewportW;
872         m_viewportOffsetX = viewportX;
873         m_viewportOffsetY = viewportY;
874 }
875
876 TextureBinding* TextureRenderer::getTextureBinding (int textureIndex) const
877 {
878         DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
879         return m_textureBindings[textureIndex].get();
880 }
881
882 deUint32 TextureRenderer::getRenderWidth (void) const
883 {
884         return m_renderWidth;
885 }
886
887 deUint32 TextureRenderer::getRenderHeight (void) const
888 {
889         return m_renderHeight;
890 }
891
892 Move<VkDescriptorSet> TextureRenderer::makeDescriptorSet (const VkDescriptorPool descriptorPool, const VkDescriptorSetLayout setLayout) const
893 {
894         const DeviceInterface&                                          vkd                                             = m_context.getDeviceInterface();
895         const VkDevice                                                          vkDevice                                = m_context.getDevice();
896
897         const VkDescriptorSetAllocateInfo                       allocateParams                  =
898         {
899                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                                      sType
900                         DE_NULL,                                                                                        // const void*                                          pNext
901                         descriptorPool,                                                                         // VkDescriptorPool                                     descriptorPool
902                         1u,                                                                                                     // deUint32                                                     descriptorSetCount
903                         &setLayout,                                                                                     // const VkDescriptorSetLayout*         pSetLayouts
904         };
905         return allocateDescriptorSet(vkd, vkDevice, &allocateParams);
906 }
907
908 void TextureRenderer::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
909 {
910         const DeviceInterface&                  vkd                                     = m_context.getDeviceInterface();
911
912         const VkImageSubresourceRange   subResourcerange        =
913         {
914                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
915                 0,                                                              // deUint32                             baseMipLevel;
916                 1,                                                              // deUint32                             levelCount;
917                 0,                                                              // deUint32                             baseArrayLayer;
918                 1                                                               // deUint32                             layerCount;
919         };
920
921         const VkImageMemoryBarrier              imageBarrier            =
922         {
923                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
924                 DE_NULL,                                                                        // const void*                          pNext;
925                 srcAccessMask,                                                          // VkAccessFlags                        srcAccessMask;
926                 dstAccessMask,                                                          // VkAccessFlags                        dstAccessMask;
927                 oldLayout,                                                                      // VkImageLayout                        oldLayout;
928                 newLayout,                                                                      // VkImageLayout                        newLayout;
929                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
930                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     destQueueFamilyIndex;
931                 image,                                                                          // VkImage                                      image;
932                 subResourcerange                                                        // VkImageSubresourceRange      subresourceRange;
933         };
934
935         vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
936 }
937
938
939 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, TextureType texType)
940 {
941         renderQuad(result, texUnit, texCoord, ReferenceParams(texType));
942 }
943
944 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, const ReferenceParams& params)
945 {
946         const float     maxAnisotropy = 1.0f;
947         float           positions[]     =
948         {
949                 -1.0,   -1.0f,  0.0f,   1.0f,
950                 -1.0f,  +1.0f,  0.0f,   1.0f,
951                 +1.0f,  -1.0f,  0.0f,   1.0f,
952                 +1.0f,  +1.0f,  0.0f,   1.0f
953         };
954         renderQuad(result, positions, texUnit, texCoord, params, maxAnisotropy);
955 }
956
957 void TextureRenderer::renderQuad (tcu::Surface&                                                                 result,
958                                                                   const float*                                                                  positions,
959                                                                   int                                                                                   texUnit,
960                                                                   const float*                                                                  texCoord,
961                                                                   const glu::TextureTestUtil::ReferenceParams&  params,
962                                                                   const float                                                                   maxAnisotropy)
963 {
964         const DeviceInterface&          vkd                                             = m_context.getDeviceInterface();
965         const VkDevice                          vkDevice                                = m_context.getDevice();
966         const VkQueue                           queue                                   = m_context.getUniversalQueue();
967         const deUint32                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
968         Allocator&                                      allocator                               = m_context.getDefaultAllocator();
969
970         tcu::Vec4                                       wCoord                                  = params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
971         bool                                            useBias                                 = !!(params.flags & RenderParams::USE_BIAS);
972         bool                                            logUniforms                             = !!(params.flags & RenderParams::LOG_UNIFORMS);
973
974         // Render quad with texture.
975         float                                           position[]                              =
976         {
977                 positions[0]*wCoord.x(),        positions[1]*wCoord.x(),        positions[2],   positions[3]*wCoord.x(),
978                 positions[4]*wCoord.y(),        positions[5]*wCoord.y(),        positions[6],   positions[7]*wCoord.y(),
979                 positions[8]*wCoord.z(),        positions[9]*wCoord.z(),        positions[10],  positions[11]*wCoord.z(),
980                 positions[12]*wCoord.w(),       positions[13]*wCoord.w(),       positions[14],  positions[15]*wCoord.w()
981         };
982
983         Program                                         progSpec                                = PROGRAM_LAST;
984         int                                                     numComps                                = 0;
985
986         if (params.texType == TEXTURETYPE_2D)
987         {
988                 numComps = 2;
989
990                 switch (params.samplerType)
991                 {
992                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS      : PROGRAM_2D_FLOAT;             break;
993                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_2D_INT_BIAS        : PROGRAM_2D_INT;               break;
994                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_2D_UINT_BIAS       : PROGRAM_2D_UINT;              break;
995                         case SAMPLERTYPE_SHADOW:        progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS     : PROGRAM_2D_SHADOW;    break;
996                         default:                                        DE_ASSERT(false);
997                 }
998         }
999         else if (params.texType == TEXTURETYPE_1D)
1000         {
1001                 numComps = 1;
1002
1003                 switch (params.samplerType)
1004                 {
1005                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS      : PROGRAM_1D_FLOAT;             break;
1006                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_1D_INT_BIAS        : PROGRAM_1D_INT;               break;
1007                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_1D_UINT_BIAS       : PROGRAM_1D_UINT;              break;
1008                         case SAMPLERTYPE_SHADOW:        progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS     : PROGRAM_1D_SHADOW;    break;
1009                         default:                                        DE_ASSERT(false);
1010                 }
1011         }
1012         else if (params.texType == TEXTURETYPE_CUBE)
1013         {
1014                 numComps = 3;
1015
1016                 switch (params.samplerType)
1017                 {
1018                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS    : PROGRAM_CUBE_FLOAT;   break;
1019                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_CUBE_INT_BIAS              : PROGRAM_CUBE_INT;             break;
1020                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS             : PROGRAM_CUBE_UINT;    break;
1021                         case SAMPLERTYPE_SHADOW:        progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS   : PROGRAM_CUBE_SHADOW;  break;
1022                         default:                                        DE_ASSERT(false);
1023                 }
1024         }
1025         else if (params.texType == TEXTURETYPE_3D)
1026         {
1027                 numComps = 3;
1028
1029                 switch (params.samplerType)
1030                 {
1031                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS      : PROGRAM_3D_FLOAT;             break;
1032                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_3D_INT_BIAS        : PROGRAM_3D_INT;               break;
1033                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_3D_UINT_BIAS       : PROGRAM_3D_UINT;              break;
1034                         default:                                        DE_ASSERT(false);
1035                 }
1036         }
1037         else if (params.texType == TEXTURETYPE_2D_ARRAY)
1038         {
1039                 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
1040
1041                 numComps = 3;
1042
1043                 switch (params.samplerType)
1044                 {
1045                         case SAMPLERTYPE_FLOAT:         progSpec = PROGRAM_2D_ARRAY_FLOAT;      break;
1046                         case SAMPLERTYPE_INT:           progSpec = PROGRAM_2D_ARRAY_INT;        break;
1047                         case SAMPLERTYPE_UINT:          progSpec = PROGRAM_2D_ARRAY_UINT;       break;
1048                         case SAMPLERTYPE_SHADOW:        progSpec = PROGRAM_2D_ARRAY_SHADOW;     break;
1049                         default:                                        DE_ASSERT(false);
1050                 }
1051         }
1052         else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
1053         {
1054                 DE_ASSERT(!useBias);
1055
1056                 numComps = 4;
1057
1058                 switch (params.samplerType)
1059                 {
1060                         case SAMPLERTYPE_FLOAT:         progSpec = PROGRAM_CUBE_ARRAY_FLOAT;    break;
1061                         case SAMPLERTYPE_INT:           progSpec = PROGRAM_CUBE_ARRAY_INT;              break;
1062                         case SAMPLERTYPE_UINT:          progSpec = PROGRAM_CUBE_ARRAY_UINT;             break;
1063                         case SAMPLERTYPE_SHADOW:        progSpec = PROGRAM_CUBE_ARRAY_SHADOW;   break;
1064                         default:                                        DE_ASSERT(false);
1065                 }
1066         }
1067         else if (params.texType == TEXTURETYPE_1D_ARRAY)
1068         {
1069                 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
1070
1071                 numComps = 2;
1072
1073                 switch (params.samplerType)
1074                 {
1075                         case SAMPLERTYPE_FLOAT:         progSpec = PROGRAM_1D_ARRAY_FLOAT;      break;
1076                         case SAMPLERTYPE_INT:           progSpec = PROGRAM_1D_ARRAY_INT;        break;
1077                         case SAMPLERTYPE_UINT:          progSpec = PROGRAM_1D_ARRAY_UINT;       break;
1078                         case SAMPLERTYPE_SHADOW:        progSpec = PROGRAM_1D_ARRAY_SHADOW;     break;
1079                         default:                                        DE_ASSERT(false);
1080                 }
1081         }
1082         else if (params.texType == TEXTURETYPE_BUFFER)
1083         {
1084                 numComps = 1;
1085
1086                 switch (params.samplerType)
1087                 {
1088                         case SAMPLERTYPE_FETCH_FLOAT:   progSpec = PROGRAM_BUFFER_FLOAT;        break;
1089                         case SAMPLERTYPE_FETCH_INT:             progSpec = PROGRAM_BUFFER_INT;          break;
1090                         case SAMPLERTYPE_FETCH_UINT:    progSpec = PROGRAM_BUFFER_UINT;         break;
1091                         default:                                                DE_ASSERT(false);
1092                 }
1093         }
1094         else
1095                 DE_ASSERT(DE_FALSE);
1096
1097         Unique<VkShaderModule>                                  vertexShaderModule              (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_" + std::string(getProgramName(progSpec))), 0));
1098         Unique<VkShaderModule>                                  fragmentShaderModule    (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_" + std::string(getProgramName(progSpec))), 0));
1099
1100         Move<VkSampler>                                                 sampler;
1101         Move<VkDescriptorSet>                                   descriptorSet[2];
1102         Move<VkDescriptorSetLayout>                             descriptorSetLayout[2];
1103         Move<VkPipelineLayout>                                  pipelineLayout;
1104
1105         Move<VkCommandBuffer>                                   commandBuffer;
1106         Move<VkPipeline>                                                graphicsPipeline;
1107         Move<VkBuffer>                                                  vertexBuffer;
1108         de::MovePtr<Allocation>                                 vertexBufferMemory;
1109         const deUint32                                                  positionDataSize                = deUint32(sizeof(float) * 4 * 4);
1110         const deUint32                                                  textureCoordDataSize    = deUint32(sizeof(float) * numComps * 4);
1111
1112         const VkPhysicalDeviceProperties                properties                              = m_context.getDeviceProperties();
1113
1114         if (positionDataSize > properties.limits.maxVertexInputAttributeOffset)
1115         {
1116                 std::stringstream message;
1117                 message << "Larger vertex input attribute offset is needed (" << positionDataSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
1118                 TCU_THROW(NotSupportedError, message.str().c_str());
1119         }
1120
1121         // Create Graphics Pipeline
1122         {
1123                 const VkPipelineShaderStageCreateInfo   shaderStageParams[2]    =
1124                 {
1125                         {
1126                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                      sType;
1127                                 DE_NULL,                                                                                                        // const void*                                          pNext;
1128                                 0,                                                                                                                      // VkPipelineShaderStageCreateFlags flags;
1129                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStage                                        stage;
1130                                 *vertexShaderModule,                                                                            // VkShaderModule                                       shader;
1131                                 "main",                                                                                                         // const char*                                          pName;
1132                                 DE_NULL                                                                                                         // const VkSpecializationInfo*          pSpecializationInfo;
1133                         },
1134                         {
1135                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                      sType;
1136                                 DE_NULL,                                                                                                        // const void*                                          pNext;
1137                                 0,                                                                                                                      // VkPipelineShaderStageCreateFlags flags;
1138                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStage                                        stage;
1139                                 *fragmentShaderModule,                                                                          // VkShaderModule                                       shader;
1140                                 "main",                                                                                                         // const char*                                          pName;
1141                                 DE_NULL                                                                                                         // const VkSpecializationInfo*          pSpecializationInfo;
1142                         }
1143                 };
1144
1145                 const deUint32                                                  vertexPositionStrideSize                        = deUint32(sizeof(tcu::Vec4));
1146                 const deUint32                                                  vertexTextureStrideSize                         = deUint32(numComps * sizeof(float));
1147
1148                 const VkVertexInputBindingDescription   vertexInputBindingDescription[2]        =
1149                 {
1150                         {
1151                                 0u,                                                             // deUint32                                     binding;
1152                                 vertexPositionStrideSize,               // deUint32                                     strideInBytes;
1153                                 VK_VERTEX_INPUT_RATE_VERTEX             // VkVertexInputStepRate        stepRate;
1154                         },
1155                         {
1156                                 1u,                                                             // deUint32                                     binding;
1157                                 vertexTextureStrideSize,                // deUint32                                     strideInBytes;
1158                                 VK_VERTEX_INPUT_RATE_VERTEX             // VkVertexInputStepRate        stepRate;
1159                         }
1160                 };
1161
1162                 VkFormat                                                                textureCoordinateFormat                 = VK_FORMAT_R32G32B32A32_SFLOAT;
1163
1164                 switch (numComps) {
1165                         case 1: textureCoordinateFormat = VK_FORMAT_R32_SFLOAT;                         break;
1166                         case 2: textureCoordinateFormat = VK_FORMAT_R32G32_SFLOAT;                      break;
1167                         case 3: textureCoordinateFormat = VK_FORMAT_R32G32B32_SFLOAT;           break;
1168                         case 4: textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT;        break;
1169                         default:
1170                                 DE_ASSERT(false);
1171                 }
1172
1173                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1174                 {
1175                         {
1176                                 0u,                                                                     // deUint32     location;
1177                                 0u,                                                                     // deUint32     binding;
1178                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
1179                                 0u                                                                      // deUint32     offsetInBytes;
1180                         },
1181                         {
1182                                 1u,                                                                     // deUint32     location;
1183                                 1u,                                                                     // deUint32     binding;
1184                                 textureCoordinateFormat,                        // VkFormat     format;
1185                                 positionDataSize                                        // deUint32     offsetInBytes;
1186                         }
1187                 };
1188
1189                 const VkPipelineVertexInputStateCreateInfo      vertexInputStateParams =
1190                 {
1191                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
1192                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1193                         0,                                                                                                                              // VkPipelineVertexInputStateCreateFlags        flags;
1194                         2u,                                                                                                                             // deUint32                                                                     bindingCount;
1195                         vertexInputBindingDescription,                                                                  // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
1196                         2u,                                                                                                                             // deUint32                                                                     attributeCount;
1197                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
1198                 };
1199
1200                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams =
1201                 {
1202                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
1203                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1204                         0,                                                                                                                              // VkPipelineInputAssemblyStateCreateFlags      flags;
1205                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
1206                         VK_FALSE                                                                                                                // VkBool32                                                                     primitiveRestartEnable;
1207                 };
1208
1209                 const VkViewport                                                viewport =
1210                 {
1211                         m_viewportOffsetX,                      // float        originX;
1212                         m_viewportOffsetY,                      // float        originY;
1213                         m_viewportWidth,                        // float        width;
1214                         m_viewportHeight,                       // float        height;
1215                         0.0f,                                           // float        minDepth;
1216                         1.0f                                            // float        maxDepth;
1217                 };
1218
1219                 const VkRect2D                                                  scissor =
1220                 {
1221                         { 0, 0 },                                                                                                               // VkOffset2D  offset;
1222                         { m_renderWidth, m_renderHeight }                                                               // VkExtent2D  extent;
1223                 };
1224
1225                 const VkPipelineViewportStateCreateInfo viewportStateParams =
1226                 {
1227                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
1228                         DE_NULL,                                                                                                                // const void*                                                  pNext;
1229                         0,                                                                                                                              // VkPipelineViewportStateCreateFlags   flags;
1230                         1u,                                                                                                                             // deUint32                                                             viewportCount;
1231                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
1232                         1u,                                                                                                                             // deUint32                                                             scissorCount;
1233                         &scissor                                                                                                                // const VkRect2D*                                              pScissors;
1234                 };
1235
1236                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1237                 {
1238                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
1239                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1240                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
1241                         m_sampleCount,                                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
1242                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
1243                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
1244                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
1245                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
1246                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
1247                 };
1248
1249                 const VkPipelineRasterizationStateCreateInfo    rasterizationStateCreateInfo    =
1250                 {
1251                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
1252                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1253                         0,                                                                                                                              // VkPipelineRasterizationStateCreateFlags      flags;
1254                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthClipEnable;
1255                         VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
1256                         VK_POLYGON_MODE_FILL,                                                                                   // VkFillMode                                                           fillMode;
1257                         VK_CULL_MODE_NONE,                                                                                              // VkCullMode                                                           cullMode;
1258                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
1259                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
1260                         0.0f,                                                                                                                   // float                                                                        depthBias;
1261                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
1262                         0.0f,                                                                                                                   // float                                                                        slopeScaledDepthBias;
1263                         1.0f,                                                                                                                   // float                                                                        lineWidth;
1264                 };
1265
1266                 const VkPipelineColorBlendAttachmentState       colorBlendAttachmentState       =
1267                 {
1268                         VK_FALSE,                                                                                                       // VkBool32                     blendEnable;
1269                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendColor;
1270                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendColor;
1271                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpColor;
1272                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendAlpha;
1273                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendAlpha;
1274                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpAlpha;
1275                         (VK_COLOR_COMPONENT_R_BIT |
1276                          VK_COLOR_COMPONENT_G_BIT |
1277                          VK_COLOR_COMPONENT_B_BIT |
1278                          VK_COLOR_COMPONENT_A_BIT)                                                                      // VkChannelFlags       channelWriteMask;
1279                 };
1280
1281                 const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams           =
1282                 {
1283                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
1284                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
1285                         0,                                                                                                                      // VkPipelineColorBlendStateCreateFlags                 flags;
1286                         VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
1287                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
1288                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
1289                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
1290                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
1291                 };
1292
1293                 VkSamplerCreateInfo                                     samplerCreateInfo                       = mapSampler(params.sampler, m_textureBindings[texUnit]->getTestTexture().getTextureFormat(), params.minLod, params.maxLod);
1294
1295                 if (maxAnisotropy > 1.0f)
1296                 {
1297                         samplerCreateInfo.anisotropyEnable = VK_TRUE;
1298                         samplerCreateInfo.maxAnisotropy = maxAnisotropy;
1299                 }
1300
1301                 if (samplerCreateInfo.magFilter == VK_FILTER_LINEAR || samplerCreateInfo.minFilter == VK_FILTER_LINEAR || samplerCreateInfo.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR)
1302                 {
1303                         const pipeline::TestTexture&    testTexture                     = m_textureBindings[texUnit]->getTestTexture();
1304                         const VkFormat                                  textureFormat           = testTexture.isCompressed() ? mapCompressedTextureFormat(testTexture.getCompressedLevel(0, 0).getFormat())
1305                                                                                                                                                                                          : mapTextureFormat          (testTexture.getTextureFormat());
1306                         const VkFormatProperties                formatProperties        = getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), textureFormat);
1307
1308                         if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1309                                 TCU_THROW(NotSupportedError, "Linear filtering for this image format is not supported");
1310                 }
1311
1312                 sampler = createSampler(vkd, vkDevice, &samplerCreateInfo);
1313
1314                 descriptorSetLayout[0] = DescriptorSetLayoutBuilder()
1315                                                                                         .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
1316                                                                                                 .build(vkd, vkDevice);
1317
1318                 descriptorSetLayout[1] = DescriptorSetLayoutBuilder()
1319                                                                                         .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
1320                                                                                         .build(vkd, vkDevice);
1321
1322
1323                 descriptorSet[0] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[0]);
1324                 descriptorSet[1] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[1]);
1325
1326                 {
1327                         const VkDescriptorBufferInfo                    descriptorBufferInfo    =
1328                         {
1329                                 *m_uniformBuffer,                                                       // VkBuffer             buffer;
1330                                 0u,                                                                                     // VkDeviceSize offset;
1331                                 VK_WHOLE_SIZE                                                           // VkDeviceSize range;
1332                         };
1333
1334                         DescriptorSetUpdateBuilder()
1335                                 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorBufferInfo)
1336                                 .update(vkd, vkDevice);
1337                 }
1338
1339                 {
1340                         VkDescriptorImageInfo                                   descriptorImageInfo             =
1341                         {
1342                                 *sampler,                                                                               // VkSampler            sampler;
1343                                 m_textureBindings[texUnit]->getImageView(),             // VkImageView          imageView;
1344                                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL                // VkImageLayout        imageLayout;
1345                         };
1346
1347                         DescriptorSetUpdateBuilder()
1348                                 .writeSingle(*descriptorSet[1], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo)
1349                                 .update(vkd, vkDevice);
1350                 }
1351
1352                 // Pipeline Layout
1353                 {
1354                         VkDescriptorSetLayout                                   descriptorSetLayouts[2]         =
1355                         {
1356                                 *descriptorSetLayout[0],
1357                                 *descriptorSetLayout[1]
1358                         };
1359
1360                         const VkPipelineLayoutCreateInfo                pipelineLayoutCreateInfo        =
1361                         {
1362                                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
1363                                 DE_NULL,                                                                                        // const void*                                  pNext;
1364                                 0u,                                                                                                     // VkPipelineLayoutCreateFlags  flags;
1365                                 2u,                                                                                                     // deUint32                                             descriptorSetCount;
1366                                 descriptorSetLayouts,                                                           // const VkDescriptorSetLayout* pSetLayouts;
1367                                 0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
1368                                 DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
1369                         };
1370
1371                         pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
1372                 }
1373
1374                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1375                 {
1376                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
1377                         DE_NULL,                                                                                        // const void*                                                                          pNext;
1378                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
1379                         2u,                                                                                                     // deUint32                                                                                     stageCount;
1380                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
1381                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1382                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1383                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1384                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1385                         &rasterizationStateCreateInfo,                                          // const VkPipelineRasterStateCreateInfo*                       pRasterizationState;
1386                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1387                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1388                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1389                         DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1390                         *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
1391                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
1392                         0u,                                                                                                     // deUint32                                                                                     subpass;
1393                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
1394                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
1395                 };
1396
1397                 graphicsPipeline                = createGraphicsPipeline(vkd, vkDevice, DE_NULL, &graphicsPipelineParams);
1398         }
1399
1400         // Create Vertex Buffer
1401         {
1402                 const VkBufferCreateInfo                        vertexBufferParams              =
1403                 {
1404                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1405                         DE_NULL,                                                                        // const void*                  pNext;
1406                         0u,                                                                                     // VkBufferCreateFlags  flags;
1407                         positionDataSize + textureCoordDataSize,        // VkDeviceSize                 size;
1408                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
1409                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1410                         1u,                                                                                     // deUint32                             queueFamilyCount;
1411                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1412                 };
1413
1414                 vertexBuffer            = createBuffer(vkd, vkDevice, &vertexBufferParams);
1415                 vertexBufferMemory      = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
1416
1417                 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
1418
1419                 // Load vertices into vertex buffer
1420                 deMemcpy(vertexBufferMemory->getHostPtr(), position, positionDataSize);
1421                 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) +  positionDataSize, texCoord, textureCoordDataSize);
1422                 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), VK_WHOLE_SIZE);
1423         }
1424
1425         // Create Command Buffer
1426         commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1427
1428         // Begin Command Buffer
1429         {
1430                 const VkCommandBufferBeginInfo          cmdBufferBeginInfo              =
1431                 {
1432                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                                      sType;
1433                         DE_NULL,                                                                                // const void*                                                          pNext;
1434                         0u,                                                                                             // VkCmdBufferOptimizeFlags                                     flags;
1435                         DE_NULL                                                                                 // const VkCommandBufferInheritanceInfo*        pInheritanceInfo;
1436                 };
1437
1438                 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
1439         }
1440
1441         // Begin Render Pass
1442         {
1443                 const VkRenderPassBeginInfo                     renderPassBeginInfo             =
1444                 {
1445                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
1446                         DE_NULL,                                                                                                // const void*                  pNext;
1447                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
1448                         *m_frameBuffer,                                                                                 // VkFramebuffer                framebuffer;
1449                         {
1450                                 { 0, 0 },
1451                                 { m_renderWidth, m_renderHeight }
1452                         },                                                                                                              // VkRect2D                             renderArea;
1453                         0u,                                                                                                             // deUint32                             clearValueCount;
1454                         DE_NULL                                                                                                 // const VkClearValue*  pClearValues;
1455                 };
1456
1457                 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1458         }
1459
1460         const VkDeviceSize                                              vertexBufferOffset              = 0;
1461
1462         vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1463         vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &descriptorSet[0].get(), 0u, DE_NULL);
1464         vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 1u, 1, &descriptorSet[1].get(), 0u, DE_NULL);
1465         vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
1466         vkd.cmdBindVertexBuffers(*commandBuffer, 1, 1, &vertexBuffer.get(), &vertexBufferOffset);
1467         vkd.cmdBindIndexBuffer(*commandBuffer, *m_vertexIndexBuffer, 0, VK_INDEX_TYPE_UINT16);
1468         vkd.cmdDrawIndexed(*commandBuffer, 6, 1, 0, 0, 0);
1469         vkd.cmdEndRenderPass(*commandBuffer);
1470
1471         // Copy Image
1472         {
1473                 const VkBufferMemoryBarrier                     bufferBarrier                   =
1474                 {
1475                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType              sType;
1476                         DE_NULL,                                                                        // const void*                  pNext;
1477                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkMemoryOutputFlags  outputMask;
1478                         VK_ACCESS_HOST_READ_BIT,                                        // VkMemoryInputFlags   inputMask;
1479                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                             srcQueueFamilyIndex;
1480                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                             destQueueFamilyIndex;
1481                         *m_resultBuffer,                                                        // VkBuffer                             buffer;
1482                         0u,                                                                                     // VkDeviceSize                 offset;
1483                         m_resultBufferSize                                                      // VkDeviceSize                 size;
1484                 };
1485
1486                 const VkBufferImageCopy                         copyRegion                              =
1487                 {
1488                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
1489                         m_renderWidth,                                                          // deUint32                                     bufferRowLength;
1490                         m_renderHeight,                                                         // deUint32                                     bufferImageHeight;
1491                         {
1492                                 VK_IMAGE_ASPECT_COLOR_BIT,
1493                                 0u,
1494                                 0u,
1495                                 1u
1496                         },                                                                                      // VkImageSubresourceCopy       imageSubresource;
1497                         { 0, 0, 0 },                                                            // VkOffset3D                           imageOffset;
1498                         { m_renderWidth, m_renderHeight, 1u }           // VkExtent3D                           imageExtent;
1499                 };
1500
1501                 addImageTransitionBarrier(*commandBuffer,
1502                                                                   m_multisampling ? *m_resolvedImage : *m_image,
1503                                                                   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,                // VkPipelineStageFlags         srcStageMask
1504                                                                   VK_PIPELINE_STAGE_TRANSFER_BIT,                                               // VkPipelineStageFlags         dstStageMask
1505                                                                   VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                 // VkAccessFlags                        srcAccessMask
1506                                                                   VK_ACCESS_TRANSFER_READ_BIT,                                                  // VkAccessFlags                        dstAccessMask
1507                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                             // VkImageLayout                        oldLayout;
1508                                                                   VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);                                // VkImageLayout                        newLayout;
1509
1510                 if (m_multisampling)
1511                         vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, &copyRegion);
1512                 else
1513                         vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, &copyRegion);
1514
1515                 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1516
1517                 addImageTransitionBarrier(*commandBuffer,
1518                                                                   m_multisampling ? *m_resolvedImage : *m_image,
1519                                                                   VK_PIPELINE_STAGE_TRANSFER_BIT,                                       // VkPipelineStageFlags         srcStageMask
1520                                                                   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,        // VkPipelineStageFlags         dstStageMask
1521                                                                   VK_ACCESS_TRANSFER_READ_BIT,                                          // VkAccessFlags                        srcAccessMask
1522                                                                   VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                         // VkAccessFlags                        dstAccessMask
1523                                                                   VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                         // VkImageLayout                        oldLayout;
1524                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);            // VkImageLayout                        newLayout;
1525         }
1526
1527         VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
1528
1529         // Upload uniform buffer data
1530         {
1531                 const ShaderParameters  shaderParameters        =
1532                 {
1533                         params.bias,                    // float                bias;                           //!< User-supplied bias.
1534                         params.ref,                             // float                ref;                            //!< Reference value for shadow lookups.
1535                         tcu::Vec2(),                    // tcu::Vec2    padding;                        //!< Shader uniform padding.
1536                         params.colorScale,              // tcu::Vec4    colorScale;                     //!< Scale for texture color values.
1537                         params.colorBias                // tcu::Vec4    colorBias;                      //!< Bias for texture color values.
1538                 };
1539                 deMemcpy(m_uniformBufferMemory->getHostPtr(), &shaderParameters, sizeof(shaderParameters));
1540                 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), VK_WHOLE_SIZE);
1541
1542                 if (logUniforms)
1543                         m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
1544
1545                 if (useBias)
1546                 {
1547                         if (logUniforms)
1548                                 m_log << TestLog::Message << "u_bias = " << shaderParameters.bias << TestLog::EndMessage;
1549                 }
1550
1551                 if (params.samplerType == SAMPLERTYPE_SHADOW)
1552                 {
1553                         if (logUniforms)
1554                                 m_log << TestLog::Message << "u_ref = " << shaderParameters.ref << TestLog::EndMessage;
1555                 }
1556
1557                 if (logUniforms)
1558                 {
1559                         m_log << TestLog::Message << "u_colorScale = " << shaderParameters.colorScale << TestLog::EndMessage;
1560                         m_log << TestLog::Message << "u_colorBias = " << shaderParameters.colorBias << TestLog::EndMessage;
1561                 }
1562         }
1563
1564         // Submit
1565         {
1566                 const VkSubmitInfo                                      submitInfo                              =
1567                 {
1568                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                              sType;
1569                         DE_NULL,                                                                // const void*                                  pNext;
1570                         0u,                                                                             // deUint32                                             waitSemaphoreCount;
1571                         DE_NULL,                                                                // const VkSemaphore*                   pWaitSemaphores;
1572                         DE_NULL,                                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
1573                         1u,                                                                             // deUint32                                             commandBufferCount;
1574                         &commandBuffer.get(),                                   // const VkCommandBuffer*               pCommandBuffers;
1575                         0u,                                                                             // deUint32                                             signalSemaphoreCount;
1576                         DE_NULL,                                                                // const VkSemaphore*                   pSignalSemaphores;
1577                 };
1578
1579                 VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
1580                 VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
1581                 VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1582         }
1583
1584         invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
1585
1586         tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderWidth, m_renderHeight, 1u), m_resultBufferMemory->getHostPtr()));
1587 }
1588
1589 /*--------------------------------------------------------------------*//*!
1590  * \brief Map Vulkan sampler parameters to tcu::Sampler.
1591  *
1592  * If no mapping is found, throws tcu::InternalError.
1593  *
1594  * \param wrapU                 U-component wrap mode
1595  * \param wrapV                 V-component wrap mode
1596  * \param wrapW                 W-component wrap mode
1597  * \param minFilterMode Minification filter mode
1598  * \param magFilterMode Magnification filter mode
1599  * \return Sampler description.
1600  *//*--------------------------------------------------------------------*/
1601 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::WrapMode wrapW, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
1602 {
1603         return tcu::Sampler(wrapU, wrapV, wrapW,
1604                                                 minFilterMode, magFilterMode,
1605                                                 0.0f /* lod threshold */,
1606                                                 true /* normalized coords */,
1607                                                 tcu::Sampler::COMPAREMODE_NONE /* no compare */,
1608                                                 0 /* compare channel */,
1609                                                 tcu::Vec4(0.0f) /* border color, not used */);
1610 }
1611
1612 /*--------------------------------------------------------------------*//*!
1613  * \brief Map Vulkan sampler parameters to tcu::Sampler.
1614  *
1615  * If no mapping is found, throws tcu::InternalError.
1616  *
1617  * \param wrapU                 U-component wrap mode
1618  * \param wrapV                 V-component wrap mode
1619  * \param minFilterMode Minification filter mode
1620  * \param minFilterMode Magnification filter mode
1621  * \return Sampler description.
1622  *//*--------------------------------------------------------------------*/
1623 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
1624 {
1625         return createSampler(wrapU, wrapV, wrapU, minFilterMode, magFilterMode);
1626 }
1627
1628 /*--------------------------------------------------------------------*//*!
1629  * \brief Map Vulkan sampler parameters to tcu::Sampler.
1630  *
1631  * If no mapping is found, throws tcu::InternalError.
1632  *
1633  * \param wrapU                 U-component wrap mode
1634  * \param minFilterMode Minification filter mode
1635  * \return Sampler description.
1636  *//*--------------------------------------------------------------------*/
1637 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode)
1638 {
1639         return createSampler(wrapU, wrapU, wrapU, minFilterMode, magFilterMode);
1640 }
1641
1642 TestTexture2DSp loadTexture2D (const tcu::Archive& archive, const std::vector<std::string>& filenames)
1643 {
1644         DE_ASSERT(filenames.size() > 0);
1645
1646         TestTexture2DSp texture;
1647
1648         std::string ext = de::FilePath(filenames[0]).getFileExtension();
1649
1650         if (ext == "png")
1651         {
1652
1653                 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1654                 {
1655                         tcu::TextureLevel level;
1656
1657                         tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
1658
1659                         TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
1660                                                                                            level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
1661
1662                         if (fileIndex == 0)
1663                                 texture = TestTexture2DSp(new pipeline::TestTexture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
1664
1665                         tcu::copy(texture->getLevel((int)fileIndex, 0), level.getAccess());
1666                 }
1667         }
1668         else if (ext == "pkm")
1669         {
1670
1671                 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1672                 {
1673                         // Compressed texture.
1674                         tcu::CompressedTexture  level;
1675
1676                         tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
1677
1678                         tcu::TextureFormat              uncompressedFormat              = tcu::getUncompressedFormat(level.getFormat());
1679                         std::vector<deUint8>    uncompressedData                (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1680                         tcu::PixelBufferAccess  decompressedBuffer              (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data());
1681
1682                         tcu::TextureFormat              commonFormat                    = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1683                         std::vector<deUint8>    commonFromatData                (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1684                         tcu::PixelBufferAccess  commonFormatBuffer              (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data());
1685
1686                         if (fileIndex == 0)
1687                                 texture = TestTexture2DSp(new pipeline::TestTexture2D(commonFormat, level.getWidth(), level.getHeight()));
1688
1689                         level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
1690
1691                         tcu::copy(commonFormatBuffer, decompressedBuffer);
1692                         tcu::copy(texture->getLevel((int)fileIndex, 0), commonFormatBuffer);
1693                 }
1694         }
1695         else
1696                 TCU_FAIL("Unsupported file format");
1697
1698         return texture;
1699 }
1700
1701 TestTextureCubeSp loadTextureCube (const tcu::Archive& archive, const std::vector<std::string>& filenames)
1702 {
1703         DE_ASSERT(filenames.size() > 0);
1704         DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
1705         TCU_CHECK((int)filenames.size() % tcu::CUBEFACE_LAST == 0);
1706
1707         TestTextureCubeSp texture;
1708
1709         std::string ext = de::FilePath(filenames[0]).getFileExtension();
1710
1711         if (ext == "png")
1712         {
1713
1714                 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1715                 {
1716                         tcu::TextureLevel level;
1717
1718                         tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
1719
1720                         TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
1721                                                                                            level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
1722
1723                         TCU_CHECK( level.getWidth() == level.getHeight());
1724
1725                         if (fileIndex == 0)
1726                                 texture = TestTextureCubeSp(new pipeline::TestTextureCube(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth()));
1727
1728                         tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), level.getAccess());
1729                 }
1730         }
1731         else if (ext == "pkm")
1732         {
1733                 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1734                 {
1735                         // Compressed texture.
1736                         tcu::CompressedTexture  level;
1737
1738                         tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
1739
1740                         TCU_CHECK( level.getWidth() == level.getHeight());
1741
1742                         tcu::TextureFormat              uncompressedFormat                              = tcu::getUncompressedFormat(level.getFormat());
1743                         std::vector<deUint8>    uncompressedData                                (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1744                         tcu::PixelBufferAccess  decompressedBuffer                              (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data());
1745
1746                         tcu::TextureFormat              commonFormat                                    = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
1747                         std::vector<deUint8>    commonFromatData                                (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
1748                         tcu::PixelBufferAccess  commonFormatBuffer                              (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data());
1749
1750                         if (fileIndex == 0)
1751                                 texture = TestTextureCubeSp(new pipeline::TestTextureCube(commonFormat, level.getWidth()));
1752
1753                         level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
1754
1755                         tcu::copy(commonFormatBuffer, decompressedBuffer);
1756                         tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), commonFormatBuffer);
1757                 }
1758         }
1759         else
1760                 TCU_FAIL("Unsupported file format");
1761
1762         return texture;
1763 }
1764
1765 TextureCommonTestCaseParameters::TextureCommonTestCaseParameters (void)
1766         : sampleCount                   (VK_SAMPLE_COUNT_1_BIT)
1767         , texCoordPrecision             (glu::PRECISION_HIGHP)
1768         , minFilter                             (tcu::Sampler::LINEAR)
1769         , magFilter                             (tcu::Sampler::LINEAR)
1770         , wrapS                                 (tcu::Sampler::REPEAT_GL)
1771         , wrapT                                 (tcu::Sampler::REPEAT_GL)
1772         , format                                (VK_FORMAT_R8G8B8A8_UNORM)
1773 {
1774 }
1775
1776 Texture2DTestCaseParameters::Texture2DTestCaseParameters (void)
1777         : width                                 (64)
1778         , height                                (64)
1779 {
1780 }
1781
1782 TextureCubeTestCaseParameters::TextureCubeTestCaseParameters (void)
1783         : size                                  (64)
1784 {
1785 }
1786
1787 Texture2DArrayTestCaseParameters::Texture2DArrayTestCaseParameters (void)
1788         : numLayers                             (8)
1789 {
1790 }
1791
1792 Texture3DTestCaseParameters::Texture3DTestCaseParameters (void)
1793         : wrapR                                 (tcu::Sampler::REPEAT_GL)
1794         , depth                                 (64)
1795 {
1796 }
1797
1798 } // util
1799 } // texture
1800 } // vkt