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 Emit Geometry Shader Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktGeometryEmitGeometryShaderTests.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 std::string;
52 using de::MovePtr;
53 using tcu::Vec4;
54 using tcu::TestStatus;
55 using tcu::TestContext;
56 using tcu::TestCaseGroup;
57
58 typedef enum VertexOutputs {VERTEXT_NO_OP = -1,VERTEXT_ZERO, VERTEXT_ONE} VertexOut;
59 typedef enum GeometryOutputs {GEOMETRY_ZERO, GEOMETRY_ONE, GEOMETRY_TWO} GeometryOut;
60
61 struct EmitTestSpec
62 {
63 VkPrimitiveTopology primitiveTopology;
64 int emitCountA; //!< primitive A emit count
65 int endCountA; //!< primitive A end count
66 int emitCountB; //!<
67 int endCountB; //!<
68 string name;
69 string desc;
70 };
71
72 class GeometryEmitTestInstance : public GeometryExpanderRenderTestInstance
73 {
74 public:
75 GeometryEmitTestInstance (Context& context,
76 const char* name);
77 void genVertexAttribData (void);
78 };
79
GeometryEmitTestInstance(Context & context,const char * name)80 GeometryEmitTestInstance::GeometryEmitTestInstance (Context& context, const char* name)
81 : GeometryExpanderRenderTestInstance (context, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, name)
82 {
83 genVertexAttribData();
84 }
85
genVertexAttribData(void)86 void GeometryEmitTestInstance::genVertexAttribData (void)
87 {
88 m_numDrawVertices = 1;
89 m_vertexPosData.resize(m_numDrawVertices);
90 m_vertexPosData[0] = Vec4(0, 0, 0, 1);
91
92 m_vertexAttrData.resize(m_numDrawVertices);
93 m_vertexAttrData[0] = Vec4(1, 1, 1, 1);
94 }
95
96 class EmitTest : public TestCase
97 {
98 public:
99 EmitTest (TestContext& testCtx,
100 const EmitTestSpec& emitTestSpec);
101
102 void initPrograms (SourceCollections& sourceCollections) const;
103 virtual TestInstance* createInstance (Context& context) const;
104 virtual void checkSupport (Context& context) const;
105
106 protected:
107 string shaderGeometry (bool pointSize) const;
108 const EmitTestSpec m_emitTestSpec;
109 };
110
EmitTest(TestContext & testCtx,const EmitTestSpec & emitTestSpec)111 EmitTest::EmitTest (TestContext& testCtx, const EmitTestSpec& emitTestSpec)
112 : TestCase (testCtx, emitTestSpec.name, emitTestSpec.desc)
113 , m_emitTestSpec (emitTestSpec)
114
115 {
116
117 }
118
checkSupport(Context & context) const119 void EmitTest::checkSupport (Context& context) const
120 {
121 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
122 }
123
initPrograms(SourceCollections & sourceCollections) const124 void EmitTest::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 << "layout(location = 0) out highp vec4 v_geom_FragColor;\n"
132 << "void main (void)\n"
133 << "{\n"
134 << " gl_Position = a_position;\n"
135 << " v_geom_FragColor = a_color;\n"
136 << "}\n";
137 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
138 }
139
140 {
141 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(shaderGeometry(false));
142 if(m_emitTestSpec.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
143 sourceCollections.glslSources.add("geometry_pointsize") << glu::GeometrySource(shaderGeometry(true));
144 }
145
146 {
147 std::ostringstream src;
148 src << "#version 310 es\n"
149 << "layout(location = 0) out mediump vec4 fragColor;\n"
150 << "layout(location = 0) in highp vec4 v_frag_FragColor;\n"
151 << "void main (void)\n"
152 << "{\n"
153 << " fragColor = v_frag_FragColor;\n"
154 <<"}\n";
155 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
156 }
157 }
158
createInstance(Context & context) const159 TestInstance* EmitTest::createInstance (Context& context) const
160 {
161 return new GeometryEmitTestInstance(context, getName());
162 }
163
shaderGeometry(bool pointSize) const164 string EmitTest::shaderGeometry (bool pointSize) const
165 {
166 std::ostringstream src;
167 src << "#version 310 es\n"
168 << "#extension GL_EXT_geometry_shader : require\n";
169 if (pointSize)
170 src <<"#extension GL_EXT_geometry_point_size : require\n";
171 src << "layout(points) in;\n"
172 << "layout(" << outputTypeToGLString(m_emitTestSpec.primitiveTopology) << ", max_vertices = " << (m_emitTestSpec.emitCountA + m_emitTestSpec.emitCountB +1) << ") out;\n"
173 << "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
174 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
175 << "void main (void)\n"
176 << "{\n"
177 << " const highp vec4 position0 = vec4(-0.5, 0.5, 0.0, 0.0);\n"
178 << " const highp vec4 position1 = vec4( 0.0, 0.1, 0.0, 0.0);\n"
179 << " const highp vec4 position2 = vec4( 0.5, 0.5, 0.0, 0.0);\n"
180 << " const highp vec4 position3 = vec4( 0.7, -0.2, 0.0, 0.0);\n"
181 << " const highp vec4 position4 = vec4( 0.2, 0.2, 0.0, 0.0);\n"
182 << " const highp vec4 position5 = vec4( 0.4, -0.3, 0.0, 0.0);\n";
183 for (int i = 0; i < m_emitTestSpec.emitCountA; ++i)
184 {
185 if (pointSize)
186 src << " gl_PointSize = 1.0;\n";
187 src << " gl_Position = gl_in[0].gl_Position + position" << i << ";\n"
188 " gl_PrimitiveID = gl_PrimitiveIDIn;\n"
189 " v_frag_FragColor = v_geom_FragColor[0];\n"
190 " EmitVertex();\n"
191 "\n";
192 }
193
194 for (int i = 0; i < m_emitTestSpec.endCountA; ++i)
195 src << " EndPrimitive();\n";
196
197 for (int i = 0; i < m_emitTestSpec.emitCountB; ++i)
198 {
199 if (pointSize)
200 src << " gl_PointSize = 1.0;\n";
201 src << " gl_Position = gl_in[0].gl_Position + position" << (m_emitTestSpec.emitCountA + i) << ";\n"
202 " gl_PrimitiveID = gl_PrimitiveIDIn;\n"
203 " v_frag_FragColor = v_geom_FragColor[0];\n"
204 " EmitVertex();\n"
205 "\n";
206 }
207
208 for (int i = 0; i < m_emitTestSpec.endCountB; ++i)
209 src << " EndPrimitive();\n";
210 src << "}\n";
211 return src.str();
212 }
213
214 } // anonymous
215
createEmitGeometryShaderTests(TestContext & testCtx)216 TestCaseGroup* createEmitGeometryShaderTests (TestContext& testCtx)
217 {
218 MovePtr<TestCaseGroup> emitGroup (new TestCaseGroup(testCtx, "emit", "Different emit counts."));
219
220 // emit different amounts
221 {
222 EmitTestSpec emitTests[] =
223 {
224 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, 0, 0, 0, "points" , ""},
225 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, 1, 0, 0, "points" , ""},
226 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 1, 1, 0, 0, "points" , ""},
227 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, 2, 0, 0, "points" , ""},
228 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 1, 2, 0, 0, "points" , ""},
229 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, 0, 0, 0, "line_strip" , ""},
230 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, 1, 0, 0, "line_strip" , ""},
231 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 1, 1, 0, 0, "line_strip" , ""},
232 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 1, 0, 0, "line_strip" , ""},
233 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, 2, 0, 0, "line_strip" , ""},
234 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 1, 2, 0, 0, "line_strip" , ""},
235 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 2, 0, 0, "line_strip" , ""},
236 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 2, 2, 0, "line_strip" , ""},
237 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0, 0, 0, 0, "triangle_strip", ""},
238 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0, 1, 0, 0, "triangle_strip", ""},
239 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 1, 1, 0, 0, "triangle_strip", ""},
240 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 2, 1, 0, 0, "triangle_strip", ""},
241 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 1, 0, 0, "triangle_strip", ""},
242 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0, 2, 0, 0, "triangle_strip", ""},
243 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 1, 2, 0, 0, "triangle_strip", ""},
244 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 2, 2, 0, 0, "triangle_strip", ""},
245 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 2, 0, 0, "triangle_strip", ""},
246 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 2, 3, 0, "triangle_strip", ""},
247 };
248
249 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(emitTests); ++ndx)
250 {
251 emitTests[ndx].name = std::string(emitTests[ndx].name) + "_emit_" + de::toString(emitTests[ndx].emitCountA) + "_end_" + de::toString(emitTests[ndx].endCountA);
252 emitTests[ndx].desc = std::string(emitTests[ndx].name) + " output, emit " + de::toString(emitTests[ndx].emitCountA) + " vertices, call EndPrimitive " + de::toString(emitTests[ndx].endCountA) + " times";
253
254 if (emitTests[ndx].emitCountB)
255 {
256 emitTests[ndx].name += "_emit_" + de::toString(emitTests[ndx].emitCountB) + "_end_" + de::toString(emitTests[ndx].endCountB);
257 emitTests[ndx].desc += ", emit " + de::toString(emitTests[ndx].emitCountB) + " vertices, call EndPrimitive " + de::toString(emitTests[ndx].endCountB) + " times";
258 }
259
260 emitGroup->addChild(new EmitTest(testCtx, emitTests[ndx]));
261 }
262 }
263
264 return emitGroup.release();
265 }
266
267 } // geometry
268 } // vkt
269