9998459aeee76bd3aee17020fb1d6af5e16a8f19
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderrender / vktShaderRender.hpp
1 #ifndef _VKTSHADERRENDER_HPP
2 #define _VKTSHADERRENDER_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2015 The Khronos Group Inc.
8  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Vulkan ShaderRenderCase
25  *//*--------------------------------------------------------------------*/
26
27 #include "tcuTexture.hpp"
28 #include "tcuSurface.hpp"
29
30 #include "deMemory.h"
31 #include "deSharedPtr.hpp"
32 #include "deUniquePtr.hpp"
33
34 #include "vkDefs.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkRef.hpp"
37 #include "vkMemUtil.hpp"
38 #include "vkBuilderUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkPlatform.hpp"
41
42 #include "vktTestCaseUtil.hpp"
43
44 namespace vkt
45 {
46 namespace sr
47 {
48
49 class LineStream
50 {
51 public:
52                                                 LineStream              (int indent = 0)        { m_indent = indent; }
53                                                 ~LineStream             (void)                          {}
54
55         const char*                     str                             (void) const            { m_string = m_stream.str(); return m_string.c_str(); }
56         LineStream&                     operator<<              (const char* line)      { for (int i = 0; i < m_indent; i++) { m_stream << "\t"; } m_stream << line << "\n"; return *this; }
57
58 private:
59         int                                     m_indent;
60         std::ostringstream      m_stream;
61         mutable std::string     m_string;
62 };
63
64 class QuadGrid;
65 class ShaderRenderCaseInstance;
66
67 class TextureBinding
68 {
69 public:
70         enum Type
71         {
72                 TYPE_NONE = 0,
73                 TYPE_2D,
74                 TYPE_CUBE_MAP,
75                 TYPE_2D_ARRAY,
76                 TYPE_3D,
77
78                 TYPE_LAST
79         };
80
81         struct Parameters
82         {
83                 deUint32                                        baseMipLevel;
84                 vk::VkComponentMapping          componentMapping;
85
86                 Parameters (deUint32                                    baseMipLevel_           = 0,
87                                         vk::VkComponentMapping          componentMapping_       = vk::makeComponentMappingRGBA())
88                         : baseMipLevel          (baseMipLevel_)
89                         , componentMapping      (componentMapping_)
90                 {
91                 }
92         };
93
94                                                                                 TextureBinding          (const tcu::Archive&    archive,
95                                                                                                                         const char*                             filename,
96                                                                                                                         const Type                              type,
97                                                                                                                         const tcu::Sampler&             sampler);
98                                                                                 TextureBinding          (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler);
99                                                                                 TextureBinding          (const tcu::TextureCube* texCube, const tcu::Sampler& sampler);
100                                                                                 TextureBinding          (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler);
101                                                                                 TextureBinding          (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler);
102                                                                                 ~TextureBinding         (void);
103
104         Type                                                            getType                         (void) const { return m_type;           }
105         const tcu::Sampler&                                     getSampler                      (void) const { return m_sampler;        }
106         const tcu::Texture2D&                           get2D                           (void) const { DE_ASSERT(getType() == TYPE_2D && m_binding.tex2D != NULL);                              return *m_binding.tex2D;                }
107         const tcu::TextureCube&                         getCube                         (void) const { DE_ASSERT(getType() == TYPE_CUBE_MAP && m_binding.texCube != NULL);              return *m_binding.texCube;              }
108         const tcu::Texture2DArray&                      get2DArray                      (void) const { DE_ASSERT(getType() == TYPE_2D_ARRAY && m_binding.tex2DArray != NULL);   return *m_binding.tex2DArray;   }
109         const tcu::Texture3D&                           get3D                           (void) const { DE_ASSERT(getType() == TYPE_3D && m_binding.tex3D != NULL);                              return *m_binding.tex3D;                }
110
111         void                                                            setParameters           (const Parameters& params) { m_params = params; }
112         const Parameters&                                       getParameters           (void) const { return m_params; }
113
114 private:
115                                                                                 TextureBinding          (const TextureBinding&);        // not allowed!
116         TextureBinding&                                         operator=                       (const TextureBinding&);        // not allowed!
117
118         static de::MovePtr<tcu::Texture2D>      loadTexture2D           (const tcu::Archive& archive, const char* filename);
119
120         Type                                                            m_type;
121         tcu::Sampler                                            m_sampler;
122         Parameters                                                      m_params;
123
124         union
125         {
126                 const tcu::Texture2D*                   tex2D;
127                 const tcu::TextureCube*                 texCube;
128                 const tcu::Texture2DArray*              tex2DArray;
129                 const tcu::Texture3D*                   tex3D;
130         } m_binding;
131 };
132
133 typedef de::SharedPtr<TextureBinding> TextureBindingSp;
134
135 // ShaderEvalContext.
136
137 class ShaderEvalContext
138 {
139 public:
140         // Limits.
141         enum
142         {
143                 MAX_USER_ATTRIBS        = 4,
144                 MAX_TEXTURES            = 4
145         };
146
147         struct ShaderSampler
148         {
149                 tcu::Sampler                            sampler;
150                 const tcu::Texture2D*           tex2D;
151                 const tcu::TextureCube*         texCube;
152                 const tcu::Texture2DArray*      tex2DArray;
153                 const tcu::Texture3D*           tex3D;
154
155                 inline ShaderSampler (void)
156                         : tex2D         (DE_NULL)
157                         , texCube       (DE_NULL)
158                         , tex2DArray(DE_NULL)
159                         , tex3D         (DE_NULL)
160                 {
161                 }
162         };
163
164                                                         ShaderEvalContext               (const QuadGrid& quadGrid);
165                                                         ~ShaderEvalContext              (void);
166
167         void                                    reset                                   (float sx, float sy);
168
169         // Inputs.
170         tcu::Vec4                               coords;
171         tcu::Vec4                               unitCoords;
172         tcu::Vec4                               constCoords;
173
174         tcu::Vec4                               in[MAX_USER_ATTRIBS];
175         ShaderSampler                   textures[MAX_TEXTURES];
176
177         // Output.
178         tcu::Vec4                               color;
179         bool                                    isDiscarded;
180
181         // Functions.
182         inline void                             discard                                 (void)  { isDiscarded = true; }
183         tcu::Vec4                               texture2D                               (int unitNdx, const tcu::Vec2& coords);
184
185 private:
186         const QuadGrid&                 m_quadGrid;
187 };
188
189 typedef void (*ShaderEvalFunc) (ShaderEvalContext& c);
190
191 inline void evalCoordsPassthroughX              (ShaderEvalContext& c) { c.color.x() = c.coords.x(); }
192 inline void evalCoordsPassthroughXY             (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); }
193 inline void evalCoordsPassthroughXYZ    (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
194 inline void evalCoordsPassthrough               (ShaderEvalContext& c) { c.color = c.coords; }
195 inline void evalCoordsSwizzleWZYX               (ShaderEvalContext& c) { c.color = c.coords.swizzle(3,2,1,0); }
196
197 // ShaderEvaluator
198 // Either inherit a class with overridden evaluate() or just pass in an evalFunc.
199
200 class ShaderEvaluator
201 {
202 public:
203                                                         ShaderEvaluator                 (void);
204                                                         ShaderEvaluator                 (const ShaderEvalFunc evalFunc);
205         virtual                                 ~ShaderEvaluator                (void);
206
207         virtual void                    evaluate                                (ShaderEvalContext& ctx) const;
208
209 private:
210                                                         ShaderEvaluator                 (const ShaderEvaluator&);   // not allowed!
211         ShaderEvaluator&                operator=                               (const ShaderEvaluator&);   // not allowed!
212
213         const ShaderEvalFunc    m_evalFunc;
214 };
215
216 // UniformSetup
217
218 typedef void (*UniformSetupFunc) (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords);
219
220 class UniformSetup
221 {
222 public:
223                                                         UniformSetup                    (void);
224                                                         UniformSetup                    (const UniformSetupFunc setup);
225         virtual                                 ~UniformSetup                   (void);
226         virtual void                    setup                                   (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const;
227
228 private:
229                                                         UniformSetup                    (const UniformSetup&);  // not allowed!
230         UniformSetup&                   operator=                               (const UniformSetup&);  // not allowed!
231
232         const UniformSetupFunc  m_setupFunc;
233 };
234
235 typedef void (*AttributeSetupFunc) (ShaderRenderCaseInstance& instance, deUint32 numVertices);
236
237 class ShaderRenderCase : public vkt::TestCase
238 {
239 public:
240                                                                                                         ShaderRenderCase        (tcu::TestContext&                      testCtx,
241                                                                                                                                                  const std::string&                     name,
242                                                                                                                                                  const std::string&                     description,
243                                                                                                                                                  const bool                                     isVertexCase,
244                                                                                                                                                  const ShaderEvalFunc           evalFunc,
245                                                                                                                                                  const UniformSetup*            uniformSetup,
246                                                                                                                                                  const AttributeSetupFunc       attribFunc);
247
248                                                                                                         ShaderRenderCase        (tcu::TestContext&                      testCtx,
249                                                                                                                                                  const std::string&                     name,
250                                                                                                                                                  const std::string&                     description,
251                                                                                                                                                  const bool                                     isVertexCase,
252                                                                                                                                                  const ShaderEvaluator*         evaluator,
253                                                                                                                                                  const UniformSetup*            uniformSetup,
254                                                                                                                                                  const AttributeSetupFunc       attribFunc);
255
256         virtual                                                                                 ~ShaderRenderCase       (void);
257         virtual void                                                                    initPrograms            (vk::SourceCollections& programCollection) const;
258         virtual TestInstance*                                                   createInstance          (Context& context) const;
259
260 protected:
261         std::string                                                                             m_vertShaderSource;
262         std::string                                                                             m_fragShaderSource;
263
264         const bool                                                                              m_isVertexCase;
265         const de::UniquePtr<const ShaderEvaluator>              m_evaluator;
266         const de::UniquePtr<const UniformSetup>                 m_uniformSetup;
267         const AttributeSetupFunc                                                m_attribFunc;
268 };
269
270 enum BaseUniformType
271 {
272 // Bool
273         UB_FALSE,
274         UB_TRUE,
275
276 // BVec4
277         UB4_FALSE,
278         UB4_TRUE,
279
280 // Integers
281         UI_ZERO,
282         UI_ONE,
283         UI_TWO,
284         UI_THREE,
285         UI_FOUR,
286         UI_FIVE,
287         UI_SIX,
288         UI_SEVEN,
289         UI_EIGHT,
290         UI_ONEHUNDREDONE,
291
292 // IVec2
293         UI2_MINUS_ONE,
294         UI2_ZERO,
295         UI2_ONE,
296         UI2_TWO,
297         UI2_THREE,
298         UI2_FOUR,
299         UI2_FIVE,
300
301 // IVec3
302         UI3_MINUS_ONE,
303         UI3_ZERO,
304         UI3_ONE,
305         UI3_TWO,
306         UI3_THREE,
307         UI3_FOUR,
308         UI3_FIVE,
309
310 // IVec4
311         UI4_MINUS_ONE,
312         UI4_ZERO,
313         UI4_ONE,
314         UI4_TWO,
315         UI4_THREE,
316         UI4_FOUR,
317         UI4_FIVE,
318
319 // Float
320         UF_ZERO,
321         UF_ONE,
322         UF_TWO,
323         UF_THREE,
324         UF_FOUR,
325         UF_FIVE,
326         UF_SIX,
327         UF_SEVEN,
328         UF_EIGHT,
329
330         UF_HALF,
331         UF_THIRD,
332         UF_FOURTH,
333         UF_FIFTH,
334         UF_SIXTH,
335         UF_SEVENTH,
336         UF_EIGHTH,
337
338 // Vec2
339         UV2_MINUS_ONE,
340         UV2_ZERO,
341         UV2_ONE,
342         UV2_TWO,
343         UV2_THREE,
344
345         UV2_HALF,
346
347 // Vec3
348         UV3_MINUS_ONE,
349         UV3_ZERO,
350         UV3_ONE,
351         UV3_TWO,
352         UV3_THREE,
353
354         UV3_HALF,
355
356 // Vec4
357         UV4_MINUS_ONE,
358         UV4_ZERO,
359         UV4_ONE,
360         UV4_TWO,
361         UV4_THREE,
362
363         UV4_HALF,
364
365         UV4_BLACK,
366         UV4_GRAY,
367         UV4_WHITE,
368
369 // Last
370         U_LAST
371 };
372
373 enum BaseAttributeType
374 {
375 // User attributes
376         A_IN0,
377         A_IN1,
378         A_IN2,
379         A_IN3,
380
381 // Matrices
382         MAT2,
383         MAT2x3,
384         MAT2x4,
385         MAT3x2,
386         MAT3,
387         MAT3x4,
388         MAT4x2,
389         MAT4x3,
390         MAT4
391 };
392
393 // ShaderRenderCaseInstance.
394
395 class ShaderRenderCaseInstance : public vkt::TestInstance
396 {
397 public:
398                                                                                                                 ShaderRenderCaseInstance        (Context&                                       context,
399                                                                                                                                                                         const bool                                      isVertexCase,
400                                                                                                                                                                         const ShaderEvaluator&          evaluator,
401                                                                                                                                                                         const UniformSetup&                     uniformSetup,
402                                                                                                                                                                         const AttributeSetupFunc        attribFunc);
403
404         virtual                                                                                         ~ShaderRenderCaseInstance       (void);
405         virtual tcu::TestStatus                                                         iterate                                         (void);
406
407         void                                                                                            addAttribute                            (deUint32                       bindingLocation,
408                                                                                                                                                                         vk::VkFormat            format,
409                                                                                                                                                                         deUint32                        sizePerElement,
410                                                                                                                                                                         deUint32                        count,
411                                                                                                                                                                         const void*                     data);
412         void                                                                                            useAttribute                            (deUint32                       bindingLocation,
413                                                                                                                                                                         BaseAttributeType       type);
414
415         template<typename T>
416         void                                                                                            addUniform                                      (deUint32                               bindingLocation,
417                                                                                                                                                                         vk::VkDescriptorType    descriptorType,
418                                                                                                                                                                         const T&                                data);
419         void                                                                                            addUniform                                      (deUint32                               bindingLocation,
420                                                                                                                                                                         vk::VkDescriptorType    descriptorType,
421                                                                                                                                                                         size_t                                  dataSize,
422                                                                                                                                                                         const void*                             data);
423         void                                                                                            useUniform                                      (deUint32                               bindingLocation,
424                                                                                                                                                                         BaseUniformType                 type);
425         void                                                                                            useSampler                                      (deUint32                               bindingLocation,
426                                                                                                                                                                         deUint32                                textureId);
427
428         static const tcu::Vec4                                                          getDefaultConstCoords           (void) { return tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); }
429
430 protected:
431                                                                                                                 ShaderRenderCaseInstance        (Context&                                       context,
432                                                                                                                                                                          const bool                                     isVertexCase,
433                                                                                                                                                                          const ShaderEvaluator*         evaluator,
434                                                                                                                                                                          const UniformSetup*            uniformSetup,
435                                                                                                                                                                          const AttributeSetupFunc       attribFunc);
436
437         virtual void                                                                            setup                                           (void);
438         virtual void                                                                            setupUniforms                           (const tcu::Vec4& constCoords);
439         virtual void                                                                            setupDefaultInputs                      (void);
440
441         void                                                                                            render                                          (deUint32                                       numVertices,
442                                                                                                                                                                          deUint32                                       numTriangles,
443                                                                                                                                                                          const deUint16*                        indices,
444                                                                                                                                                                          const tcu::Vec4&                       constCoords             = getDefaultConstCoords());
445
446         const tcu::TextureLevel&                                                        getResultImage                          (void) const { return m_resultImage; }
447
448         const tcu::UVec2                                                                        getViewportSize                         (void) const;
449
450         void                                                                                            setSampleCount                          (vk::VkSampleCountFlagBits sampleCount);
451
452         bool                                                                                            isMultiSampling                         (void) const;
453         
454         vk::Allocator&                                                                          m_memAlloc;
455         const tcu::Vec4                                                                         m_clearColor;
456         const bool                                                                                      m_isVertexCase;
457
458         std::vector<tcu::Mat4>                                                          m_userAttribTransforms;
459         std::vector<TextureBindingSp>                                           m_textures;
460
461         std::string                                                                                     m_vertexShaderName;
462         std::string                                                                                     m_fragmentShaderName;
463         tcu::UVec2                                                                                      m_renderSize;
464         vk::VkFormat                                                                            m_colorFormat;
465
466 private:
467         typedef std::vector<tcu::ConstPixelBufferAccess>        TextureLayerData;
468         typedef std::vector<TextureLayerData>                           TextureData;
469
470         void                                                                                            uploadImage                                     (const tcu::TextureFormat&              texFormat,
471                                                                                                                                                                          const TextureData&                             textureData,
472                                                                                                                                                                          const tcu::Sampler&                    refSampler,
473                                                                                                                                                                          deUint32                                               mipLevels,
474                                                                                                                                                                          deUint32                                               arrayLayers,
475                                                                                                                                                                          vk::VkImage                                    destImage);
476
477         void                                                                                            createSamplerUniform            (deUint32                                               bindingLocation,
478                                                                                                                                                                          TextureBinding::Type                   textureType,
479                                                                                                                                                                          const tcu::TextureFormat&              texFormat,
480                                                                                                                                                                          const tcu::IVec3                               texSize,
481                                                                                                                                                                          const TextureData&                             textureData,
482                                                                                                                                                                          const tcu::Sampler&                    refSampler,
483                                                                                                                                                                          deUint32                                               mipLevels,
484                                                                                                                                                                          deUint32                                               arrayLayers,
485                                                                                                                                                                          TextureBinding::Parameters             textureParams);
486
487         void                                                                                            setupUniformData                        (deUint32 bindingLocation, size_t size, const void* dataPtr);
488
489         void                                                                                            computeVertexReference          (tcu::Surface& result, const QuadGrid& quadGrid);
490         void                                                                                            computeFragmentReference        (tcu::Surface& result, const QuadGrid& quadGrid);
491         bool                                                                                            compareImages                           (const tcu::Surface&    resImage,
492                                                                                                                                                                          const tcu::Surface&    refImage,
493                                                                                                                                                                          float                                  errorThreshold);
494
495 private:
496         const ShaderEvaluator*                                                          m_evaluator;
497         const UniformSetup*                                                                     m_uniformSetup;
498         const AttributeSetupFunc                                                        m_attribFunc;
499
500         de::MovePtr<QuadGrid>                                                           m_quadGrid;
501         tcu::TextureLevel                                                                       m_resultImage;
502
503         struct EnabledBaseAttribute
504         {
505                 deUint32                        location;
506                 BaseAttributeType       type;
507         };
508         std::vector<EnabledBaseAttribute>                                       m_enabledBaseAttributes;
509
510         de::MovePtr<vk::DescriptorSetLayoutBuilder>                     m_descriptorSetLayoutBuilder;
511         de::MovePtr<vk::DescriptorPoolBuilder>                          m_descriptorPoolBuilder;
512         de::MovePtr<vk::DescriptorSetUpdateBuilder>                     m_descriptorSetUpdateBuilder;
513
514         typedef de::SharedPtr<vk::Unique<vk::VkBuffer> >                VkBufferSp;
515         typedef de::SharedPtr<vk::Unique<vk::VkImage> >                 VkImageSp;
516         typedef de::SharedPtr<vk::Unique<vk::VkImageView> >             VkImageViewSp;
517         typedef de::SharedPtr<vk::Unique<vk::VkSampler> >               VkSamplerSp;
518         typedef de::SharedPtr<vk::Allocation>                                   AllocationSp;
519
520         class UniformInfo
521         {
522         public:
523                                                                         UniformInfo             (void) {}
524                 virtual                                         ~UniformInfo    (void) {}
525
526                 vk::VkDescriptorType            type;
527                 deUint32                                        location;
528         };
529
530         class BufferUniform : public UniformInfo
531         {
532         public:
533                                                                         BufferUniform   (void) {}
534                 virtual                                         ~BufferUniform  (void) {}
535
536                 VkBufferSp                                      buffer;
537                 AllocationSp                            alloc;
538                 vk::VkDescriptorBufferInfo      descriptor;
539         };
540
541         class SamplerUniform : public UniformInfo
542         {
543         public:
544                                                                         SamplerUniform  (void) {}
545                 virtual                                         ~SamplerUniform (void) {}
546
547                 VkImageSp                                       image;
548                 VkImageViewSp                           imageView;
549                 VkSamplerSp                                     sampler;
550                 AllocationSp                            alloc;
551                 vk::VkDescriptorImageInfo       descriptor;
552         };
553
554         typedef de::SharedPtr<de::UniquePtr<UniformInfo> >      UniformInfoSp;
555         std::vector<UniformInfoSp>                                                      m_uniformInfos;
556
557         std::vector<vk::VkVertexInputBindingDescription>        m_vertexBindingDescription;
558         std::vector<vk::VkVertexInputAttributeDescription>      m_vertexAttributeDescription;
559
560         std::vector<VkBufferSp>                                                         m_vertexBuffers;
561         std::vector<AllocationSp>                                                       m_vertexBufferAllocs;
562
563         vk::VkSampleCountFlagBits                                                       m_sampleCount;
564 };
565
566 template<typename T>
567 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, const T& data)
568 {
569         addUniform(bindingLocation, descriptorType, sizeof(T), &data);
570 }
571
572 } // sr
573 } // vkt
574
575 #endif // _VKTSHADERRENDER_HPP