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 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
VaryingTest(TestContext & testCtx,const VaryingTestSpec & varyingTestSpec)111 VaryingTest::VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec)
112 : TestCase (testCtx, varyingTestSpec.name, varyingTestSpec.desc)
113 , m_varyingTestSpec (varyingTestSpec)
114
115 {
116
117 }
118
checkSupport(Context & context) const119 void VaryingTest::checkSupport (Context& context) const
120 {
121 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
122 }
123
initPrograms(SourceCollections & sourceCollections) const124 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
createInstance(Context & context) const260 TestInstance* VaryingTest::createInstance (Context& context) const
261 {
262 return new GeometryVaryingTestInstance(context, getName());
263 }
264
265 } // anonymous
266
createVaryingGeometryShaderTests(TestContext & testCtx)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
291