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
GeometryVaryingTestInstance(Context & context,const char * name)77 GeometryVaryingTestInstance::GeometryVaryingTestInstance (Context& context, const char* name)
78 : GeometryExpanderRenderTestInstance (context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, name)
79 {
80 genVertexAttribData();
81 }
82
genVertexAttribData(void)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 initPrograms (SourceCollections& sourceCollections) const;
104 virtual TestInstance* createInstance (Context& context) const;
105
106 protected:
107 const VaryingTestSpec m_varyingTestSpec;
108 };
109
VaryingTest(TestContext & testCtx,const VaryingTestSpec & varyingTestSpec)110 VaryingTest::VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec)
111 : TestCase (testCtx, varyingTestSpec.name, varyingTestSpec.desc)
112 , m_varyingTestSpec (varyingTestSpec)
113
114 {
115
116 }
117
initPrograms(SourceCollections & sourceCollections) const118 void VaryingTest::initPrograms (SourceCollections& sourceCollections) const
119 {
120 {
121 std::ostringstream src;
122 src << "#version 310 es\n"
123 <<"layout(location = 0) in highp vec4 a_position;\n"
124 <<"layout(location = 1) in highp vec4 a_color;\n";
125 switch(m_varyingTestSpec.vertexOutputs)
126 {
127 case VERTEXT_NO_OP:
128 src << "void main (void)\n"
129 << "{\n"
130 << "}\n";
131 break;
132 case VERTEXT_ZERO:
133 src << "void main (void)\n"
134 << "{\n"
135 << " gl_Position = a_position;\n"
136 << "}\n";
137 break;
138 case VERTEXT_ONE:
139 src <<"layout(location = 0) out highp vec4 v_geom_0;\n"
140 << "void main (void)\n"
141 << "{\n"
142 << " gl_Position = a_position;\n"
143 << " v_geom_0 = a_color;\n"
144 << "}\n";
145 break;
146 default:
147 DE_ASSERT(0);
148 }
149 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
150 }
151
152 {
153 std::ostringstream src;
154 src << "#version 310 es\n"
155 << "#extension GL_EXT_geometry_shader : require\n"
156 << "layout(triangles) in;\n"
157 << "layout(triangle_strip, max_vertices = 3) out;\n";
158
159 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
160 src << "layout(location = 0) in highp vec4 v_geom_0[];\n";
161
162 if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE)
163 src << "layout(location = 0) out highp vec4 v_frag_0;\n";
164 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
165 src << "layout(location = 1) out highp vec4 v_frag_1;\n";
166
167 src << "void main (void)\n"
168 << "{\n"
169 << " highp vec4 offset = vec4(-0.2, -0.2, 0.0, 0.0);\n"
170 << " highp vec4 inputColor;\n"
171 << "\n";
172 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
173 src << " inputColor = v_geom_0[0];\n";
174 else
175 src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
176
177 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
178 src << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0) + offset;\n";
179 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
180 src << " gl_Position = gl_in[0].gl_Position + offset;\n";
181
182 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
183 src << " v_frag_0 = inputColor;\n";
184 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
185 src << " v_frag_0 = inputColor * 0.5;\n"
186 << " v_frag_1 = inputColor.yxzw * 0.5;\n";
187
188 src << " EmitVertex();\n"
189 << "\n";
190 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
191 src << " inputColor = v_geom_0[1];\n";
192 else
193 src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
194
195 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
196 src << " gl_Position = vec4(1.0, 0.0, 0.0, 1.0) + offset;\n";
197 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
198 src << " gl_Position = gl_in[1].gl_Position + offset;\n";
199
200 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
201 src << " v_frag_0 = inputColor;\n";
202 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
203 src << " v_frag_0 = inputColor * 0.5;\n"
204 << " v_frag_1 = inputColor.yxzw * 0.5;\n";
205
206 src << " EmitVertex();\n"
207 << "\n";
208
209 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
210 src << " inputColor = v_geom_0[2];\n";
211 else
212 src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
213
214 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
215 src << " gl_Position = vec4(1.0, 1.0, 0.0, 1.0) + offset;\n";
216 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
217 src << " gl_Position = gl_in[2].gl_Position + offset;\n";
218
219 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
220 src << " v_frag_0 = inputColor;\n";
221 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
222 src << " v_frag_0 = inputColor * 0.5;\n"
223 << " v_frag_1 = inputColor.yxzw * 0.5;\n";
224
225 src << " EmitVertex();\n"
226 << "\n"
227 << " EndPrimitive();\n"
228 << "}\n";
229 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
230 }
231
232 {
233 std::ostringstream src;
234 src << "#version 310 es\n"
235 <<"layout(location = 0) out highp vec4 fragColor;\n";
236 if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE)
237 src <<"layout(location = 0) in highp vec4 v_frag_0;\n";
238 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
239 src <<"layout(location = 1) in highp vec4 v_frag_1;\n";
240
241 src <<"void main (void)\n"
242 <<"{\n";
243 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ZERO)
244 src <<"fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
245 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
246 src <<" fragColor = v_frag_0;\n";
247 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
248 src <<" fragColor = v_frag_0 + v_frag_1.yxzw;\n";
249 src <<"}\n";
250 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
251 }
252 }
253
createInstance(Context & context) const254 TestInstance* VaryingTest::createInstance (Context& context) const
255 {
256 return new GeometryVaryingTestInstance(context, getName());
257 }
258
259 } // anonymous
260
createVaryingGeometryShaderTests(TestContext & testCtx)261 TestCaseGroup* createVaryingGeometryShaderTests (TestContext& testCtx)
262 {
263 MovePtr<TestCaseGroup> varyingGroup (new TestCaseGroup(testCtx, "varying", "Test varyings."));
264
265 // varying
266 {
267 static const VaryingTestSpec varyingTests[] =
268 {
269 { VERTEXT_NO_OP, GEOMETRY_ONE, "vertex_no_op_geometry_out_1", "vertex_no_op_geometry_out_1" },
270 { VERTEXT_ZERO, GEOMETRY_ONE, "vertex_out_0_geometry_out_1", "vertex_out_0_geometry_out_1" },
271 { VERTEXT_ZERO, GEOMETRY_TWO, "vertex_out_0_geometry_out_2", "vertex_out_0_geometry_out_2" },
272 { VERTEXT_ONE, GEOMETRY_ZERO, "vertex_out_1_geometry_out_0", "vertex_out_1_geometry_out_0" },
273 { VERTEXT_ONE, GEOMETRY_TWO, "vertex_out_1_geometry_out_2", "vertex_out_1_geometry_out_2" },
274 };
275
276 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(varyingTests); ++ndx)
277 varyingGroup->addChild(new VaryingTest(testCtx, varyingTests[ndx]));
278 }
279
280 return varyingGroup.release();
281 }
282
283 } // geometry
284 } // vkt
285