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