Merge vk-gl-cts/vulkan-cts-1.1.5 into vk-gl-cts/vulkan-cts-1.2.0
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / geometry / vktGeometryVaryingGeometryShaderTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Varying Geometry Shader Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktGeometryVaryingGeometryShaderTests.hpp"
26 #include "vktGeometryBasicClass.hpp"
27 #include "vktGeometryTestsUtil.hpp"
28
29 #include "vkDefs.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkBuilderUtil.hpp"
36
37 #include "vkRefUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkMemUtil.hpp"
40
41 #include <string>
42
43 using namespace vk;
44
45 namespace vkt
46 {
47 namespace geometry
48 {
49 namespace
50 {
51 using tcu::TestStatus;
52 using tcu::TestContext;
53 using tcu::TestCaseGroup;
54 using std::string;
55 using de::MovePtr;
56
57 typedef enum VertexOutputs              {VERTEXT_NO_OP = -1,VERTEXT_ZERO, VERTEXT_ONE}  VertexOut;
58 typedef enum GeometryOutputs    {GEOMETRY_ZERO, GEOMETRY_ONE, GEOMETRY_TWO}             GeometryOut;
59
60 struct VaryingTestSpec
61 {
62         VertexOutputs   vertexOutputs;
63         GeometryOutputs geometryOutputs;
64         const string    name;
65         const string    desc;
66 };
67
68 class GeometryVaryingTestInstance : public GeometryExpanderRenderTestInstance
69 {
70 public:
71                         GeometryVaryingTestInstance     (Context&               context,
72                                                                                  const char*    name);
73
74         void    genVertexAttribData                     (void);
75 };
76
77 GeometryVaryingTestInstance::GeometryVaryingTestInstance (Context& context, const char* name)
78         : GeometryExpanderRenderTestInstance    (context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, name)
79 {
80         genVertexAttribData();
81 }
82
83 void GeometryVaryingTestInstance::genVertexAttribData (void)
84 {
85         m_numDrawVertices = 3;
86         m_vertexPosData.resize(m_numDrawVertices);
87         m_vertexPosData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f);
88         m_vertexPosData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f);
89         m_vertexPosData[2] = tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f);
90
91         m_vertexAttrData.resize(m_numDrawVertices);
92         m_vertexAttrData[0] = tcu::Vec4(0.7f, 0.4f, 0.6f, 1.0f);
93         m_vertexAttrData[1] = tcu::Vec4(0.9f, 0.2f, 0.5f, 1.0f);
94         m_vertexAttrData[2] = tcu::Vec4(0.1f, 0.8f, 0.3f, 1.0f);
95 }
96
97 class VaryingTest : public TestCase
98 {
99 public:
100                                                         VaryingTest             (TestContext&                           testCtx,
101                                                                                          const VaryingTestSpec&         varyingTestSpec);
102
103         void                                    checkSupport    (Context&                                       context) const;
104         void                                    initPrograms    (SourceCollections&                     sourceCollections) const;
105         virtual TestInstance*   createInstance  (Context&                                       context) const;
106
107 protected:
108         const VaryingTestSpec   m_varyingTestSpec;
109 };
110
111 VaryingTest::VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec)
112         : TestCase                      (testCtx, varyingTestSpec.name, varyingTestSpec.desc)
113         , m_varyingTestSpec     (varyingTestSpec)
114
115 {
116
117 }
118
119 void VaryingTest::checkSupport (Context& context) const
120 {
121         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
122 }
123
124 void VaryingTest::initPrograms (SourceCollections& sourceCollections) const
125 {
126         {
127                 std::ostringstream src;
128                 src     << "#version 310 es\n"
129                         <<"layout(location = 0) in highp vec4 a_position;\n"
130                         <<"layout(location = 1) in highp vec4 a_color;\n";
131                 switch(m_varyingTestSpec.vertexOutputs)
132                 {
133                         case VERTEXT_NO_OP:
134                                 src     << "void main (void)\n"
135                                         << "{\n"
136                                         << "}\n";
137                                 break;
138                         case VERTEXT_ZERO:
139                                 src     << "void main (void)\n"
140                                         << "{\n"
141                                         << "    gl_Position = a_position;\n"
142                                         << "}\n";
143                                 break;
144                         case VERTEXT_ONE:
145                                 src     <<"layout(location = 0) out highp vec4 v_geom_0;\n"
146                                         << "void main (void)\n"
147                                         << "{\n"
148                                         << "    gl_Position = a_position;\n"
149                                         << "    v_geom_0 = a_color;\n"
150                                         << "}\n";
151                                 break;
152                         default:
153                                 DE_ASSERT(0);
154                 }
155                 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
156         }
157
158         {
159                 std::ostringstream src;
160                 src     << "#version 310 es\n"
161                         << "#extension GL_EXT_geometry_shader : require\n"
162                         << "layout(triangles) in;\n"
163                         << "layout(triangle_strip, max_vertices = 3) out;\n";
164
165                 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
166                         src     << "layout(location = 0) in highp vec4 v_geom_0[];\n";
167
168                 if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE)
169                         src     << "layout(location = 0) out highp vec4 v_frag_0;\n";
170                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
171                         src     << "layout(location = 1) out highp vec4 v_frag_1;\n";
172
173                 src     << "void main (void)\n"
174                         << "{\n"
175                         << "    highp vec4 offset = vec4(-0.2, -0.2, 0.0, 0.0);\n"
176                         << "    highp vec4 inputColor;\n"
177                         << "\n";
178                 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
179                         src     << "    inputColor = v_geom_0[0];\n";
180                 else
181                         src     << "    inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
182
183                 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
184                         src     << "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0) + offset;\n";
185                 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
186                         src     << "    gl_Position = gl_in[0].gl_Position + offset;\n";
187
188                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
189                         src     << "    v_frag_0 = inputColor;\n";
190                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
191                         src     << "    v_frag_0 = inputColor * 0.5;\n"
192                                 << "    v_frag_1 = inputColor.yxzw * 0.5;\n";
193
194                 src     << "    EmitVertex();\n"
195                         << "\n";
196                 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
197                         src     << "    inputColor = v_geom_0[1];\n";
198                 else
199                         src     << "    inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
200
201                 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
202                                 src     << "    gl_Position = vec4(1.0, 0.0, 0.0, 1.0) + offset;\n";
203                 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
204                                 src     << "    gl_Position = gl_in[1].gl_Position + offset;\n";
205
206                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
207                         src     << "    v_frag_0 = inputColor;\n";
208                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
209                         src     << "    v_frag_0 = inputColor * 0.5;\n"
210                                 << "    v_frag_1 = inputColor.yxzw * 0.5;\n";
211
212                 src     << "    EmitVertex();\n"
213                         << "\n";
214
215                 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
216                         src     << "    inputColor = v_geom_0[2];\n";
217                 else
218                         src     << "    inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
219
220                 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
221                                 src     << "    gl_Position = vec4(1.0, 1.0, 0.0, 1.0) + offset;\n";
222                 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
223                                 src     << "    gl_Position = gl_in[2].gl_Position + offset;\n";
224
225                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
226                         src     << "    v_frag_0 = inputColor;\n";
227                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
228                         src     << "    v_frag_0 = inputColor * 0.5;\n"
229                                 << "    v_frag_1 = inputColor.yxzw * 0.5;\n";
230
231                 src     << "    EmitVertex();\n"
232                         << "\n"
233                         << "    EndPrimitive();\n"
234                         << "}\n";
235                 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
236         }
237
238         {
239                 std::ostringstream src;
240                 src     << "#version 310 es\n"
241                         <<"layout(location = 0) out highp vec4 fragColor;\n";
242                 if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE)
243                         src     <<"layout(location = 0) in highp vec4 v_frag_0;\n";
244                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
245                         src     <<"layout(location = 1) in highp vec4 v_frag_1;\n";
246
247                 src     <<"void main (void)\n"
248                         <<"{\n";
249                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ZERO)
250                         src     <<"fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
251                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
252                         src     <<"     fragColor = v_frag_0;\n";
253                 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
254                         src     <<"     fragColor = v_frag_0 + v_frag_1.yxzw;\n";
255                 src     <<"}\n";
256                 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
257         }
258 }
259
260 TestInstance* VaryingTest::createInstance (Context& context) const
261 {
262         return new GeometryVaryingTestInstance(context, getName());
263 }
264
265 } // anonymous
266
267 TestCaseGroup* createVaryingGeometryShaderTests (TestContext& testCtx)
268 {
269         MovePtr<TestCaseGroup> varyingGroup     (new TestCaseGroup(testCtx, "varying",  "Test varyings."));
270
271         // varying
272         {
273                 static const VaryingTestSpec varyingTests[] =
274                 {
275                         { VERTEXT_NO_OP,        GEOMETRY_ONE,   "vertex_no_op_geometry_out_1", "vertex_no_op_geometry_out_1" },
276                         { VERTEXT_ZERO,         GEOMETRY_ONE,   "vertex_out_0_geometry_out_1", "vertex_out_0_geometry_out_1" },
277                         { VERTEXT_ZERO,         GEOMETRY_TWO,   "vertex_out_0_geometry_out_2", "vertex_out_0_geometry_out_2" },
278                         { VERTEXT_ONE,          GEOMETRY_ZERO,  "vertex_out_1_geometry_out_0", "vertex_out_1_geometry_out_0" },
279                         { VERTEXT_ONE,          GEOMETRY_TWO,   "vertex_out_1_geometry_out_2", "vertex_out_1_geometry_out_2" },
280                 };
281
282                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(varyingTests); ++ndx)
283                         varyingGroup->addChild(new VaryingTest(testCtx, varyingTests[ndx]));
284         }
285
286         return varyingGroup.release();
287 }
288
289 } // geometry
290 } // vkt