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