Merge branch 'jekstrand_renderpass_transfer_bit_fix' into 'master'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderrender / vktShaderRenderDiscardTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Shader discard statement tests.
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktShaderRenderDiscardTests.hpp"
37 #include "vktShaderRender.hpp"
38 #include "tcuStringTemplate.hpp"
39 #include "gluTexture.hpp"
40
41 #include <string>
42
43 using tcu::StringTemplate;
44
45 namespace vkt
46 {
47 namespace sr
48 {
49 namespace
50 {
51
52 class SamplerUniformSetup : public UniformSetup
53 {
54 public:
55                                                 SamplerUniformSetup                     (bool useSampler)
56                                                         : m_useSampler(useSampler)
57                                                 {}
58
59         virtual void            setup                                            (ShaderRenderCaseInstance& instance, const tcu::Vec4&) const
60                                                 {
61                                                         instance.useUniform(0u, UI_ONE);
62                                                         instance.useUniform(1u, UI_TWO);
63                                                         if (m_useSampler)
64                                                                 instance.useSampler2D(2u, 0u); // To the uniform binding location 2 bind the texture 0
65                                                 }
66
67 private:
68         const bool                      m_useSampler;
69 };
70
71
72 class ShaderDiscardCaseInstance : public ShaderRenderCaseInstance
73 {
74 public:
75                                                 ShaderDiscardCaseInstance       (Context&                               context,
76                                                                                                         bool                                    isVertexCase,
77                                                                                                         const ShaderEvaluator&  evaluator,
78                                                                                                         const UniformSetup&             uniformSetup,
79                                                                                                         bool                                    usesTexture);
80         virtual                         ~ShaderDiscardCaseInstance      (void);
81 };
82
83 ShaderDiscardCaseInstance::ShaderDiscardCaseInstance (Context&                                  context,
84                                                                                                          bool                                           isVertexCase,
85                                                                                                          const ShaderEvaluator&         evaluator,
86                                                                                                          const UniformSetup&            uniformSetup,
87                                                                                                          bool                                           usesTexture)
88         : ShaderRenderCaseInstance      (context, isVertexCase, evaluator, uniformSetup, DE_NULL)
89 {
90         if (usesTexture)
91         {
92                 de::SharedPtr<TextureBinding> brickTexture(new TextureBinding(m_context.getTestContext().getArchive(),
93                                                                                                                                           "vulkan/data/brick.png",
94                                                                                                                                           TextureBinding::TYPE_2D,
95                                                                                                                                           tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE,
96                                                                                                                                                                         tcu::Sampler::CLAMP_TO_EDGE,
97                                                                                                                                                                         tcu::Sampler::CLAMP_TO_EDGE,
98                                                                                                                                                                         tcu::Sampler::LINEAR,
99                                                                                                                                                                         tcu::Sampler::LINEAR)));
100                 m_textures.push_back(brickTexture);
101         }
102 }
103
104 ShaderDiscardCaseInstance::~ShaderDiscardCaseInstance (void)
105 {
106 }
107
108 class ShaderDiscardCase : public ShaderRenderCase
109 {
110 public:
111                                                         ShaderDiscardCase                       (tcu::TestContext&              testCtx,
112                                                                                                                  const char*                    name,
113                                                                                                                  const char*                    description,
114                                                                                                                  const char*                    shaderSource,
115                                                                                                                  const ShaderEvalFunc   evalFunc,
116                                                                                                                  bool                                   usesTexture);
117         virtual TestInstance*   createInstance                          (Context& context) const
118                                                         {
119                                                                 DE_ASSERT(m_evaluator != DE_NULL);
120                                                                 DE_ASSERT(m_uniformSetup != DE_NULL);
121                                                                 return new ShaderDiscardCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_usesTexture);
122                                                         }
123
124 private:
125         const bool                              m_usesTexture;
126 };
127
128 ShaderDiscardCase::ShaderDiscardCase (tcu::TestContext&         testCtx,
129                                                                           const char*                   name,
130                                                                           const char*                   description,
131                                                                           const char*                   shaderSource,
132                                                                           const ShaderEvalFunc  evalFunc,
133                                                                           bool                                  usesTexture)
134         : ShaderRenderCase      (testCtx, name, description, false, evalFunc, new SamplerUniformSetup(usesTexture), DE_NULL)
135         , m_usesTexture         (usesTexture)
136 {
137         m_fragShaderSource      = shaderSource;
138         m_vertShaderSource      =
139                 "#version 310 es\n"
140                 "#extension GL_ARB_separate_shader_objects : enable\n"
141                 "#extension GL_ARB_shading_language_420pack : enable\n"
142                 "layout(location=0) in  highp   vec4 a_position;\n"
143                 "layout(location=1) in  highp   vec4 a_coords;\n"
144                 "layout(location=0) out mediump vec4 v_color;\n"
145                 "layout(location=1) out mediump vec4 v_coords;\n\n"
146                 "void main (void)\n"
147                 "{\n"
148                 "    gl_Position = a_position;\n"
149                 "    v_color = vec4(a_coords.xyz, 1.0);\n"
150                 "    v_coords = a_coords;\n"
151                 "}\n";
152 }
153
154
155 enum DiscardMode
156 {
157         DISCARDMODE_ALWAYS = 0,
158         DISCARDMODE_NEVER,
159         DISCARDMODE_UNIFORM,
160         DISCARDMODE_DYNAMIC,
161         DISCARDMODE_TEXTURE,
162
163         DISCARDMODE_LAST
164 };
165
166 enum DiscardTemplate
167 {
168         DISCARDTEMPLATE_MAIN_BASIC = 0,
169         DISCARDTEMPLATE_FUNCTION_BASIC,
170         DISCARDTEMPLATE_MAIN_STATIC_LOOP,
171         DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP,
172         DISCARDTEMPLATE_FUNCTION_STATIC_LOOP,
173
174         DISCARDTEMPLATE_LAST
175 };
176
177 // Evaluation functions
178 inline void evalDiscardAlways   (ShaderEvalContext& c) { c.discard(); }
179 inline void evalDiscardNever    (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
180 inline void evalDiscardDynamic  (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); if (c.coords.x()+c.coords.y() > 0.0f) c.discard(); }
181
182 inline void evalDiscardTexture (ShaderEvalContext& c)
183 {
184         c.color.xyz() = c.coords.swizzle(0,1,2);
185         if (c.texture2D(0, c.coords.swizzle(0,1) * 0.25f + 0.5f).x() < 0.7f)
186                 c.discard();
187 }
188
189 static ShaderEvalFunc getEvalFunc (DiscardMode mode)
190 {
191         switch (mode)
192         {
193                 case DISCARDMODE_ALWAYS:        return evalDiscardAlways;
194                 case DISCARDMODE_NEVER:         return evalDiscardNever;
195                 case DISCARDMODE_UNIFORM:       return evalDiscardAlways;
196                 case DISCARDMODE_DYNAMIC:       return evalDiscardDynamic;
197                 case DISCARDMODE_TEXTURE:       return evalDiscardTexture;
198                 default:
199                         DE_ASSERT(DE_FALSE);
200                         return evalDiscardAlways;
201         }
202 }
203
204 static const char* getTemplate (DiscardTemplate variant)
205 {
206         #define GLSL_SHADER_TEMPLATE_HEADER \
207                                 "#version 310 es\n"     \
208                                 "#extension GL_ARB_separate_shader_objects : enable\n"  \
209                                 "#extension GL_ARB_shading_language_420pack : enable\n"  \
210                                 "layout(location = 0) in mediump vec4 v_color;\n"       \
211                                 "layout(location = 1) in mediump vec4 v_coords;\n"      \
212                                 "layout(location = 0) out mediump vec4 o_color;\n"      \
213                                 "layout(set = 0, binding = 2) uniform sampler2D    ut_brick;\n" \
214                                 "layout(set = 0, binding = 0) uniform block0 { mediump int  ui_one; };\n\n"
215
216         switch (variant)
217         {
218                 case DISCARDTEMPLATE_MAIN_BASIC:
219                         return GLSL_SHADER_TEMPLATE_HEADER
220                                    "void main (void)\n"
221                                    "{\n"
222                                    "    o_color = v_color;\n"
223                                    "    ${DISCARD};\n"
224                                    "}\n";
225
226                 case DISCARDTEMPLATE_FUNCTION_BASIC:
227                         return GLSL_SHADER_TEMPLATE_HEADER
228                                    "void myfunc (void)\n"
229                                    "{\n"
230                                    "    ${DISCARD};\n"
231                                    "}\n\n"
232                                    "void main (void)\n"
233                                    "{\n"
234                                    "    o_color = v_color;\n"
235                                    "    myfunc();\n"
236                                    "}\n";
237
238                 case DISCARDTEMPLATE_MAIN_STATIC_LOOP:
239                         return GLSL_SHADER_TEMPLATE_HEADER
240                                    "void main (void)\n"
241                                    "{\n"
242                                    "    o_color = v_color;\n"
243                                    "    for (int i = 0; i < 2; i++)\n"
244                                    "    {\n"
245                                    "        if (i > 0)\n"
246                                    "            ${DISCARD};\n"
247                                    "    }\n"
248                                    "}\n";
249
250                 case DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP:
251                         return GLSL_SHADER_TEMPLATE_HEADER
252                                    "layout(set = 0, binding = 1) uniform block1 { mediump int  ui_two; };\n\n"
253                                    "void main (void)\n"
254                                    "{\n"
255                                    "    o_color = v_color;\n"
256                                    "    for (int i = 0; i < ui_two; i++)\n"
257                                    "    {\n"
258                                    "        if (i > 0)\n"
259                                    "            ${DISCARD};\n"
260                                    "    }\n"
261                                    "}\n";
262
263                 case DISCARDTEMPLATE_FUNCTION_STATIC_LOOP:
264                         return GLSL_SHADER_TEMPLATE_HEADER
265                                    "void myfunc (void)\n"
266                                    "{\n"
267                                    "    for (int i = 0; i < 2; i++)\n"
268                                    "    {\n"
269                                    "        if (i > 0)\n"
270                                    "            ${DISCARD};\n"
271                                    "    }\n"
272                                    "}\n\n"
273                                    "void main (void)\n"
274                                    "{\n"
275                                    "    o_color = v_color;\n"
276                                    "    myfunc();\n"
277                                    "}\n";
278
279                 default:
280                         DE_ASSERT(DE_FALSE);
281                         return DE_NULL;
282         }
283
284         #undef GLSL_SHADER_TEMPLATE_HEADER
285 }
286
287 static const char* getTemplateName (DiscardTemplate variant)
288 {
289         switch (variant)
290         {
291                 case DISCARDTEMPLATE_MAIN_BASIC:                        return "basic";
292                 case DISCARDTEMPLATE_FUNCTION_BASIC:            return "function";
293                 case DISCARDTEMPLATE_MAIN_STATIC_LOOP:          return "static_loop";
294                 case DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP:         return "dynamic_loop";
295                 case DISCARDTEMPLATE_FUNCTION_STATIC_LOOP:      return "function_static_loop";
296                 default:
297                         DE_ASSERT(DE_FALSE);
298                         return DE_NULL;
299         }
300 }
301
302 static const char* getModeName (DiscardMode mode)
303 {
304         switch (mode)
305         {
306                 case DISCARDMODE_ALWAYS:        return "always";
307                 case DISCARDMODE_NEVER:         return "never";
308                 case DISCARDMODE_UNIFORM:       return "uniform";
309                 case DISCARDMODE_DYNAMIC:       return "dynamic";
310                 case DISCARDMODE_TEXTURE:       return "texture";
311                 default:
312                         DE_ASSERT(DE_FALSE);
313                         return DE_NULL;
314         }
315 }
316
317 static const char* getTemplateDesc (DiscardTemplate variant)
318 {
319         switch (variant)
320         {
321                 case DISCARDTEMPLATE_MAIN_BASIC:                        return "main";
322                 case DISCARDTEMPLATE_FUNCTION_BASIC:            return "function";
323                 case DISCARDTEMPLATE_MAIN_STATIC_LOOP:          return "static loop";
324                 case DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP:         return "dynamic loop";
325                 case DISCARDTEMPLATE_FUNCTION_STATIC_LOOP:      return "static loop in function";
326                 default:
327                         DE_ASSERT(DE_FALSE);
328                         return DE_NULL;
329         }
330 }
331
332 static const char* getModeDesc (DiscardMode mode)
333 {
334         switch (mode)
335         {
336                 case DISCARDMODE_ALWAYS:        return "Always discard";
337                 case DISCARDMODE_NEVER:         return "Never discard";
338                 case DISCARDMODE_UNIFORM:       return "Discard based on uniform value";
339                 case DISCARDMODE_DYNAMIC:       return "Discard based on varying values";
340                 case DISCARDMODE_TEXTURE:       return "Discard based on texture value";
341                 default:
342                         DE_ASSERT(DE_FALSE);
343                         return DE_NULL;
344         }
345 }
346
347 de::MovePtr<ShaderDiscardCase> makeDiscardCase (tcu::TestContext& testCtx, DiscardTemplate tmpl, DiscardMode mode)
348 {
349         StringTemplate shaderTemplate(getTemplate(tmpl));
350
351         std::map<std::string, std::string> params;
352
353         switch (mode)
354         {
355                 case DISCARDMODE_ALWAYS:        params["DISCARD"] = "discard";                                                                          break;
356                 case DISCARDMODE_NEVER:         params["DISCARD"] = "if (false) discard";                                                       break;
357                 case DISCARDMODE_UNIFORM:       params["DISCARD"] = "if (ui_one > 0) discard";                                          break;
358                 case DISCARDMODE_DYNAMIC:       params["DISCARD"] = "if (v_coords.x+v_coords.y > 0.0) discard";         break;
359                 case DISCARDMODE_TEXTURE:       params["DISCARD"] = "if (texture(ut_brick, v_coords.xy*0.25+0.5).x < 0.7) discard";     break;
360                 default:
361                         DE_ASSERT(DE_FALSE);
362                         break;
363         }
364
365         std::string name                = std::string(getTemplateName(tmpl)) + "_" + getModeName(mode);
366         std::string description = std::string(getModeDesc(mode)) + " in " + getTemplateDesc(tmpl);
367
368         return de::MovePtr<ShaderDiscardCase>(new ShaderDiscardCase(testCtx, name.c_str(), description.c_str(), shaderTemplate.specialize(params).c_str(), getEvalFunc(mode), mode == DISCARDMODE_TEXTURE));
369 }
370
371 class ShaderDiscardTests : public tcu::TestCaseGroup
372 {
373 public:
374                                                         ShaderDiscardTests              (tcu::TestContext& textCtx);
375         virtual                                 ~ShaderDiscardTests             (void);
376
377         virtual void                    init                                    (void);
378
379 private:
380                                                         ShaderDiscardTests              (const ShaderDiscardTests&);            // not allowed!
381         ShaderDiscardTests&             operator=                               (const ShaderDiscardTests&);            // not allowed!
382 };
383
384 ShaderDiscardTests::ShaderDiscardTests (tcu::TestContext& testCtx)
385         : TestCaseGroup(testCtx, "discard", "Discard statement tests")
386 {
387 }
388
389 ShaderDiscardTests::~ShaderDiscardTests (void)
390 {
391 }
392
393 void ShaderDiscardTests::init (void)
394 {
395         for (int tmpl = 0; tmpl < DISCARDTEMPLATE_LAST; tmpl++)
396                 for (int mode = 0; mode < DISCARDMODE_LAST; mode++)
397                         addChild(makeDiscardCase(m_testCtx, (DiscardTemplate)tmpl, (DiscardMode)mode).release());
398 }
399
400 } // anonymous
401
402 tcu::TestCaseGroup* createDiscardTests (tcu::TestContext& testCtx)
403 {
404         return new ShaderDiscardTests(testCtx);
405 }
406
407 } // sr
408 } // vkt