xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include <map>
44 #include <string>
45 #include <vector>
46 #include <set>
47 #include "vktCustomInstancesDevices.hpp"
48 #include "tcuCommandLine.hpp"
49 
50 using tcu::TestLog;
51 
52 using namespace vk;
53 using namespace glu::TextureTestUtil;
54 
55 namespace vkt
56 {
57 namespace texture
58 {
59 namespace util
60 {
61 
62 struct ShaderParameters
63 {
64     float bias;           //!< User-supplied bias.
65     float ref;            //!< Reference value for shadow lookups.
66     tcu::Vec2 padding;    //!< Shader uniform padding.
67     tcu::Vec4 colorScale; //!< Scale for texture color values.
68     tcu::Vec4 colorBias;  //!< Bias for texture color values.
69     int lod;              //!< Lod (for usage in Integer Texel Coord tests for VK_EXT_image_view_min_lod)
70 };
71 
getProgramName(Program program)72 const char *getProgramName(Program program)
73 {
74     switch (program)
75     {
76     case PROGRAM_2D_FLOAT:
77         return "2D_FLOAT";
78     case PROGRAM_2D_INT:
79         return "2D_INT";
80     case PROGRAM_2D_UINT:
81         return "2D_UINT";
82     case PROGRAM_2D_FETCH_LOD:
83         return "2D_FETCH_LOD";
84     case PROGRAM_2D_SHADOW:
85         return "2D_SHADOW";
86     case PROGRAM_2D_FLOAT_BIAS:
87         return "2D_FLOAT_BIAS";
88     case PROGRAM_2D_INT_BIAS:
89         return "2D_INT_BIAS";
90     case PROGRAM_2D_UINT_BIAS:
91         return "2D_UINT_BIAS";
92     case PROGRAM_2D_SHADOW_BIAS:
93         return "2D_SHADOW_BIAS";
94     case PROGRAM_1D_FLOAT:
95         return "1D_FLOAT";
96     case PROGRAM_1D_INT:
97         return "1D_INT";
98     case PROGRAM_1D_UINT:
99         return "1D_UINT";
100     case PROGRAM_1D_SHADOW:
101         return "1D_SHADOW";
102     case PROGRAM_1D_FLOAT_BIAS:
103         return "1D_FLOAT_BIAS";
104     case PROGRAM_1D_INT_BIAS:
105         return "1D_INT_BIAS";
106     case PROGRAM_1D_UINT_BIAS:
107         return "1D_UINT_BIAS";
108     case PROGRAM_1D_SHADOW_BIAS:
109         return "1D_SHADOW_BIAS";
110     case PROGRAM_CUBE_FLOAT:
111         return "CUBE_FLOAT";
112     case PROGRAM_CUBE_INT:
113         return "CUBE_INT";
114     case PROGRAM_CUBE_UINT:
115         return "CUBE_UINT";
116     case PROGRAM_CUBE_SHADOW:
117         return "CUBE_SHADOW";
118     case PROGRAM_CUBE_FLOAT_BIAS:
119         return "CUBE_FLOAT_BIAS";
120     case PROGRAM_CUBE_INT_BIAS:
121         return "CUBE_INT_BIAS";
122     case PROGRAM_CUBE_UINT_BIAS:
123         return "CUBE_UINT_BIAS";
124     case PROGRAM_CUBE_SHADOW_BIAS:
125         return "CUBE_SHADOW_BIAS";
126     case PROGRAM_2D_ARRAY_FLOAT:
127         return "2D_ARRAY_FLOAT";
128     case PROGRAM_2D_ARRAY_INT:
129         return "2D_ARRAY_INT";
130     case PROGRAM_2D_ARRAY_UINT:
131         return "2D_ARRAY_UINT";
132     case PROGRAM_2D_ARRAY_SHADOW:
133         return "2D_ARRAY_SHADOW";
134     case PROGRAM_3D_FLOAT:
135         return "3D_FLOAT";
136     case PROGRAM_3D_INT:
137         return "3D_INT";
138     case PROGRAM_3D_UINT:
139         return "3D_UINT";
140     case PROGRAM_3D_FETCH_LOD:
141         return "3D_FETCH_LOD";
142     case PROGRAM_3D_FLOAT_BIAS:
143         return "3D_FLOAT_BIAS";
144     case PROGRAM_3D_INT_BIAS:
145         return "3D_INT_BIAS";
146     case PROGRAM_3D_UINT_BIAS:
147         return "3D_UINT_BIAS";
148     case PROGRAM_CUBE_ARRAY_FLOAT:
149         return "CUBE_ARRAY_FLOAT";
150     case PROGRAM_CUBE_ARRAY_INT:
151         return "CUBE_ARRAY_INT";
152     case PROGRAM_CUBE_ARRAY_UINT:
153         return "CUBE_ARRAY_UINT";
154     case PROGRAM_CUBE_ARRAY_SHADOW:
155         return "CUBE_ARRAY_SHADOW";
156     case PROGRAM_1D_ARRAY_FLOAT:
157         return "1D_ARRAY_FLOAT";
158     case PROGRAM_1D_ARRAY_INT:
159         return "1D_ARRAY_INT";
160     case PROGRAM_1D_ARRAY_UINT:
161         return "1D_ARRAY_UINT";
162     case PROGRAM_1D_ARRAY_SHADOW:
163         return "1D_ARRAY_SHADOW";
164     case PROGRAM_BUFFER_FLOAT:
165         return "BUFFER_FLOAT";
166     case PROGRAM_BUFFER_INT:
167         return "BUFFER_INT";
168     case PROGRAM_BUFFER_UINT:
169         return "BUFFER_UINT";
170     default:
171         DE_ASSERT(false);
172     }
173     return NULL;
174 }
175 
textureTypeToImageViewType(TextureBinding::Type type)176 VkImageViewType textureTypeToImageViewType(TextureBinding::Type type)
177 {
178     switch (type)
179     {
180     case TextureBinding::TYPE_2D:
181         return VK_IMAGE_VIEW_TYPE_2D;
182     case TextureBinding::TYPE_2D_ARRAY:
183         return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
184     case TextureBinding::TYPE_CUBE_MAP:
185         return VK_IMAGE_VIEW_TYPE_CUBE;
186     case TextureBinding::TYPE_3D:
187         return VK_IMAGE_VIEW_TYPE_3D;
188     case TextureBinding::TYPE_1D:
189         return VK_IMAGE_VIEW_TYPE_1D;
190     case TextureBinding::TYPE_1D_ARRAY:
191         return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
192     case TextureBinding::TYPE_CUBE_ARRAY:
193         return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
194     default:
195         TCU_THROW(InternalError, "Unhandled TextureBinding");
196     }
197 }
198 
imageViewTypeToImageType(VkImageViewType type)199 VkImageType imageViewTypeToImageType(VkImageViewType type)
200 {
201     switch (type)
202     {
203     case VK_IMAGE_VIEW_TYPE_2D:
204     case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
205     case VK_IMAGE_VIEW_TYPE_CUBE:
206         return VK_IMAGE_TYPE_2D;
207     case VK_IMAGE_VIEW_TYPE_3D:
208         return VK_IMAGE_TYPE_3D;
209     case VK_IMAGE_VIEW_TYPE_1D:
210     case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
211         return VK_IMAGE_TYPE_1D;
212     case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
213         return VK_IMAGE_TYPE_2D;
214     default:
215         TCU_THROW(InternalError, "Unhandled ImageViewType");
216     }
217 }
218 
initializePrograms(vk::SourceCollections & programCollection,glu::Precision texCoordPrecision,const std::vector<Program> & programs,const char * texCoordSwizzle,glu::Precision fragOutputPrecision,bool unnormal)219 void initializePrograms(vk::SourceCollections &programCollection, glu::Precision texCoordPrecision,
220                         const std::vector<Program> &programs, const char *texCoordSwizzle,
221                         glu::Precision fragOutputPrecision, bool unnormal)
222 {
223     static const char *vertShaderTemplate =
224         "${VTX_HEADER}"
225         "layout(location = 0) ${VTX_IN} highp vec4 a_position;\n"
226         "layout(location = 1) ${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n"
227         "layout(location = 0) ${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
228         "${VTX_OUT} gl_PerVertex { vec4 gl_Position; };\n"
229         "\n"
230         "void main (void)\n"
231         "{\n"
232         "    gl_Position = a_position;\n"
233         "    v_texCoord = a_texCoord;\n"
234         "}\n";
235 
236     static const char *fragShaderTemplate =
237         "${FRAG_HEADER}"
238         "layout(location = 0) ${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
239         "layout(location = 0) out ${FRAG_PRECISION} vec4 ${FRAG_COLOR};\n"
240         "layout (set=0, binding=0, std140) uniform Block \n"
241         "{\n"
242         "  ${PRECISION} float u_bias;\n"
243         "  ${PRECISION} float u_ref;\n"
244         "  ${PRECISION} vec4 u_colorScale;\n"
245         "  ${PRECISION} vec4 u_colorBias;\n"
246         "};\n\n"
247         "layout (set=1, binding=0) uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n"
248         "void main (void)\n"
249         "{\n"
250         "  ${PRECISION} ${TEXCOORD_TYPE} texCoord = v_texCoord${TEXCOORD_SWZ:opt};\n"
251         "  ${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n"
252         "}\n";
253 
254     tcu::StringTemplate vertexSource(vertShaderTemplate);
255     tcu::StringTemplate fragmentSource(fragShaderTemplate);
256 
257     for (std::vector<Program>::const_iterator programIt = programs.begin(); programIt != programs.end(); ++programIt)
258     {
259         Program program = *programIt;
260         std::map<std::string, std::string> params;
261 
262         bool isCube  = de::inRange<int>(program, PROGRAM_CUBE_FLOAT, PROGRAM_CUBE_SHADOW_BIAS);
263         bool isArray = de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW) ||
264                        de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW);
265 
266         bool is1D = de::inRange<int>(program, PROGRAM_1D_FLOAT, PROGRAM_1D_SHADOW_BIAS) ||
267                     de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW) ||
268                     de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
269 
270         bool is2D = de::inRange<int>(program, PROGRAM_2D_FLOAT, PROGRAM_2D_SHADOW_BIAS) ||
271                     de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW);
272 
273         bool is3D        = de::inRange<int>(program, PROGRAM_3D_FLOAT, PROGRAM_3D_UINT_BIAS);
274         bool isCubeArray = de::inRange<int>(program, PROGRAM_CUBE_ARRAY_FLOAT, PROGRAM_CUBE_ARRAY_SHADOW);
275 
276         const std::string version = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450);
277 
278         params["FRAG_HEADER"] = version + "\n";
279         params["VTX_HEADER"]  = version + "\n";
280         params["VTX_IN"]      = "in";
281         params["VTX_OUT"]     = "out";
282         params["FRAG_IN"]     = "in";
283         params["FRAG_COLOR"]  = "dEQP_FragColor";
284 
285         params["PRECISION"]      = glu::getPrecisionName(texCoordPrecision);
286         params["FRAG_PRECISION"] = glu::getPrecisionName(fragOutputPrecision);
287 
288         if (isCubeArray)
289             params["TEXCOORD_TYPE"] = "vec4";
290         else if (isCube || (is2D && isArray) || is3D)
291             params["TEXCOORD_TYPE"] = "vec3";
292         else if ((is1D && isArray) || is2D)
293             params["TEXCOORD_TYPE"] = "vec2";
294         else if (is1D)
295             params["TEXCOORD_TYPE"] = "float";
296         else
297             DE_ASSERT(false);
298 
299         if (texCoordSwizzle)
300             params["TEXCOORD_SWZ"] = std::string(".") + texCoordSwizzle;
301 
302         const char *sampler = DE_NULL;
303         std::string lookup;
304 
305         std::string texture = unnormal ? "textureLod" : "texture";
306         std::string lod     = unnormal ? ", 0" : "";
307 
308         switch (program)
309         {
310         case PROGRAM_2D_FLOAT:
311             sampler = "sampler2D";
312             lookup  = texture + "(u_sampler, texCoord" + lod + ")";
313             break;
314         case PROGRAM_2D_INT:
315             sampler = "isampler2D";
316             lookup  = "vec4(" + texture + "(u_sampler, texCoord" + lod + "))";
317             break;
318         case PROGRAM_2D_UINT:
319             sampler = "usampler2D";
320             lookup  = "vec4(" + texture + "(u_sampler, texCoord" + lod + "))";
321             break;
322         case PROGRAM_2D_FETCH_LOD:
323             sampler = "sampler2D";
324             lookup  = "texelFetch(u_sampler, ivec2(texCoord * vec2(64.f), 3)";
325             break;
326         case PROGRAM_2D_SHADOW:
327             sampler = "sampler2DShadow";
328             lookup  = "vec4(" + texture + "(u_sampler, vec3(texCoord, u_ref)" + lod + "), 0.0, 0.0, 1.0)";
329             break;
330         case PROGRAM_2D_FLOAT_BIAS:
331             sampler = "sampler2D";
332             lookup  = "texture(u_sampler, texCoord, u_bias)";
333             break;
334         case PROGRAM_2D_INT_BIAS:
335             sampler = "isampler2D";
336             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
337             break;
338         case PROGRAM_2D_UINT_BIAS:
339             sampler = "usampler2D";
340             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
341             break;
342         case PROGRAM_2D_SHADOW_BIAS:
343             sampler = "sampler2DShadow";
344             lookup  = "vec4(texture(u_sampler, vec3(texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";
345             break;
346         case PROGRAM_1D_FLOAT:
347             sampler = "sampler1D";
348             lookup  = texture + "(u_sampler, texCoord" + lod + ")";
349             break;
350         case PROGRAM_1D_INT:
351             sampler = "isampler1D";
352             lookup  = "vec4(" + texture + "(u_sampler, texCoord" + lod + "))";
353             break;
354         case PROGRAM_1D_UINT:
355             sampler = "usampler1D";
356             lookup  = "vec4(" + texture + "(u_sampler, texCoord" + lod + "))";
357             break;
358         case PROGRAM_1D_SHADOW:
359             sampler = "sampler1DShadow";
360             lookup  = "vec4(" + texture + "(u_sampler, vec3(texCoord, 0.0, u_ref)" + lod + "), 0.0, 0.0, 1.0)";
361             break;
362         case PROGRAM_1D_FLOAT_BIAS:
363             sampler = "sampler1D";
364             lookup  = "texture(u_sampler, texCoord, u_bias)";
365             break;
366         case PROGRAM_1D_INT_BIAS:
367             sampler = "isampler1D";
368             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
369             break;
370         case PROGRAM_1D_UINT_BIAS:
371             sampler = "usampler1D";
372             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
373             break;
374         case PROGRAM_1D_SHADOW_BIAS:
375             sampler = "sampler1DShadow";
376             lookup  = "vec4(texture(u_sampler, vec3(texCoord, 0.0, u_ref), u_bias), 0.0, 0.0, 1.0)";
377             break;
378         case PROGRAM_CUBE_FLOAT:
379             sampler = "samplerCube";
380             lookup  = "texture(u_sampler, texCoord)";
381             break;
382         case PROGRAM_CUBE_INT:
383             sampler = "isamplerCube";
384             lookup  = "vec4(texture(u_sampler, texCoord))";
385             break;
386         case PROGRAM_CUBE_UINT:
387             sampler = "usamplerCube";
388             lookup  = "vec4(texture(u_sampler, texCoord))";
389             break;
390         case PROGRAM_CUBE_SHADOW:
391             sampler = "samplerCubeShadow";
392             lookup  = "vec4(texture(u_sampler, vec4(texCoord, u_ref)), 0.0, 0.0, 1.0)";
393             break;
394         case PROGRAM_CUBE_FLOAT_BIAS:
395             sampler = "samplerCube";
396             lookup  = "texture(u_sampler, texCoord, u_bias)";
397             break;
398         case PROGRAM_CUBE_INT_BIAS:
399             sampler = "isamplerCube";
400             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
401             break;
402         case PROGRAM_CUBE_UINT_BIAS:
403             sampler = "usamplerCube";
404             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
405             break;
406         case PROGRAM_CUBE_SHADOW_BIAS:
407             sampler = "samplerCubeShadow";
408             lookup  = "vec4(texture(u_sampler, vec4(texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";
409             break;
410         case PROGRAM_2D_ARRAY_FLOAT:
411             sampler = "sampler2DArray";
412             lookup  = "texture(u_sampler, texCoord)";
413             break;
414         case PROGRAM_2D_ARRAY_INT:
415             sampler = "isampler2DArray";
416             lookup  = "vec4(texture(u_sampler, texCoord))";
417             break;
418         case PROGRAM_2D_ARRAY_UINT:
419             sampler = "usampler2DArray";
420             lookup  = "vec4(texture(u_sampler, texCoord))";
421             break;
422         case PROGRAM_2D_ARRAY_SHADOW:
423             sampler = "sampler2DArrayShadow";
424             lookup  = "vec4(texture(u_sampler, vec4(texCoord, u_ref)), 0.0, 0.0, 1.0)";
425             break;
426         case PROGRAM_3D_FLOAT:
427             sampler = "sampler3D";
428             lookup  = "texture(u_sampler, texCoord)";
429             break;
430         case PROGRAM_3D_INT:
431             sampler = "isampler3D";
432             lookup  = "vec4(texture(u_sampler, texCoord))";
433             break;
434         case PROGRAM_3D_UINT:
435             sampler = "usampler3D";
436             lookup  = "vec4(texture(u_sampler, texCoord))";
437             break;
438         case PROGRAM_3D_FLOAT_BIAS:
439             sampler = "sampler3D";
440             lookup  = "texture(u_sampler, texCoord, u_bias)";
441             break;
442         case PROGRAM_3D_INT_BIAS:
443             sampler = "isampler3D";
444             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
445             break;
446         case PROGRAM_3D_UINT_BIAS:
447             sampler = "usampler3D";
448             lookup  = "vec4(texture(u_sampler, texCoord, u_bias))";
449             break;
450         case PROGRAM_CUBE_ARRAY_FLOAT:
451             sampler = "samplerCubeArray";
452             lookup  = "texture(u_sampler, texCoord)";
453             break;
454         case PROGRAM_CUBE_ARRAY_INT:
455             sampler = "isamplerCubeArray";
456             lookup  = "vec4(texture(u_sampler, texCoord))";
457             break;
458         case PROGRAM_CUBE_ARRAY_UINT:
459             sampler = "usamplerCubeArray";
460             lookup  = "vec4(texture(u_sampler, texCoord))";
461             break;
462         case PROGRAM_CUBE_ARRAY_SHADOW:
463             sampler = "samplerCubeArrayShadow";
464             lookup  = "vec4(texture(u_sampler, texCoord, u_ref), 0.0, 0.0, 1.0)";
465             break;
466         case PROGRAM_1D_ARRAY_FLOAT:
467             sampler = "sampler1DArray";
468             lookup  = "texture(u_sampler, texCoord)";
469             break;
470         case PROGRAM_1D_ARRAY_INT:
471             sampler = "isampler1DArray";
472             lookup  = "vec4(texture(u_sampler, texCoord))";
473             break;
474         case PROGRAM_1D_ARRAY_UINT:
475             sampler = "usampler1DArray";
476             lookup  = "vec4(texture(u_sampler, texCoord))";
477             break;
478         case PROGRAM_1D_ARRAY_SHADOW:
479             sampler = "sampler1DArrayShadow";
480             lookup  = "vec4(texture(u_sampler, vec3(texCoord, u_ref)), 0.0, 0.0, 1.0)";
481             break;
482         case PROGRAM_BUFFER_FLOAT:
483             sampler = "samplerBuffer";
484             lookup  = "texelFetch(u_sampler, int(texCoord))";
485             break;
486         case PROGRAM_BUFFER_INT:
487             sampler = "isamplerBuffer";
488             lookup  = "vec4(texelFetch(u_sampler, int(texCoord)))";
489             break;
490         case PROGRAM_BUFFER_UINT:
491             sampler = "usamplerBuffer";
492             lookup  = "vec4(texelFetch(u_sampler, int(texCoord)))";
493             break;
494         default:
495             DE_ASSERT(false);
496         }
497 
498         params["SAMPLER_TYPE"] = sampler;
499         params["LOOKUP"]       = lookup;
500 
501         programCollection.glslSources.add("vertex_" + std::string(getProgramName(program)))
502             << glu::VertexSource(vertexSource.specialize(params));
503         programCollection.glslSources.add("fragment_" + std::string(getProgramName(program)))
504             << glu::FragmentSource(fragmentSource.specialize(params));
505     }
506 }
507 
TextureBinding(Context & context)508 TextureBinding::TextureBinding(Context &context)
509     : m_context(context)
510     , m_device(context.getDevice())
511     , m_allocator(context.getDefaultAllocator())
512 {
513 }
514 
TextureBinding(Context & context,VkDevice device,Allocator & allocator,const TestTextureSp & textureData,const TextureBinding::Type type,const vk::VkImageAspectFlags aspectMask,const TextureBinding::ImageBackingMode backingMode,const VkComponentMapping componentMapping)515 TextureBinding::TextureBinding(Context &context, VkDevice device, Allocator &allocator,
516                                const TestTextureSp &textureData, const TextureBinding::Type type,
517                                const vk::VkImageAspectFlags aspectMask,
518                                const TextureBinding::ImageBackingMode backingMode,
519                                const VkComponentMapping componentMapping)
520     : m_context(context)
521     , m_device(device)
522     , m_allocator(allocator)
523     , m_type(type)
524     , m_backingMode(backingMode)
525     , m_textureData(textureData)
526     , m_aspectMask(aspectMask)
527     , m_componentMapping(componentMapping)
528 {
529     updateTextureData(m_textureData, m_type);
530 }
531 
guessAspectMask(const vk::VkFormat format)532 VkImageAspectFlags guessAspectMask(const vk::VkFormat format)
533 {
534     tcu::TextureFormat textureFormat = mapVkFormat(format);
535     const bool isShadowTexture       = tcu::hasDepthComponent(textureFormat.order);
536     const bool isStencilTexture      = tcu::hasStencilComponent(textureFormat.order);
537     return isShadowTexture  ? VK_IMAGE_ASPECT_DEPTH_BIT :
538            isStencilTexture ? VK_IMAGE_ASPECT_STENCIL_BIT :
539                               VK_IMAGE_ASPECT_COLOR_BIT;
540 }
541 
updateTextureData(const TestTextureSp & textureData,const TextureBinding::Type textureType)542 void TextureBinding::updateTextureData(const TestTextureSp &textureData, const TextureBinding::Type textureType)
543 {
544     const DeviceInterface &vkd          = m_context.getDeviceInterface();
545     const bool sparse                   = m_backingMode == IMAGE_BACKING_MODE_SPARSE;
546     const uint32_t queueFamilyIndices[] = {m_context.getUniversalQueueFamilyIndex(),
547                                            m_context.getSparseQueueFamilyIndex()};
548     m_type                              = textureType;
549     m_textureData                       = textureData;
550 
551     const bool isCube = (m_type == TYPE_CUBE_MAP) || (m_type == TYPE_CUBE_ARRAY);
552     VkImageCreateFlags imageCreateFlags =
553         (isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0) |
554         (sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0);
555     const VkImageViewType imageViewType     = textureTypeToImageViewType(textureType);
556     const VkImageType imageType             = imageViewTypeToImageType(imageViewType);
557     const VkImageTiling imageTiling         = VK_IMAGE_TILING_OPTIMAL;
558     const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
559     const VkFormat format                   = textureData->isCompressed() ?
560                                                   mapCompressedTextureFormat(textureData->getCompressedLevel(0, 0).getFormat()) :
561                                                   mapTextureFormat(textureData->getTextureFormat());
562     const tcu::UVec3 textureDimension       = textureData->getTextureDimension();
563     const uint32_t mipLevels                = textureData->getNumLevels();
564     const uint32_t arraySize                = textureData->getArraySize();
565     vk::VkImageFormatProperties imageFormatProperties;
566     const VkResult imageFormatQueryResult = m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
567         m_context.getPhysicalDevice(), format, imageType, imageTiling, imageUsageFlags, imageCreateFlags,
568         &imageFormatProperties);
569     const VkSharingMode sharingMode =
570         (sparse && m_context.getUniversalQueueFamilyIndex() != m_context.getSparseQueueFamilyIndex()) ?
571             VK_SHARING_MODE_CONCURRENT :
572             VK_SHARING_MODE_EXCLUSIVE;
573     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
574     const VkQueue queue             = getDeviceQueue(vkd, m_device, queueFamilyIndex, 0);
575 
576     if (imageFormatQueryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
577     {
578         TCU_THROW(NotSupportedError, (std::string("Format not supported: ") + vk::getFormatName(format)).c_str());
579     }
580     else
581         VK_CHECK(imageFormatQueryResult);
582 
583     if (sparse)
584     {
585         uint32_t numSparseImageProperties = 0;
586 #ifndef CTS_USES_VULKANSC
587         m_context.getInstanceInterface().getPhysicalDeviceSparseImageFormatProperties(
588             m_context.getPhysicalDevice(), format, imageType, VK_SAMPLE_COUNT_1_BIT, imageUsageFlags, imageTiling,
589             &numSparseImageProperties, DE_NULL);
590 #endif // CTS_USES_VULKANSC
591         if (numSparseImageProperties == 0)
592             TCU_THROW(NotSupportedError,
593                       (std::string("Sparse format not supported: ") + vk::getFormatName(format)).c_str());
594     }
595 
596     if (imageFormatProperties.maxArrayLayers < arraySize)
597         TCU_THROW(NotSupportedError, ("Maximum array layers number for this format is not enough for this test."));
598 
599     if (imageFormatProperties.maxMipLevels < mipLevels)
600         TCU_THROW(NotSupportedError, ("Maximum mimap level number for this format is not enough for this test."));
601 
602     if (imageFormatProperties.maxExtent.width < textureDimension.x() ||
603         imageFormatProperties.maxExtent.height < textureDimension.y() ||
604         imageFormatProperties.maxExtent.depth < textureDimension.z())
605     {
606         TCU_THROW(NotSupportedError, ("Maximum image dimension for this format is not enough for this test."));
607     }
608 
609     // Create image
610     const VkImageCreateInfo imageParams = {
611         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
612         DE_NULL,                             // const void* pNext;
613         imageCreateFlags,                    // VkImageCreateFlags flags;
614         imageType,                           // VkImageType imageType;
615         format,                              // VkFormat format;
616         {                                    // VkExtent3D extent;
617          (uint32_t)textureDimension.x(), (uint32_t)textureDimension.y(), (uint32_t)textureDimension.z()},
618         mipLevels,                                           // uint32_t mipLevels;
619         arraySize,                                           // uint32_t arrayLayers;
620         VK_SAMPLE_COUNT_1_BIT,                               // VkSampleCountFlagBits samples;
621         imageTiling,                                         // VkImageTiling tiling;
622         imageUsageFlags,                                     // VkImageUsageFlags usage;
623         sharingMode,                                         // VkSharingMode sharingMode;
624         sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u, // uint32_t queueFamilyIndexCount;
625         queueFamilyIndices,                                  // const uint32_t* pQueueFamilyIndices;
626         VK_IMAGE_LAYOUT_UNDEFINED                            // VkImageLayout initialLayout;
627     };
628 
629     m_textureImage = createImage(vkd, m_device, &imageParams);
630 
631     if (sparse)
632     {
633         pipeline::uploadTestTextureSparse(
634             vkd, m_device, m_context.getPhysicalDevice(), m_context.getInstanceInterface(), imageParams, queue,
635             queueFamilyIndex, m_context.getSparseQueue(), m_allocator, m_allocations, *m_textureData, *m_textureImage);
636     }
637     else
638     {
639         m_textureImageMemory =
640             m_allocator.allocate(getImageMemoryRequirements(vkd, m_device, *m_textureImage), MemoryRequirement::Any);
641         VK_CHECK(vkd.bindImageMemory(m_device, *m_textureImage, m_textureImageMemory->getMemory(),
642                                      m_textureImageMemory->getOffset()));
643 
644         pipeline::uploadTestTexture(vkd, m_device, queue, queueFamilyIndex, m_allocator, *m_textureData,
645                                     *m_textureImage);
646     }
647 
648     updateTextureViewMipLevels(0, mipLevels - 1);
649 }
650 
updateTextureViewMipLevels(uint32_t baseLevel,uint32_t maxLevel,float imageViewMinLod)651 void TextureBinding::updateTextureViewMipLevels(uint32_t baseLevel, uint32_t maxLevel, float imageViewMinLod)
652 {
653     const DeviceInterface &vkd              = m_context.getDeviceInterface();
654     const vk::VkImageViewType imageViewType = textureTypeToImageViewType(m_type);
655     const vk::VkFormat format               = m_textureData->isCompressed() ?
656                                                   mapCompressedTextureFormat(m_textureData->getCompressedLevel(0, 0).getFormat()) :
657                                                   mapTextureFormat(m_textureData->getTextureFormat());
658     const VkImageAspectFlags aspectMask =
659         (m_aspectMask != VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM) ? m_aspectMask : guessAspectMask(format);
660     const uint32_t layerCount = m_textureData->getArraySize();
661 
662 #ifndef CTS_USES_VULKANSC
663     vk::VkImageViewMinLodCreateInfoEXT imageViewMinLodCreateInfo = {
664         VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT, // VkStructureType    sType
665         DE_NULL,                                              // const void*        pNext
666         imageViewMinLod,                                      // float            minLod
667     };
668 #else
669     DE_UNREF(imageViewMinLod);
670 #endif // CTS_USES_VULKANSC
671 
672     const vk::VkImageViewCreateInfo viewParams = {
673         vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
674 #ifndef CTS_USES_VULKANSC
675         imageViewMinLod >= 0.0f ? &imageViewMinLodCreateInfo : DE_NULL, // const void* pNext;
676 #else
677         DE_NULL, // const void* pNext;
678 #endif                      // CTS_USES_VULKANSC
679         0u,                 // VkImageViewCreateFlags flags;
680         *m_textureImage,    // VkImage image;
681         imageViewType,      // VkImageViewType viewType;
682         format,             // VkFormat format;
683         m_componentMapping, // VkComponentMapping components;
684         {
685             aspectMask,               // VkImageAspectFlags aspectMask;
686             baseLevel,                // uint32_t baseMipLevel;
687             maxLevel - baseLevel + 1, // uint32_t levelCount;
688             0,                        // uint32_t baseArrayLayer;
689             layerCount                // uint32_t layerCount;
690         },                            // VkImageSubresourceRange subresourceRange;
691     };
692 
693     m_textureImageView = createImageView(vkd, m_device, &viewParams);
694 }
695 
createRobustBufferAccessDevice(Context & context,const VkPhysicalDeviceFeatures2 * enabledFeatures2)696 Move<VkDevice> createRobustBufferAccessDevice(Context &context, const VkPhysicalDeviceFeatures2 *enabledFeatures2)
697 {
698     const float queuePriority = 1.0f;
699 
700     // Create a universal queue that supports graphics and compute
701     const VkDeviceQueueCreateInfo queueParams = {
702         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
703         DE_NULL,                                    // const void* pNext;
704         0u,                                         // VkDeviceQueueCreateFlags flags;
705         context.getUniversalQueueFamilyIndex(),     // uint32_t queueFamilyIndex;
706         1u,                                         // uint32_t queueCount;
707         &queuePriority                              // const float* pQueuePriorities;
708     };
709 
710     // \note Extensions in core are not explicitly enabled even though
711     //         they are in the extension list advertised to tests.
712     const auto &extensionPtrs = context.getDeviceCreationExtensions();
713 
714     const VkDeviceCreateInfo deviceParams = {
715         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
716         enabledFeatures2,                     // const void* pNext;
717         0u,                                   // VkDeviceCreateFlags flags;
718         1u,                                   // uint32_t queueCreateInfoCount;
719         &queueParams,                         // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
720         0u,                                   // uint32_t enabledLayerCount;
721         nullptr,                              // const char* const* ppEnabledLayerNames;
722         de::sizeU32(extensionPtrs),           // uint32_t enabledExtensionCount;
723         de::dataOrNull(extensionPtrs),        // const char* const* ppEnabledExtensionNames;
724         nullptr                               // const VkPhysicalDeviceFeatures* pEnabledFeatures;
725     };
726 
727     return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(),
728                               context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(),
729                               context.getPhysicalDevice(), &deviceParams);
730 }
731 
getDevice(void) const732 VkDevice TextureRenderer::getDevice(void) const
733 {
734     return (m_requireRobustness2 || m_requireImageViewMinLod) ? *m_customDevice : m_context.getDevice();
735 }
736 
737 const uint16_t TextureRenderer::s_vertexIndices[6]          = {0, 1, 2, 2, 1, 3};
738 const VkDeviceSize TextureRenderer::s_vertexIndexBufferSize = sizeof(TextureRenderer::s_vertexIndices);
739 
TextureRenderer(Context & context,vk::VkSampleCountFlagBits sampleCount,uint32_t renderWidth,uint32_t renderHeight,vk::VkComponentMapping componentMapping,bool requireRobustness2,bool requireImageViewMinLod)740 TextureRenderer::TextureRenderer(Context &context, vk::VkSampleCountFlagBits sampleCount, uint32_t renderWidth,
741                                  uint32_t renderHeight, vk::VkComponentMapping componentMapping,
742                                  bool requireRobustness2, bool requireImageViewMinLod)
743     : TextureRenderer(context, sampleCount, renderWidth, renderHeight, 1u, componentMapping, VK_IMAGE_TYPE_2D,
744                       VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, requireRobustness2, requireImageViewMinLod)
745 {
746 }
747 
TextureRenderer(Context & context,VkSampleCountFlagBits sampleCount,uint32_t renderWidth,uint32_t renderHeight,uint32_t renderDepth,VkComponentMapping componentMapping,VkImageType imageType,VkImageViewType imageViewType,vk::VkFormat imageFormat,bool requireRobustness2,bool requireImageViewMinLod)748 TextureRenderer::TextureRenderer(Context &context, VkSampleCountFlagBits sampleCount, uint32_t renderWidth,
749                                  uint32_t renderHeight, uint32_t renderDepth, VkComponentMapping componentMapping,
750                                  VkImageType imageType, VkImageViewType imageViewType, vk::VkFormat imageFormat,
751                                  bool requireRobustness2, bool requireImageViewMinLod)
752     : m_context(context)
753     , m_log(context.getTestContext().getLog())
754     , m_renderWidth(renderWidth)
755     , m_renderHeight(renderHeight)
756     , m_renderDepth(renderDepth)
757     , m_sampleCount(sampleCount)
758     , m_multisampling(m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
759     , m_imageFormat(imageFormat)
760     , m_textureFormat(vk::mapVkFormat(m_imageFormat))
761     , m_uniformBufferSize(sizeof(ShaderParameters))
762     , m_resultBufferSize(renderWidth * renderHeight * m_textureFormat.getPixelSize())
763     , m_viewportOffsetX(0.0f)
764     , m_viewportOffsetY(0.0f)
765     , m_viewportWidth((float)renderWidth)
766     , m_viewportHeight((float)renderHeight)
767     , m_componentMapping(componentMapping)
768     , m_requireRobustness2(requireRobustness2)
769     , m_requireImageViewMinLod(requireImageViewMinLod)
770 {
771     const DeviceInterface &vkd      = m_context.getDeviceInterface();
772     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
773 
774     if (m_requireRobustness2 || m_requireImageViewMinLod)
775     {
776         // Note we are already checking the needed features are available in checkSupport().
777         VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features = initVulkanStructure();
778         VkPhysicalDeviceFeatures2 features2                        = initVulkanStructure(&robustness2Features);
779 #ifndef CTS_USES_VULKANSC
780         VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures = initVulkanStructure();
781         if (m_requireImageViewMinLod)
782         {
783             DE_ASSERT(context.isDeviceFunctionalitySupported("VK_EXT_image_view_min_lod"));
784             imageViewMinLodFeatures.minLod = true;
785             if (m_requireRobustness2)
786             {
787                 robustness2Features.pNext = &imageViewMinLodFeatures;
788             }
789             else
790             {
791                 features2.pNext = &imageViewMinLodFeatures;
792             }
793         }
794 #endif
795         if (m_requireRobustness2)
796         {
797             DE_ASSERT(context.isDeviceFunctionalitySupported("VK_EXT_robustness2"));
798             robustness2Features.robustImageAccess2 = true;
799         }
800 
801         context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
802         m_customDevice = createRobustBufferAccessDevice(context, &features2);
803     }
804 
805     const VkDevice vkDevice = getDevice();
806     m_allocator             = de::MovePtr<Allocator>(new SimpleAllocator(
807         vkd, vkDevice,
808         getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())));
809 
810     // Command Pool
811     m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
812 
813     // Image
814     {
815         const VkImageUsageFlags imageUsage =
816             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
817         VkImageFormatProperties properties;
818 
819         if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
820                  m_context.getPhysicalDevice(), m_imageFormat, imageType, VK_IMAGE_TILING_OPTIMAL, imageUsage, 0,
821                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
822         {
823             TCU_THROW(NotSupportedError, "Format not supported");
824         }
825 
826         if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
827         {
828             TCU_THROW(NotSupportedError, "Format not supported");
829         }
830 
831         const VkImageCreateInfo imageCreateInfo = {
832             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType sType;
833             DE_NULL,                                        // const void* pNext;
834             0u,                                             // VkImageCreateFlags flags;
835             imageType,                                      // VkImageType imageType;
836             m_imageFormat,                                  // VkFormat format;
837             {m_renderWidth, m_renderHeight, m_renderDepth}, // VkExtent3D extent;
838             1u,                                             // uint32_t mipLevels;
839             1u,                                             // uint32_t arrayLayers;
840             m_sampleCount,                                  // VkSampleCountFlagBits samples;
841             VK_IMAGE_TILING_OPTIMAL,                        // VkImageTiling tiling;
842             imageUsage,                                     // VkImageUsageFlags usage;
843             VK_SHARING_MODE_EXCLUSIVE,                      // VkSharingMode sharingMode;
844             1u,                                             // uint32_t queueFamilyIndexCount;
845             &queueFamilyIndex,                              // const uint32_t* pQueueFamilyIndices;
846             VK_IMAGE_LAYOUT_UNDEFINED                       // VkImageLayout initialLayout;
847         };
848 
849         m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
850 
851         m_imageMemory =
852             m_allocator->allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
853         VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
854     }
855 
856     // Image View
857     {
858         const VkImageViewCreateInfo imageViewCreateInfo = {
859             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
860             DE_NULL,                                  // const void* pNext;
861             0u,                                       // VkImageViewCreateFlags flags;
862             *m_image,                                 // VkImage image;
863             imageViewType,                            // VkImageViewType viewType;
864             m_imageFormat,                            // VkFormat format;
865             makeComponentMappingRGBA(),               // VkComponentMapping components;
866             {
867                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
868                 0u,                        // uint32_t baseMipLevel;
869                 1u,                        // uint32_t mipLevels;
870                 0u,                        // uint32_t baseArrayLayer;
871                 1u,                        // uint32_t arraySize;
872             },                             // VkImageSubresourceRange subresourceRange;
873         };
874 
875         m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
876     }
877 
878     if (m_multisampling)
879     {
880         {
881             // Resolved Image
882             const VkImageUsageFlags imageUsage =
883                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
884             VkImageFormatProperties properties;
885 
886             if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
887                      m_context.getPhysicalDevice(), m_imageFormat, imageType, VK_IMAGE_TILING_OPTIMAL, imageUsage, 0,
888                      &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
889             {
890                 TCU_THROW(NotSupportedError, "Format not supported");
891             }
892 
893             const VkImageCreateInfo imageCreateInfo = {
894                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType sType;
895                 DE_NULL,                                        // const void* pNext;
896                 0u,                                             // VkImageCreateFlags flags;
897                 imageType,                                      // VkImageType imageType;
898                 m_imageFormat,                                  // VkFormat format;
899                 {m_renderWidth, m_renderHeight, m_renderDepth}, // VkExtent3D extent;
900                 1u,                                             // uint32_t mipLevels;
901                 1u,                                             // uint32_t arrayLayers;
902                 VK_SAMPLE_COUNT_1_BIT,                          // VkSampleCountFlagBits samples;
903                 VK_IMAGE_TILING_OPTIMAL,                        // VkImageTiling tiling;
904                 imageUsage,                                     // VkImageUsageFlags usage;
905                 VK_SHARING_MODE_EXCLUSIVE,                      // VkSharingMode sharingMode;
906                 1u,                                             // uint32_t queueFamilyIndexCount;
907                 &queueFamilyIndex,                              // const uint32_t* pQueueFamilyIndices;
908                 VK_IMAGE_LAYOUT_UNDEFINED                       // VkImageLayout initialLayout;
909             };
910 
911             m_resolvedImage       = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
912             m_resolvedImageMemory = m_allocator->allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage),
913                                                           MemoryRequirement::Any);
914             VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(),
915                                          m_resolvedImageMemory->getOffset()));
916         }
917 
918         // Resolved Image View
919         {
920             const VkImageViewCreateInfo imageViewCreateInfo = {
921                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
922                 DE_NULL,                                  // const void* pNext;
923                 0u,                                       // VkImageViewCreateFlags flags;
924                 *m_resolvedImage,                         // VkImage image;
925                 imageViewType,                            // VkImageViewType viewType;
926                 m_imageFormat,                            // VkFormat format;
927                 makeComponentMappingRGBA(),               // VkComponentMapping components;
928                 {
929                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
930                     0u,                        // uint32_t baseMipLevel;
931                     1u,                        // uint32_t mipLevels;
932                     0u,                        // uint32_t baseArrayLayer;
933                     1u,                        // uint32_t arraySize;
934                 },                             // VkImageSubresourceRange subresourceRange;
935             };
936 
937             m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
938         }
939     }
940 
941     // Render Pass
942     {
943         const VkImageLayout imageLayout                = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
944         const VkAttachmentDescription attachmentDesc[] = {
945             {
946                 0u,                               // VkAttachmentDescriptionFlags flags;
947                 m_imageFormat,                    // VkFormat format;
948                 m_sampleCount,                    // VkSampleCountFlagBits samples;
949                 VK_ATTACHMENT_LOAD_OP_LOAD,       // VkAttachmentLoadOp loadOp;
950                 VK_ATTACHMENT_STORE_OP_STORE,     // VkAttachmentStoreOp storeOp;
951                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,  // VkAttachmentLoadOp stencilLoadOp;
952                 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
953                 imageLayout,                      // VkImageLayout initialLayout;
954                 imageLayout,                      // VkImageLayout finalLayout;
955             },
956             {
957                 0u,                               // VkAttachmentDescriptionFlags flags;
958                 m_imageFormat,                    // VkFormat format;
959                 VK_SAMPLE_COUNT_1_BIT,            // VkSampleCountFlagBits samples;
960                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,  // VkAttachmentLoadOp loadOp;
961                 VK_ATTACHMENT_STORE_OP_STORE,     // VkAttachmentStoreOp storeOp;
962                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,  // VkAttachmentLoadOp stencilLoadOp;
963                 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
964                 imageLayout,                      // VkImageLayout initialLayout;
965                 imageLayout,                      // VkImageLayout finalLayout;
966             }};
967 
968         const VkAttachmentReference attachmentRef = {
969             0u,          // uint32_t attachment;
970             imageLayout, // VkImageLayout layout;
971         };
972 
973         const VkAttachmentReference resolveAttachmentRef = {
974             1u,          // uint32_t attachment;
975             imageLayout, // VkImageLayout layout;
976         };
977 
978         const VkSubpassDescription subpassDesc = {
979             0u,                                                // VkSubpassDescriptionFlags flags;
980             VK_PIPELINE_BIND_POINT_GRAPHICS,                   // VkPipelineBindPoint pipelineBindPoint;
981             0u,                                                // uint32_t inputAttachmentCount;
982             DE_NULL,                                           // const VkAttachmentReference* pInputAttachments;
983             1u,                                                // uint32_t colorAttachmentCount;
984             &attachmentRef,                                    // const VkAttachmentReference* pColorAttachments;
985             m_multisampling ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
986             DE_NULL,                                           // const VkAttachmentReference* pDepthStencilAttachment;
987             0u,                                                // uint32_t preserveAttachmentCount;
988             DE_NULL,                                           // const VkAttachmentReference* pPreserveAttachments;
989         };
990 
991         const VkRenderPassCreateInfo renderPassCreateInfo = {
992             VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
993             DE_NULL,                                   // const void* pNext;
994             0u,                                        // VkRenderPassCreateFlags flags;
995             m_multisampling ? 2u : 1u,                 // uint32_t attachmentCount;
996             attachmentDesc,                            // const VkAttachmentDescription* pAttachments;
997             1u,                                        // uint32_t subpassCount;
998             &subpassDesc,                              // const VkSubpassDescription* pSubpasses;
999             0u,                                        // uint32_t dependencyCount;
1000             DE_NULL,                                   // const VkSubpassDependency* pDependencies;
1001         };
1002 
1003         m_renderPass = createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
1004     }
1005 
1006     // Vertex index buffer
1007     {
1008         const VkBufferCreateInfo indexBufferParams = {
1009             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1010             DE_NULL,                              // const void* pNext;
1011             0u,                                   // VkBufferCreateFlags flags;
1012             s_vertexIndexBufferSize,              // VkDeviceSize size;
1013             VK_BUFFER_USAGE_INDEX_BUFFER_BIT,     // VkBufferUsageFlags usage;
1014             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
1015             1u,                                   // uint32_t queueFamilyCount;
1016             &queueFamilyIndex                     // const uint32_t* pQueueFamilyIndices;
1017         };
1018 
1019         m_vertexIndexBuffer       = createBuffer(vkd, vkDevice, &indexBufferParams);
1020         m_vertexIndexBufferMemory = m_allocator->allocate(
1021             getBufferMemoryRequirements(vkd, vkDevice, *m_vertexIndexBuffer), MemoryRequirement::HostVisible);
1022 
1023         VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_vertexIndexBuffer, m_vertexIndexBufferMemory->getMemory(),
1024                                       m_vertexIndexBufferMemory->getOffset()));
1025 
1026         // Load vertices into vertex buffer
1027         deMemcpy(m_vertexIndexBufferMemory->getHostPtr(), s_vertexIndices, s_vertexIndexBufferSize);
1028         flushMappedMemoryRange(vkd, vkDevice, m_vertexIndexBufferMemory->getMemory(),
1029                                m_vertexIndexBufferMemory->getOffset(), VK_WHOLE_SIZE);
1030     }
1031 
1032     // FrameBuffer
1033     {
1034         const VkImageView attachments[] = {
1035             *m_imageView,
1036             *m_resolvedImageView,
1037         };
1038 
1039         const VkFramebufferCreateInfo framebufferCreateInfo = {
1040             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1041             DE_NULL,                                   // const void* pNext;
1042             0u,                                        // VkFramebufferCreateFlags flags;
1043             *m_renderPass,                             // VkRenderPass renderPass;
1044             m_multisampling ? 2u : 1u,                 // uint32_t attachmentCount;
1045             attachments,                               // const VkImageView* pAttachments;
1046             m_renderWidth,                             // uint32_t width;
1047             m_renderHeight,                            // uint32_t height;
1048             1u,                                        // uint32_t layers;
1049         };
1050 
1051         m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
1052     }
1053 
1054     // Uniform Buffer
1055     {
1056         const VkBufferCreateInfo bufferCreateInfo = {
1057             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1058             DE_NULL,                              // const void* pNext;
1059             0u,                                   // VkBufferCreateFlags flags;
1060             m_uniformBufferSize,                  // VkDeviceSize size;
1061             VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,   // VkBufferUsageFlags usage;
1062             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
1063             1u,                                   // uint32_t queueFamilyIndexCount;
1064             &queueFamilyIndex                     // const uint32_t* pQueueFamilyIndices;
1065         };
1066 
1067         m_uniformBuffer       = createBuffer(vkd, vkDevice, &bufferCreateInfo);
1068         m_uniformBufferMemory = m_allocator->allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer),
1069                                                       MemoryRequirement::HostVisible);
1070 
1071         VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(),
1072                                       m_uniformBufferMemory->getOffset()));
1073     }
1074 
1075     // DescriptorPool
1076     {
1077         DescriptorPoolBuilder descriptorPoolBuilder;
1078 
1079         descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
1080         descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1081         m_descriptorPool =
1082             descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
1083     }
1084 
1085     // Descriptor Sets
1086     {
1087         m_descriptorSetLayout[0] =
1088             DescriptorSetLayoutBuilder()
1089                 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
1090                 .build(vkd, vkDevice);
1091 
1092         m_descriptorSetLayout[1] =
1093             DescriptorSetLayoutBuilder()
1094                 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
1095                 .build(vkd, vkDevice);
1096 
1097         m_descriptorSet[0] = makeDescriptorSet(*m_descriptorPool, *m_descriptorSetLayout[0]);
1098         m_descriptorSet[1] = makeDescriptorSet(*m_descriptorPool, *m_descriptorSetLayout[1]);
1099     }
1100 
1101     // Pipeline Layout
1102     {
1103         VkDescriptorSetLayout descriptorSetLayouts[2] = {*m_descriptorSetLayout[0], *m_descriptorSetLayout[1]};
1104 
1105         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
1106             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1107             DE_NULL,                                       // const void* pNext;
1108             0u,                                            // VkPipelineLayoutCreateFlags flags;
1109             2u,                                            // uint32_t descriptorSetCount;
1110             descriptorSetLayouts,                          // const VkDescriptorSetLayout* pSetLayouts;
1111             0u,                                            // uint32_t pushConstantRangeCount;
1112             DE_NULL                                        // const VkPushConstantRange* pPushConstantRanges;
1113         };
1114 
1115         m_pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
1116     }
1117 
1118     // Result Buffer
1119     {
1120         const VkBufferCreateInfo bufferCreateInfo = {
1121             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1122             DE_NULL,                              // const void* pNext;
1123             0u,                                   // VkBufferCreateFlags flags;
1124             m_resultBufferSize,                   // VkDeviceSize size;
1125             VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // VkBufferUsageFlags usage;
1126             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
1127             1u,                                   // uint32_t queueFamilyIndexCount;
1128             &queueFamilyIndex                     // const uint32_t* pQueueFamilyIndices;
1129         };
1130 
1131         m_resultBuffer       = createBuffer(vkd, vkDevice, &bufferCreateInfo);
1132         m_resultBufferMemory = m_allocator->allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer),
1133                                                      MemoryRequirement::HostVisible);
1134 
1135         VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(),
1136                                       m_resultBufferMemory->getOffset()));
1137     }
1138 
1139     clearImage(*m_image);
1140     if (m_multisampling)
1141         clearImage(*m_resolvedImage);
1142 }
1143 
~TextureRenderer(void)1144 TextureRenderer::~TextureRenderer(void)
1145 {
1146 }
1147 
clearImage(VkImage image)1148 void TextureRenderer::clearImage(VkImage image)
1149 {
1150     const DeviceInterface &vkd = m_context.getDeviceInterface();
1151     const VkDevice vkDevice    = getDevice();
1152     Move<VkCommandBuffer> commandBuffer;
1153     const uint32_t queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
1154     const VkQueue queue                            = getDeviceQueue(vkd, vkDevice, queueFamilyIndex, 0);
1155     const VkImageSubresourceRange subResourcerange = {
1156         VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1157         0,                         // uint32_t baseMipLevel;
1158         1,                         // uint32_t levelCount;
1159         0,                         // uint32_t baseArrayLayer;
1160         1                          // uint32_t layerCount;
1161     };
1162 
1163     commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1164 
1165     beginCommandBuffer(vkd, *commandBuffer);
1166 
1167     addImageTransitionBarrier(*commandBuffer, image,
1168                               VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,     // VkPipelineStageFlags        srcStageMask
1169                               VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,    // VkPipelineStageFlags        dstStageMask
1170                               0,                                     // VkAccessFlags            srcAccessMask
1171                               VK_ACCESS_TRANSFER_WRITE_BIT,          // VkAccessFlags            dstAccessMask
1172                               VK_IMAGE_LAYOUT_UNDEFINED,             // VkImageLayout oldLayout;
1173                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1174 
1175     VkClearColorValue color = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color;
1176     vkd.cmdClearColorImage(*commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subResourcerange);
1177 
1178     addImageTransitionBarrier(*commandBuffer, image,
1179                               VK_PIPELINE_STAGE_TRANSFER_BIT,            // VkPipelineStageFlags        srcStageMask
1180                               VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,        // VkPipelineStageFlags        dstStageMask
1181                               VK_ACCESS_TRANSFER_WRITE_BIT,              // VkAccessFlags            srcAccessMask
1182                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,      // VkAccessFlags            dstAccessMask
1183                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,      // VkImageLayout oldLayout;
1184                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
1185 
1186     endCommandBuffer(vkd, *commandBuffer);
1187 
1188     submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
1189 }
1190 
add2DTexture(const TestTexture2DSp & texture,const vk::VkImageAspectFlags & aspectMask,TextureBinding::ImageBackingMode backingMode)1191 void TextureRenderer::add2DTexture(const TestTexture2DSp &texture, const vk::VkImageAspectFlags &aspectMask,
1192                                    TextureBinding::ImageBackingMode backingMode)
1193 {
1194     m_textureBindings.push_back(
1195         TextureBindingSp(new TextureBinding(m_context, getDevice(), *m_allocator, texture, TextureBinding::TYPE_2D,
1196                                             aspectMask, backingMode, m_componentMapping)));
1197 }
1198 
addCubeTexture(const TestTextureCubeSp & texture,const vk::VkImageAspectFlags & aspectMask,TextureBinding::ImageBackingMode backingMode)1199 void TextureRenderer::addCubeTexture(const TestTextureCubeSp &texture, const vk::VkImageAspectFlags &aspectMask,
1200                                      TextureBinding::ImageBackingMode backingMode)
1201 {
1202     m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, getDevice(), *m_allocator, texture,
1203                                                                     TextureBinding::TYPE_CUBE_MAP, aspectMask,
1204                                                                     backingMode, m_componentMapping)));
1205 }
1206 
add2DArrayTexture(const TestTexture2DArraySp & texture,const vk::VkImageAspectFlags & aspectMask,TextureBinding::ImageBackingMode backingMode)1207 void TextureRenderer::add2DArrayTexture(const TestTexture2DArraySp &texture, const vk::VkImageAspectFlags &aspectMask,
1208                                         TextureBinding::ImageBackingMode backingMode)
1209 {
1210     m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, getDevice(), *m_allocator, texture,
1211                                                                     TextureBinding::TYPE_2D_ARRAY, aspectMask,
1212                                                                     backingMode, m_componentMapping)));
1213 }
1214 
add3DTexture(const TestTexture3DSp & texture,const vk::VkImageAspectFlags & aspectMask,TextureBinding::ImageBackingMode backingMode)1215 void TextureRenderer::add3DTexture(const TestTexture3DSp &texture, const vk::VkImageAspectFlags &aspectMask,
1216                                    TextureBinding::ImageBackingMode backingMode)
1217 {
1218     m_textureBindings.push_back(
1219         TextureBindingSp(new TextureBinding(m_context, getDevice(), *m_allocator, texture, TextureBinding::TYPE_3D,
1220                                             aspectMask, backingMode, m_componentMapping)));
1221 }
1222 
add1DTexture(const TestTexture1DSp & texture,const vk::VkImageAspectFlags & aspectMask,TextureBinding::ImageBackingMode backingMode)1223 void TextureRenderer::add1DTexture(const TestTexture1DSp &texture, const vk::VkImageAspectFlags &aspectMask,
1224                                    TextureBinding::ImageBackingMode backingMode)
1225 {
1226     m_textureBindings.push_back(
1227         TextureBindingSp(new TextureBinding(m_context, getDevice(), *m_allocator, texture, TextureBinding::TYPE_1D,
1228                                             aspectMask, backingMode, m_componentMapping)));
1229 }
1230 
add1DArrayTexture(const TestTexture1DArraySp & texture,const vk::VkImageAspectFlags & aspectMask,TextureBinding::ImageBackingMode backingMode)1231 void TextureRenderer::add1DArrayTexture(const TestTexture1DArraySp &texture, const vk::VkImageAspectFlags &aspectMask,
1232                                         TextureBinding::ImageBackingMode backingMode)
1233 {
1234     m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, getDevice(), *m_allocator, texture,
1235                                                                     TextureBinding::TYPE_1D_ARRAY, aspectMask,
1236                                                                     backingMode, m_componentMapping)));
1237 }
1238 
addCubeArrayTexture(const TestTextureCubeArraySp & texture,const vk::VkImageAspectFlags & aspectMask,TextureBinding::ImageBackingMode backingMode)1239 void TextureRenderer::addCubeArrayTexture(const TestTextureCubeArraySp &texture,
1240                                           const vk::VkImageAspectFlags &aspectMask,
1241                                           TextureBinding::ImageBackingMode backingMode)
1242 {
1243     m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, getDevice(), *m_allocator, texture,
1244                                                                     TextureBinding::TYPE_CUBE_ARRAY, aspectMask,
1245                                                                     backingMode, m_componentMapping)));
1246 }
1247 
get2DTexture(int textureIndex) const1248 const pipeline::TestTexture2D &TextureRenderer::get2DTexture(int textureIndex) const
1249 {
1250     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1251     DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D);
1252 
1253     return dynamic_cast<const pipeline::TestTexture2D &>(m_textureBindings[textureIndex]->getTestTexture());
1254 }
1255 
getCubeTexture(int textureIndex) const1256 const pipeline::TestTextureCube &TextureRenderer::getCubeTexture(int textureIndex) const
1257 {
1258     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1259     DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_CUBE_MAP);
1260 
1261     return dynamic_cast<const pipeline::TestTextureCube &>(m_textureBindings[textureIndex]->getTestTexture());
1262 }
1263 
get2DArrayTexture(int textureIndex) const1264 const pipeline::TestTexture2DArray &TextureRenderer::get2DArrayTexture(int textureIndex) const
1265 {
1266     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1267     DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D_ARRAY);
1268 
1269     return dynamic_cast<const pipeline::TestTexture2DArray &>(m_textureBindings[textureIndex]->getTestTexture());
1270 }
1271 
get3DTexture(int textureIndex) const1272 const pipeline::TestTexture3D &TextureRenderer::get3DTexture(int textureIndex) const
1273 {
1274     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1275     DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_3D);
1276 
1277     return dynamic_cast<const pipeline::TestTexture3D &>(m_textureBindings[textureIndex]->getTestTexture());
1278 }
1279 
get1DTexture(int textureIndex) const1280 const pipeline::TestTexture1D &TextureRenderer::get1DTexture(int textureIndex) const
1281 {
1282     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1283     DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_1D);
1284 
1285     return dynamic_cast<const pipeline::TestTexture1D &>(m_textureBindings[textureIndex]->getTestTexture());
1286 }
1287 
get1DArrayTexture(int textureIndex) const1288 const pipeline::TestTexture1DArray &TextureRenderer::get1DArrayTexture(int textureIndex) const
1289 {
1290     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1291     DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_1D_ARRAY);
1292 
1293     return dynamic_cast<const pipeline::TestTexture1DArray &>(m_textureBindings[textureIndex]->getTestTexture());
1294 }
1295 
getCubeArrayTexture(int textureIndex) const1296 const pipeline::TestTextureCubeArray &TextureRenderer::getCubeArrayTexture(int textureIndex) const
1297 {
1298     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1299     DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_CUBE_ARRAY);
1300 
1301     return dynamic_cast<const pipeline::TestTextureCubeArray &>(m_textureBindings[textureIndex]->getTestTexture());
1302 }
1303 
setViewport(float viewportX,float viewportY,float viewportW,float viewportH)1304 void TextureRenderer::setViewport(float viewportX, float viewportY, float viewportW, float viewportH)
1305 {
1306     m_viewportHeight  = viewportH;
1307     m_viewportWidth   = viewportW;
1308     m_viewportOffsetX = viewportX;
1309     m_viewportOffsetY = viewportY;
1310 }
1311 
getTextureBinding(int textureIndex) const1312 TextureBinding *TextureRenderer::getTextureBinding(int textureIndex) const
1313 {
1314     DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex);
1315     return m_textureBindings[textureIndex].get();
1316 }
1317 
getRenderWidth(void) const1318 uint32_t TextureRenderer::getRenderWidth(void) const
1319 {
1320     return m_renderWidth;
1321 }
1322 
getRenderHeight(void) const1323 uint32_t TextureRenderer::getRenderHeight(void) const
1324 {
1325     return m_renderHeight;
1326 }
1327 
makeDescriptorSet(const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout) const1328 Move<VkDescriptorSet> TextureRenderer::makeDescriptorSet(const VkDescriptorPool descriptorPool,
1329                                                          const VkDescriptorSetLayout setLayout) const
1330 {
1331     const DeviceInterface &vkd = m_context.getDeviceInterface();
1332     const VkDevice vkDevice    = getDevice();
1333 
1334     const VkDescriptorSetAllocateInfo allocateParams = {
1335         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                    sType
1336         DE_NULL,                                        // const void*                        pNext
1337         descriptorPool,                                 // VkDescriptorPool                    descriptorPool
1338         1u,                                             // uint32_t                            descriptorSetCount
1339         &setLayout,                                     // const VkDescriptorSetLayout*        pSetLayouts
1340     };
1341     return allocateDescriptorSet(vkd, vkDevice, &allocateParams);
1342 }
1343 
addImageTransitionBarrier(VkCommandBuffer commandBuffer,VkImage image,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkImageLayout oldLayout,VkImageLayout newLayout) const1344 void TextureRenderer::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image,
1345                                                 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1346                                                 VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
1347                                                 VkImageLayout oldLayout, VkImageLayout newLayout) const
1348 {
1349     const DeviceInterface &vkd = m_context.getDeviceInterface();
1350 
1351     const VkImageSubresourceRange subResourcerange = {
1352         VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1353         0,                         // uint32_t baseMipLevel;
1354         1,                         // uint32_t levelCount;
1355         0,                         // uint32_t baseArrayLayer;
1356         1                          // uint32_t layerCount;
1357     };
1358 
1359     const VkImageMemoryBarrier imageBarrier = {
1360         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1361         DE_NULL,                                // const void* pNext;
1362         srcAccessMask,                          // VkAccessFlags srcAccessMask;
1363         dstAccessMask,                          // VkAccessFlags dstAccessMask;
1364         oldLayout,                              // VkImageLayout oldLayout;
1365         newLayout,                              // VkImageLayout newLayout;
1366         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
1367         VK_QUEUE_FAMILY_IGNORED,                // uint32_t destQueueFamilyIndex;
1368         image,                                  // VkImage image;
1369         subResourcerange                        // VkImageSubresourceRange subresourceRange;
1370     };
1371 
1372     vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
1373 }
1374 
renderQuad(tcu::Surface & result,int texUnit,const float * texCoord,TextureType texType)1375 void TextureRenderer::renderQuad(tcu::Surface &result, int texUnit, const float *texCoord, TextureType texType)
1376 {
1377     renderQuad(result, texUnit, texCoord, ReferenceParams(texType));
1378 }
1379 
renderQuad(tcu::Surface & result,int texUnit,const float * texCoord,const ReferenceParams & params)1380 void TextureRenderer::renderQuad(tcu::Surface &result, int texUnit, const float *texCoord,
1381                                  const ReferenceParams &params)
1382 {
1383     renderQuad(result.getAccess(), texUnit, texCoord, params);
1384 }
1385 
renderQuad(const tcu::PixelBufferAccess & result,int texUnit,const float * texCoord,const ReferenceParams & params)1386 void TextureRenderer::renderQuad(const tcu::PixelBufferAccess &result, int texUnit, const float *texCoord,
1387                                  const ReferenceParams &params)
1388 {
1389     const float maxAnisotropy = 1.0f;
1390     float positions[]         = {-1.0,  -1.0f, 0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f,
1391                                  +1.0f, -1.0f, 0.0f, 1.0f, +1.0f, +1.0f, 0.0f, 1.0f};
1392     renderQuad(result, positions, texUnit, texCoord, params, maxAnisotropy);
1393 }
1394 
renderQuad(tcu::Surface & result,const float * positions,int texUnit,const float * texCoord,const glu::TextureTestUtil::ReferenceParams & params,const float maxAnisotropy)1395 void TextureRenderer::renderQuad(tcu::Surface &result, const float *positions, int texUnit, const float *texCoord,
1396                                  const glu::TextureTestUtil::ReferenceParams &params, const float maxAnisotropy)
1397 {
1398     renderQuad(result.getAccess(), positions, texUnit, texCoord, params, maxAnisotropy);
1399 }
1400 
renderQuad(const tcu::PixelBufferAccess & result,const float * positions,int texUnit,const float * texCoord,const glu::TextureTestUtil::ReferenceParams & params,const float maxAnisotropy)1401 void TextureRenderer::renderQuad(const tcu::PixelBufferAccess &result, const float *positions, int texUnit,
1402                                  const float *texCoord, const glu::TextureTestUtil::ReferenceParams &params,
1403                                  const float maxAnisotropy)
1404 {
1405     const DeviceInterface &vkd      = m_context.getDeviceInterface();
1406     const VkDevice vkDevice         = getDevice();
1407     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1408     const VkQueue queue             = getDeviceQueue(vkd, vkDevice, queueFamilyIndex, 0);
1409 
1410     tcu::Vec4 wCoord = params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
1411     bool useBias     = !!(params.flags & RenderParams::USE_BIAS);
1412     bool logUniforms = true; //!!(params.flags & RenderParams::LOG_UNIFORMS);
1413     bool imageViewMinLodIntegerTexelCoord =
1414         params.imageViewMinLod != 0.0f && params.samplerType == glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
1415 
1416     // Render quad with texture.
1417     float position[] = {
1418         positions[0] * wCoord.x(),  positions[1] * wCoord.x(),  positions[2],  positions[3] * wCoord.x(),
1419         positions[4] * wCoord.y(),  positions[5] * wCoord.y(),  positions[6],  positions[7] * wCoord.y(),
1420         positions[8] * wCoord.z(),  positions[9] * wCoord.z(),  positions[10], positions[11] * wCoord.z(),
1421         positions[12] * wCoord.w(), positions[13] * wCoord.w(), positions[14], positions[15] * wCoord.w()};
1422 
1423     Program progSpec = PROGRAM_LAST;
1424     int numComps     = 0;
1425 
1426     if (params.texType == TEXTURETYPE_2D)
1427     {
1428         numComps = 2;
1429 
1430         switch (params.samplerType)
1431         {
1432         case SAMPLERTYPE_FLOAT:
1433             progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS : PROGRAM_2D_FLOAT;
1434             break;
1435         case SAMPLERTYPE_INT:
1436             progSpec = useBias ? PROGRAM_2D_INT_BIAS : PROGRAM_2D_INT;
1437             break;
1438         case SAMPLERTYPE_UINT:
1439             progSpec = useBias ? PROGRAM_2D_UINT_BIAS : PROGRAM_2D_UINT;
1440             break;
1441         case SAMPLERTYPE_SHADOW:
1442             progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS : PROGRAM_2D_SHADOW;
1443             break;
1444         case SAMPLERTYPE_FETCH_FLOAT:
1445             progSpec = PROGRAM_2D_FETCH_LOD;
1446             break;
1447         default:
1448             DE_ASSERT(false);
1449         }
1450     }
1451     else if (params.texType == TEXTURETYPE_1D)
1452     {
1453         numComps = 1;
1454 
1455         switch (params.samplerType)
1456         {
1457         case SAMPLERTYPE_FLOAT:
1458             progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS : PROGRAM_1D_FLOAT;
1459             break;
1460         case SAMPLERTYPE_INT:
1461             progSpec = useBias ? PROGRAM_1D_INT_BIAS : PROGRAM_1D_INT;
1462             break;
1463         case SAMPLERTYPE_UINT:
1464             progSpec = useBias ? PROGRAM_1D_UINT_BIAS : PROGRAM_1D_UINT;
1465             break;
1466         case SAMPLERTYPE_SHADOW:
1467             progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS : PROGRAM_1D_SHADOW;
1468             break;
1469         default:
1470             DE_ASSERT(false);
1471         }
1472     }
1473     else if (params.texType == TEXTURETYPE_CUBE)
1474     {
1475         numComps = 3;
1476 
1477         switch (params.samplerType)
1478         {
1479         case SAMPLERTYPE_FLOAT:
1480             progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS : PROGRAM_CUBE_FLOAT;
1481             break;
1482         case SAMPLERTYPE_INT:
1483             progSpec = useBias ? PROGRAM_CUBE_INT_BIAS : PROGRAM_CUBE_INT;
1484             break;
1485         case SAMPLERTYPE_UINT:
1486             progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS : PROGRAM_CUBE_UINT;
1487             break;
1488         case SAMPLERTYPE_SHADOW:
1489             progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS : PROGRAM_CUBE_SHADOW;
1490             break;
1491         default:
1492             DE_ASSERT(false);
1493         }
1494     }
1495     else if (params.texType == TEXTURETYPE_3D)
1496     {
1497         numComps = 3;
1498 
1499         switch (params.samplerType)
1500         {
1501         case SAMPLERTYPE_FLOAT:
1502             progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS : PROGRAM_3D_FLOAT;
1503             break;
1504         case SAMPLERTYPE_INT:
1505             progSpec = useBias ? PROGRAM_3D_INT_BIAS : PROGRAM_3D_INT;
1506             break;
1507         case SAMPLERTYPE_UINT:
1508             progSpec = useBias ? PROGRAM_3D_UINT_BIAS : PROGRAM_3D_UINT;
1509             break;
1510         case SAMPLERTYPE_FETCH_FLOAT:
1511             progSpec = PROGRAM_3D_FETCH_LOD;
1512             break;
1513         default:
1514             DE_ASSERT(false);
1515         }
1516     }
1517     else if (params.texType == TEXTURETYPE_2D_ARRAY)
1518     {
1519         DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
1520 
1521         numComps = 3;
1522 
1523         switch (params.samplerType)
1524         {
1525         case SAMPLERTYPE_FLOAT:
1526             progSpec = PROGRAM_2D_ARRAY_FLOAT;
1527             break;
1528         case SAMPLERTYPE_INT:
1529             progSpec = PROGRAM_2D_ARRAY_INT;
1530             break;
1531         case SAMPLERTYPE_UINT:
1532             progSpec = PROGRAM_2D_ARRAY_UINT;
1533             break;
1534         case SAMPLERTYPE_SHADOW:
1535             progSpec = PROGRAM_2D_ARRAY_SHADOW;
1536             break;
1537         default:
1538             DE_ASSERT(false);
1539         }
1540     }
1541     else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
1542     {
1543         DE_ASSERT(!useBias);
1544 
1545         numComps = 4;
1546 
1547         switch (params.samplerType)
1548         {
1549         case SAMPLERTYPE_FLOAT:
1550             progSpec = PROGRAM_CUBE_ARRAY_FLOAT;
1551             break;
1552         case SAMPLERTYPE_INT:
1553             progSpec = PROGRAM_CUBE_ARRAY_INT;
1554             break;
1555         case SAMPLERTYPE_UINT:
1556             progSpec = PROGRAM_CUBE_ARRAY_UINT;
1557             break;
1558         case SAMPLERTYPE_SHADOW:
1559             progSpec = PROGRAM_CUBE_ARRAY_SHADOW;
1560             break;
1561         default:
1562             DE_ASSERT(false);
1563         }
1564     }
1565     else if (params.texType == TEXTURETYPE_1D_ARRAY)
1566     {
1567         DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
1568 
1569         numComps = 2;
1570 
1571         switch (params.samplerType)
1572         {
1573         case SAMPLERTYPE_FLOAT:
1574             progSpec = PROGRAM_1D_ARRAY_FLOAT;
1575             break;
1576         case SAMPLERTYPE_INT:
1577             progSpec = PROGRAM_1D_ARRAY_INT;
1578             break;
1579         case SAMPLERTYPE_UINT:
1580             progSpec = PROGRAM_1D_ARRAY_UINT;
1581             break;
1582         case SAMPLERTYPE_SHADOW:
1583             progSpec = PROGRAM_1D_ARRAY_SHADOW;
1584             break;
1585         default:
1586             DE_ASSERT(false);
1587         }
1588     }
1589     else if (params.texType == TEXTURETYPE_BUFFER)
1590     {
1591         numComps = 1;
1592 
1593         switch (params.samplerType)
1594         {
1595         case SAMPLERTYPE_FETCH_FLOAT:
1596             progSpec = PROGRAM_BUFFER_FLOAT;
1597             break;
1598         case SAMPLERTYPE_FETCH_INT:
1599             progSpec = PROGRAM_BUFFER_INT;
1600             break;
1601         case SAMPLERTYPE_FETCH_UINT:
1602             progSpec = PROGRAM_BUFFER_UINT;
1603             break;
1604         default:
1605             DE_ASSERT(false);
1606         }
1607     }
1608     else
1609         DE_ASSERT(false);
1610 
1611     Unique<VkShaderModule> vertexShaderModule(createShaderModule(
1612         vkd, vkDevice, m_context.getBinaryCollection().get("vertex_" + std::string(getProgramName(progSpec))), 0));
1613     Unique<VkShaderModule> fragmentShaderModule(createShaderModule(
1614         vkd, vkDevice, m_context.getBinaryCollection().get("fragment_" + std::string(getProgramName(progSpec))), 0));
1615 
1616     Move<VkSampler> sampler;
1617 
1618     Move<VkCommandBuffer> commandBuffer;
1619     Move<VkPipeline> graphicsPipeline;
1620     Move<VkBuffer> vertexBuffer;
1621     de::MovePtr<Allocation> vertexBufferMemory;
1622 
1623     const VkDeviceSize vertexBufferOffset   = 0;
1624     const uint32_t vertexPositionStrideSize = uint32_t(sizeof(tcu::Vec4));
1625     const uint32_t vertexTextureStrideSize  = uint32_t(numComps * sizeof(float));
1626     const uint32_t positionDataSize         = vertexPositionStrideSize * 4u;
1627     const uint32_t textureCoordDataSize     = vertexTextureStrideSize * 4u;
1628 
1629     const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
1630 
1631     if (positionDataSize > properties.limits.maxVertexInputAttributeOffset)
1632     {
1633         std::stringstream message;
1634         message << "Larger vertex input attribute offset is needed (" << positionDataSize
1635                 << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
1636         TCU_THROW(NotSupportedError, message.str().c_str());
1637     }
1638 
1639     // Create Graphics Pipeline
1640     {
1641         const VkVertexInputBindingDescription vertexInputBindingDescription[2] = {
1642             {
1643                 0u,                         // uint32_t binding;
1644                 vertexPositionStrideSize,   // uint32_t strideInBytes;
1645                 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1646             },
1647             {
1648                 1u,                         // uint32_t binding;
1649                 vertexTextureStrideSize,    // uint32_t strideInBytes;
1650                 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1651             }};
1652 
1653         VkFormat textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
1654 
1655         switch (numComps)
1656         {
1657         case 1:
1658             textureCoordinateFormat = VK_FORMAT_R32_SFLOAT;
1659             break;
1660         case 2:
1661             textureCoordinateFormat = VK_FORMAT_R32G32_SFLOAT;
1662             break;
1663         case 3:
1664             textureCoordinateFormat = VK_FORMAT_R32G32B32_SFLOAT;
1665             break;
1666         case 4:
1667             textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
1668             break;
1669         default:
1670             DE_ASSERT(false);
1671         }
1672 
1673         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = {
1674             {
1675                 0u,                            // uint32_t location;
1676                 0u,                            // uint32_t binding;
1677                 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1678                 0u                             // uint32_t offsetInBytes;
1679             },
1680             {
1681                 1u,                      // uint32_t location;
1682                 1u,                      // uint32_t binding;
1683                 textureCoordinateFormat, // VkFormat format;
1684                 positionDataSize         // uint32_t offsetInBytes;
1685             }};
1686 
1687         const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1688             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1689             DE_NULL,                                                   // const void* pNext;
1690             0,                                                         // VkPipelineVertexInputStateCreateFlags flags;
1691             2u,                                                        // uint32_t bindingCount;
1692             vertexInputBindingDescription,   // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1693             2u,                              // uint32_t attributeCount;
1694             vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1695         };
1696 
1697         const VkViewport viewport = {
1698             m_viewportOffsetX, // float originX;
1699             m_viewportOffsetY, // float originY;
1700             m_viewportWidth,   // float width;
1701             m_viewportHeight,  // float height;
1702             0.0f,              // float minDepth;
1703             1.0f               // float maxDepth;
1704         };
1705         const std::vector<VkViewport> viewports(1, viewport);
1706         const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(m_renderWidth, m_renderHeight)));
1707 
1708         const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
1709             VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1710             DE_NULL,                                                  // const void* pNext;
1711             0u,                                                       // VkPipelineMultisampleStateCreateFlags flags;
1712             m_sampleCount,                                            // VkSampleCountFlagBits rasterizationSamples;
1713             VK_FALSE,                                                 // VkBool32 sampleShadingEnable;
1714             0.0f,                                                     // float minSampleShading;
1715             DE_NULL,                                                  // const VkSampleMask* pSampleMask;
1716             VK_FALSE,                                                 // VkBool32 alphaToCoverageEnable;
1717             VK_FALSE                                                  // VkBool32 alphaToOneEnable;
1718         };
1719 
1720         VkSamplerCreateInfo samplerCreateInfo =
1721             mapSampler(params.sampler, m_textureBindings[texUnit]->getTestTexture().getTextureFormat(), params.minLod,
1722                        params.maxLod, params.unnormal);
1723 
1724         if (maxAnisotropy > 1.0f)
1725         {
1726             samplerCreateInfo.anisotropyEnable = VK_TRUE;
1727             samplerCreateInfo.maxAnisotropy    = maxAnisotropy;
1728         }
1729 
1730         bool linFilt =
1731             (samplerCreateInfo.magFilter == VK_FILTER_LINEAR || samplerCreateInfo.minFilter == VK_FILTER_LINEAR ||
1732              samplerCreateInfo.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR);
1733         if (linFilt && samplerCreateInfo.compareEnable == VK_FALSE)
1734         {
1735             const pipeline::TestTexture &testTexture = m_textureBindings[texUnit]->getTestTexture();
1736             const VkFormat textureFormat =
1737                 testTexture.isCompressed() ?
1738                     mapCompressedTextureFormat(testTexture.getCompressedLevel(0, 0).getFormat()) :
1739                     mapTextureFormat(testTexture.getTextureFormat());
1740             const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(
1741                 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), textureFormat);
1742 
1743             if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1744                 TCU_THROW(NotSupportedError, "Linear filtering for this image format is not supported");
1745         }
1746 
1747         sampler = createSampler(vkd, vkDevice, &samplerCreateInfo);
1748 
1749         {
1750             const VkDescriptorBufferInfo descriptorBufferInfo = {
1751                 *m_uniformBuffer, // VkBuffer buffer;
1752                 0u,               // VkDeviceSize offset;
1753                 VK_WHOLE_SIZE     // VkDeviceSize range;
1754             };
1755 
1756             DescriptorSetUpdateBuilder()
1757                 .writeSingle(*m_descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0),
1758                              VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorBufferInfo)
1759                 .update(vkd, vkDevice);
1760         }
1761 
1762         {
1763             VkDescriptorImageInfo descriptorImageInfo = {
1764                 *sampler,                                   // VkSampler sampler;
1765                 m_textureBindings[texUnit]->getImageView(), // VkImageView imageView;
1766                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL    // VkImageLayout imageLayout;
1767             };
1768 
1769             DescriptorSetUpdateBuilder()
1770                 .writeSingle(*m_descriptorSet[1], DescriptorSetUpdateBuilder::Location::binding(0),
1771                              VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo)
1772                 .update(vkd, vkDevice);
1773         }
1774 
1775         graphicsPipeline = makeGraphicsPipeline(
1776             vkd,                   // const DeviceInterface&                        vk
1777             vkDevice,              // const VkDevice                                device
1778             *m_pipelineLayout,     // const VkPipelineLayout                        pipelineLayout
1779             *vertexShaderModule,   // const VkShaderModule                          vertexShaderModule
1780             DE_NULL,               // const VkShaderModule                          tessellationControlShaderModule
1781             DE_NULL,               // const VkShaderModule                          tessellationEvalShaderModule
1782             DE_NULL,               // const VkShaderModule                          geometryShaderModule
1783             *fragmentShaderModule, // const VkShaderModule                          fragmentShaderModule
1784             *m_renderPass,         // const VkRenderPass                            renderPass
1785             viewports,             // const std::vector<VkViewport>&                viewports
1786             scissors,              // const std::vector<VkRect2D>&                  scissors
1787             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology                     topology
1788             0u,                                  // const uint32_t                                subpass
1789             0u,                                  // const uint32_t                                patchControlPoints
1790             &vertexInputStateParams,  // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
1791             DE_NULL,                  // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1792             &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
1793     }
1794 
1795     // Create Vertex Buffer
1796     {
1797         VkDeviceSize bufferSize = positionDataSize + textureCoordDataSize;
1798 
1799         // Pad the buffer size to a stride multiple for the last element so that it isn't out of bounds
1800         bufferSize += vertexTextureStrideSize - ((bufferSize - vertexBufferOffset) % vertexTextureStrideSize);
1801 
1802         const VkBufferCreateInfo vertexBufferParams = {
1803             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1804             DE_NULL,                              // const void* pNext;
1805             0u,                                   // VkBufferCreateFlags flags;
1806             bufferSize,                           // VkDeviceSize size;
1807             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // VkBufferUsageFlags usage;
1808             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
1809             1u,                                   // uint32_t queueFamilyCount;
1810             &queueFamilyIndex                     // const uint32_t* pQueueFamilyIndices;
1811         };
1812 
1813         vertexBuffer       = createBuffer(vkd, vkDevice, &vertexBufferParams);
1814         vertexBufferMemory = m_allocator->allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer),
1815                                                    MemoryRequirement::HostVisible);
1816 
1817         VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(),
1818                                       vertexBufferMemory->getOffset()));
1819 
1820         // Load vertices into vertex buffer
1821         deMemcpy(vertexBufferMemory->getHostPtr(), position, positionDataSize);
1822         deMemcpy(reinterpret_cast<uint8_t *>(vertexBufferMemory->getHostPtr()) + positionDataSize, texCoord,
1823                  textureCoordDataSize);
1824         flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(),
1825                                VK_WHOLE_SIZE);
1826     }
1827 
1828     // Create Command Buffer
1829     commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1830 
1831     // Begin Command Buffer
1832     beginCommandBuffer(vkd, *commandBuffer);
1833 
1834     // Begin Render Pass
1835     beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer,
1836                     makeRect2D(0, 0, m_renderWidth, m_renderHeight));
1837 
1838     vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1839     vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1,
1840                               &m_descriptorSet[0].get(), 0u, DE_NULL);
1841     vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 1u, 1,
1842                               &m_descriptorSet[1].get(), 0u, DE_NULL);
1843     vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
1844     vkd.cmdBindVertexBuffers(*commandBuffer, 1, 1, &vertexBuffer.get(), &vertexBufferOffset);
1845     vkd.cmdBindIndexBuffer(*commandBuffer, *m_vertexIndexBuffer, 0, VK_INDEX_TYPE_UINT16);
1846     vkd.cmdDrawIndexed(*commandBuffer, 6, 1, 0, 0, 0);
1847     endRenderPass(vkd, *commandBuffer);
1848 
1849     // Copy Image
1850     {
1851         copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? *m_resolvedImage : *m_image, *m_resultBuffer,
1852                           tcu::IVec2(m_renderWidth, m_renderHeight));
1853 
1854         addImageTransitionBarrier(
1855             *commandBuffer, m_multisampling ? *m_resolvedImage : *m_image,
1856             VK_PIPELINE_STAGE_TRANSFER_BIT,                // VkPipelineStageFlags        srcStageMask
1857             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags        dstStageMask
1858             VK_ACCESS_TRANSFER_READ_BIT,                   // VkAccessFlags            srcAccessMask
1859             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,          // VkAccessFlags            dstAccessMask
1860             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,          // VkImageLayout oldLayout;
1861             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);     // VkImageLayout newLayout;
1862     }
1863 
1864     endCommandBuffer(vkd, *commandBuffer);
1865 
1866     // Upload uniform buffer data
1867     {
1868         const ShaderParameters shaderParameters = {
1869             params.bias,       // float        bias;                //!< User-supplied bias.
1870             params.ref,        // float        ref;                //!< Reference value for shadow lookups.
1871             tcu::Vec2(0.0f),   // tcu::Vec2    padding;            //!< Shader uniform padding.
1872             params.colorScale, // tcu::Vec4    colorScale;            //!< Scale for texture color values.
1873             params.colorBias,  // tcu::Vec4    colorBias;            //!< Bias for texture color values.
1874             params
1875                 .lodTexelFetch // int            lod                    //!< Lod (for usage in Integer Texel Coord tests for VK_EXT_image_view_min_lod)
1876         };
1877         deMemcpy(m_uniformBufferMemory->getHostPtr(), &shaderParameters, sizeof(shaderParameters));
1878         flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(),
1879                                VK_WHOLE_SIZE);
1880 
1881         if (logUniforms)
1882             m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
1883 
1884         if (useBias)
1885         {
1886             if (logUniforms)
1887                 m_log << TestLog::Message << "u_bias = " << shaderParameters.bias << TestLog::EndMessage;
1888         }
1889 
1890         if (params.samplerType == SAMPLERTYPE_SHADOW)
1891         {
1892             if (logUniforms)
1893                 m_log << TestLog::Message << "u_ref = " << shaderParameters.ref << TestLog::EndMessage;
1894         }
1895 
1896         if (logUniforms)
1897         {
1898             m_log << TestLog::Message << "u_colorScale = " << shaderParameters.colorScale << TestLog::EndMessage;
1899             m_log << TestLog::Message << "u_colorBias = " << shaderParameters.colorBias << TestLog::EndMessage;
1900         }
1901 
1902         if (imageViewMinLodIntegerTexelCoord)
1903         {
1904             if (logUniforms)
1905             {
1906                 m_log << TestLog::Message << "u_lod = " << shaderParameters.lod << TestLog::EndMessage;
1907             }
1908         }
1909     }
1910 
1911     // Submit
1912     submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
1913 
1914     invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(),
1915                                 VK_WHOLE_SIZE);
1916 
1917     tcu::copy(result, tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderWidth, m_renderHeight, 1u),
1918                                                   m_resultBufferMemory->getHostPtr()));
1919 }
1920 
1921 /*--------------------------------------------------------------------*//*!
1922  * \brief Map Vulkan sampler parameters to tcu::Sampler.
1923  *
1924  * If no mapping is found, throws tcu::InternalError.
1925  *
1926  * \param wrapU            U-component wrap mode
1927  * \param wrapV            V-component wrap mode
1928  * \param wrapW            W-component wrap mode
1929  * \param minFilterMode    Minification filter mode
1930  * \param magFilterMode    Magnification filter mode
1931  * \return Sampler description.
1932  *//*--------------------------------------------------------------------*/
createSampler(tcu::Sampler::WrapMode wrapU,tcu::Sampler::WrapMode wrapV,tcu::Sampler::WrapMode wrapW,tcu::Sampler::FilterMode minFilterMode,tcu::Sampler::FilterMode magFilterMode,bool normalizedCoords)1933 tcu::Sampler createSampler(tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::WrapMode wrapW,
1934                            tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode,
1935                            bool normalizedCoords)
1936 {
1937     return tcu::Sampler(wrapU, wrapV, wrapW, minFilterMode, magFilterMode, 0.0f /* lod threshold */,
1938                         normalizedCoords /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE /* no compare */,
1939                         0 /* compare channel */, tcu::Vec4(0.0f) /* border color, not used */,
1940                         true /* seamless cube map */);
1941 }
1942 
1943 /*--------------------------------------------------------------------*//*!
1944  * \brief Map Vulkan sampler parameters to tcu::Sampler.
1945  *
1946  * If no mapping is found, throws tcu::InternalError.
1947  *
1948  * \param wrapU            U-component wrap mode
1949  * \param wrapV            V-component wrap mode
1950  * \param minFilterMode    Minification filter mode
1951  * \param minFilterMode    Magnification filter mode
1952  * \return Sampler description.
1953  *//*--------------------------------------------------------------------*/
createSampler(tcu::Sampler::WrapMode wrapU,tcu::Sampler::WrapMode wrapV,tcu::Sampler::FilterMode minFilterMode,tcu::Sampler::FilterMode magFilterMode,bool normalizedCoords)1954 tcu::Sampler createSampler(tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV,
1955                            tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode,
1956                            bool normalizedCoords)
1957 {
1958     return createSampler(wrapU, wrapV, wrapU, minFilterMode, magFilterMode, normalizedCoords);
1959 }
1960 
1961 /*--------------------------------------------------------------------*//*!
1962  * \brief Map Vulkan sampler parameters to tcu::Sampler.
1963  *
1964  * If no mapping is found, throws tcu::InternalError.
1965  *
1966  * \param wrapU            U-component wrap mode
1967  * \param minFilterMode    Minification filter mode
1968  * \return Sampler description.
1969  *//*--------------------------------------------------------------------*/
createSampler(tcu::Sampler::WrapMode wrapU,tcu::Sampler::FilterMode minFilterMode,tcu::Sampler::FilterMode magFilterMode,bool normalizedCoords)1970 tcu::Sampler createSampler(tcu::Sampler::WrapMode wrapU, tcu::Sampler::FilterMode minFilterMode,
1971                            tcu::Sampler::FilterMode magFilterMode, bool normalizedCoords)
1972 {
1973     return createSampler(wrapU, wrapU, wrapU, minFilterMode, magFilterMode, normalizedCoords);
1974 }
1975 
loadTexture2D(const tcu::Archive & archive,const std::vector<std::string> & filenames)1976 TestTexture2DSp loadTexture2D(const tcu::Archive &archive, const std::vector<std::string> &filenames)
1977 {
1978     DE_ASSERT(filenames.size() > 0);
1979 
1980     TestTexture2DSp texture;
1981 
1982     std::string ext = de::FilePath(filenames[0]).getFileExtension();
1983 
1984     if (ext == "png")
1985     {
1986 
1987         for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
1988         {
1989             tcu::TextureLevel level;
1990 
1991             tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
1992 
1993             TCU_CHECK_INTERNAL(
1994                 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
1995                 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
1996 
1997             if (fileIndex == 0)
1998                 texture = TestTexture2DSp(new pipeline::TestTexture2D(
1999                     tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(),
2000                     level.getHeight()));
2001 
2002             tcu::copy(texture->getLevel((int)fileIndex, 0), level.getAccess());
2003         }
2004     }
2005     else if (ext == "pkm")
2006     {
2007 
2008         for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
2009         {
2010             // Compressed texture.
2011             tcu::CompressedTexture level;
2012 
2013             tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
2014 
2015             tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat());
2016             std::vector<uint8_t> uncompressedData(
2017                 uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
2018             tcu::PixelBufferAccess decompressedBuffer(uncompressedFormat, level.getWidth(), level.getHeight(), 1,
2019                                                       uncompressedData.data());
2020 
2021             tcu::TextureFormat commonFormat =
2022                 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
2023             std::vector<uint8_t> commonFromatData(commonFormat.getPixelSize() * level.getWidth() * level.getHeight(),
2024                                                   0);
2025             tcu::PixelBufferAccess commonFormatBuffer(commonFormat, level.getWidth(), level.getHeight(), 1,
2026                                                       commonFromatData.data());
2027 
2028             if (fileIndex == 0)
2029                 texture =
2030                     TestTexture2DSp(new pipeline::TestTexture2D(commonFormat, level.getWidth(), level.getHeight()));
2031 
2032             level.decompress(decompressedBuffer,
2033                              tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
2034 
2035             tcu::copy(commonFormatBuffer, decompressedBuffer);
2036             tcu::copy(texture->getLevel((int)fileIndex, 0), commonFormatBuffer);
2037         }
2038     }
2039     else
2040         TCU_FAIL("Unsupported file format");
2041 
2042     return texture;
2043 }
2044 
loadTextureCube(const tcu::Archive & archive,const std::vector<std::string> & filenames)2045 TestTextureCubeSp loadTextureCube(const tcu::Archive &archive, const std::vector<std::string> &filenames)
2046 {
2047     DE_ASSERT(filenames.size() > 0);
2048     DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
2049     TCU_CHECK((int)filenames.size() % tcu::CUBEFACE_LAST == 0);
2050 
2051     TestTextureCubeSp texture;
2052 
2053     std::string ext = de::FilePath(filenames[0]).getFileExtension();
2054 
2055     if (ext == "png")
2056     {
2057 
2058         for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
2059         {
2060             tcu::TextureLevel level;
2061 
2062             tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str());
2063 
2064             TCU_CHECK_INTERNAL(
2065                 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
2066                 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
2067 
2068             TCU_CHECK(level.getWidth() == level.getHeight());
2069 
2070             if (fileIndex == 0)
2071                 texture = TestTextureCubeSp(new pipeline::TestTextureCube(
2072                     tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth()));
2073 
2074             tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), level.getAccess());
2075         }
2076     }
2077     else if (ext == "pkm")
2078     {
2079         for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex)
2080         {
2081             // Compressed texture.
2082             tcu::CompressedTexture level;
2083 
2084             tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str());
2085 
2086             TCU_CHECK(level.getWidth() == level.getHeight());
2087 
2088             tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat());
2089             std::vector<uint8_t> uncompressedData(
2090                 uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0);
2091             tcu::PixelBufferAccess decompressedBuffer(uncompressedFormat, level.getWidth(), level.getHeight(), 1,
2092                                                       uncompressedData.data());
2093 
2094             tcu::TextureFormat commonFormat =
2095                 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
2096             std::vector<uint8_t> commonFromatData(commonFormat.getPixelSize() * level.getWidth() * level.getHeight(),
2097                                                   0);
2098             tcu::PixelBufferAccess commonFormatBuffer(commonFormat, level.getWidth(), level.getHeight(), 1,
2099                                                       commonFromatData.data());
2100 
2101             if (fileIndex == 0)
2102                 texture = TestTextureCubeSp(new pipeline::TestTextureCube(commonFormat, level.getWidth()));
2103 
2104             level.decompress(decompressedBuffer,
2105                              tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
2106 
2107             tcu::copy(commonFormatBuffer, decompressedBuffer);
2108             tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), commonFormatBuffer);
2109         }
2110     }
2111     else
2112         TCU_FAIL("Unsupported file format");
2113 
2114     return texture;
2115 }
2116 
TextureCommonTestCaseParameters(void)2117 TextureCommonTestCaseParameters::TextureCommonTestCaseParameters(void)
2118     : sampleCount(VK_SAMPLE_COUNT_1_BIT)
2119     , texCoordPrecision(glu::PRECISION_HIGHP)
2120     , minFilter(tcu::Sampler::LINEAR)
2121     , magFilter(tcu::Sampler::LINEAR)
2122     , wrapS(tcu::Sampler::REPEAT_GL)
2123     , format(VK_FORMAT_R8G8B8A8_UNORM)
2124     , unnormal(false)
2125     , aspectMask(VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM)
2126     , testType(TEST_NORMAL)
2127 {
2128 }
2129 
Texture2DTestCaseParameters(void)2130 Texture2DTestCaseParameters::Texture2DTestCaseParameters(void)
2131     : wrapT(tcu::Sampler::REPEAT_GL)
2132     , width(64)
2133     , height(64)
2134     , mipmaps(false)
2135 {
2136 }
2137 
TextureCubeTestCaseParameters(void)2138 TextureCubeTestCaseParameters::TextureCubeTestCaseParameters(void)
2139     : wrapT(tcu::Sampler::REPEAT_GL)
2140     , size(64)
2141     , seamless(true)
2142 {
2143 }
2144 
Texture2DArrayTestCaseParameters(void)2145 Texture2DArrayTestCaseParameters::Texture2DArrayTestCaseParameters(void) : wrapT(tcu::Sampler::REPEAT_GL), numLayers(8)
2146 {
2147 }
2148 
Texture3DTestCaseParameters(void)2149 Texture3DTestCaseParameters::Texture3DTestCaseParameters(void) : wrapR(tcu::Sampler::REPEAT_GL), depth(64)
2150 {
2151 }
2152 
Texture1DTestCaseParameters(void)2153 Texture1DTestCaseParameters::Texture1DTestCaseParameters(void) : width(64)
2154 {
2155 }
2156 
Texture1DArrayTestCaseParameters(void)2157 Texture1DArrayTestCaseParameters::Texture1DArrayTestCaseParameters(void) : numLayers(8)
2158 {
2159 }
2160 
TextureCubeArrayTestCaseParameters(void)2161 TextureCubeArrayTestCaseParameters::TextureCubeArrayTestCaseParameters(void) : numLayers(8)
2162 {
2163 }
2164 
TextureCubeFilteringTestCaseParameters(void)2165 TextureCubeFilteringTestCaseParameters::TextureCubeFilteringTestCaseParameters(void) : onlySampleFaceInterior(false)
2166 {
2167 }
2168 
2169 } // namespace util
2170 } // namespace texture
2171 } // namespace vkt
2172