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 Input Geometry Shader Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktGeometryInputGeometryShaderTests.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::Vec4;
52 using tcu::TestStatus;
53 using tcu::TestContext;
54 using tcu::TestCaseGroup;
55 using de::MovePtr;
56 using std::string;
57 using std::vector;
58
59 class GeometryInputTestInstance : public GeometryExpanderRenderTestInstance
60 {
61 public:
62 GeometryInputTestInstance (Context& context,
63 const VkPrimitiveTopology primitiveType,
64 const char* name);
65
66 GeometryInputTestInstance (Context& context,
67 const VkPrimitiveTopology primitiveType,
68 const char* name,
69 const int numDrawVertices);
70
71 void genVertexAttribData (void);
72 };
73
GeometryInputTestInstance(Context & context,const VkPrimitiveTopology primitiveType,const char * name)74 GeometryInputTestInstance::GeometryInputTestInstance (Context& context,
75 const VkPrimitiveTopology primitiveType,
76 const char* name)
77 : GeometryExpanderRenderTestInstance (context, primitiveType, name)
78 {
79 genVertexAttribData();
80 }
81
GeometryInputTestInstance(Context & context,const VkPrimitiveTopology primitiveType,const char * name,const int numDrawVertices)82 GeometryInputTestInstance::GeometryInputTestInstance (Context& context,
83 const VkPrimitiveTopology primitiveType,
84 const char* name,
85 const int numDrawVertices)
86 : GeometryExpanderRenderTestInstance (context, primitiveType, name)
87 {
88 genVertexAttribData();
89 m_numDrawVertices = numDrawVertices;
90 }
91
genVertexAttribData(void)92 void GeometryInputTestInstance::genVertexAttribData (void)
93 {
94 // Create 1 X 2 grid in triangle strip adjacent - order
95 const float scale = 0.3f;
96 const Vec4 offset (-0.5f, -0.2f, 0.0f, 1.0f);
97 m_numDrawVertices = 12;
98
99 m_vertexPosData.resize(m_numDrawVertices);
100 m_vertexPosData[ 0] = Vec4( 0, 0, 0.0f, 0.0f) * scale + offset;
101 m_vertexPosData[ 1] = Vec4(-1, -1, 0.0f, 0.0f) * scale + offset;
102 m_vertexPosData[ 2] = Vec4( 0, -1, 0.0f, 0.0f) * scale + offset;
103 m_vertexPosData[ 3] = Vec4( 1, 1, 0.0f, 0.0f) * scale + offset;
104 m_vertexPosData[ 4] = Vec4( 1, 0, 0.0f, 0.0f) * scale + offset;
105 m_vertexPosData[ 5] = Vec4( 0, -2, 0.0f, 0.0f) * scale + offset;
106 m_vertexPosData[ 6] = Vec4( 1, -1, 0.0f, 0.0f) * scale + offset;
107 m_vertexPosData[ 7] = Vec4( 2, 1, 0.0f, 0.0f) * scale + offset;
108 m_vertexPosData[ 8] = Vec4( 2, 0, 0.0f, 0.0f) * scale + offset;
109 m_vertexPosData[ 9] = Vec4( 1, -2, 0.0f, 0.0f) * scale + offset;
110 m_vertexPosData[10] = Vec4( 2, -1, 0.0f, 0.0f) * scale + offset;
111 m_vertexPosData[11] = Vec4( 3, 0, 0.0f, 0.0f) * scale + offset;
112
113 // Red and white
114 m_vertexAttrData.resize(m_numDrawVertices);
115 for (int i = 0; i < m_numDrawVertices; ++i)
116 m_vertexAttrData[i] = (i % 2 == 0) ? Vec4(1, 1, 1, 1) : Vec4(1, 0, 0, 1);
117 }
118
119 class GeometryExpanderRenderTest : public TestCase
120 {
121 public:
122 GeometryExpanderRenderTest (TestContext& testCtx,
123 const PrimitiveTestSpec& inputPrimitives);
124
125 void initPrograms (SourceCollections& sourceCollections) const;
126 virtual TestInstance* createInstance (Context& context) const;
127
128 protected:
129 string shaderGeometry (bool pointSize) const;
130 const VkPrimitiveTopology m_primitiveType;
131 const VkPrimitiveTopology m_outputType;
132 };
133
GeometryExpanderRenderTest(TestContext & testCtx,const PrimitiveTestSpec & inputPrimitives)134 GeometryExpanderRenderTest::GeometryExpanderRenderTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives)
135 : TestCase (testCtx, inputPrimitives.name, inputPrimitives.name)
136 , m_primitiveType (inputPrimitives.primitiveType)
137 , m_outputType (inputPrimitives.outputType)
138 {
139
140 }
141
initPrograms(SourceCollections & sourceCollections) const142 void GeometryExpanderRenderTest::initPrograms (SourceCollections& sourceCollections) const
143 {
144 {
145 std::ostringstream src;
146 src << "#version 310 es\n"
147 <<"layout(location = 0) in highp vec4 a_position;\n"
148 <<"layout(location = 1) in highp vec4 a_color;\n"
149 <<"layout(location = 0) out highp vec4 v_geom_FragColor;\n"
150 <<"void main (void)\n"
151 <<"{\n"
152 <<" gl_Position = a_position;\n"
153 <<" v_geom_FragColor = a_color;\n"
154 <<"}\n";
155 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
156 }
157
158 {
159 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(shaderGeometry(false));
160 if (m_outputType == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
161 sourceCollections.glslSources.add("geometry_pointsize") << glu::GeometrySource(shaderGeometry(true));
162 }
163
164 {
165 std::ostringstream src;
166 src << "#version 310 es\n"
167 <<"layout(location = 0) out highp vec4 fragColor;\n"
168 <<"layout(location = 0) in highp vec4 v_frag_FragColor;\n"
169 <<"void main (void)\n"
170 <<"{\n"
171 <<" fragColor = v_frag_FragColor;\n"
172 <<"}\n";
173 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
174 }
175 }
176
createInstance(Context & context) const177 TestInstance* GeometryExpanderRenderTest::createInstance (Context& context) const
178 {
179 return new GeometryInputTestInstance(context, m_primitiveType, getName());
180 }
181
shaderGeometry(bool pointSize) const182 string GeometryExpanderRenderTest::shaderGeometry (bool pointSize) const
183 {
184 std::ostringstream src;
185 src << "#version 310 es\n"
186 << "#extension GL_EXT_geometry_shader : require\n";
187 if (pointSize)
188 src <<"#extension GL_EXT_geometry_point_size : require\n";
189 src << "layout(" << inputTypeToGLString(m_primitiveType) << ") in;\n"
190 << "layout(" << outputTypeToGLString(m_outputType) << ", max_vertices = " << calcOutputVertices(m_primitiveType) << ") out;\n"
191 << "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
192 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
193 << "\n"
194 << "void main (void)\n"
195 << "{\n"
196 << " const highp vec4 offset0 = vec4(-0.07, -0.01, 0.0, 0.0);\n"
197 << " const highp vec4 offset1 = vec4( 0.03, -0.03, 0.0, 0.0);\n"
198 << " const highp vec4 offset2 = vec4(-0.01, 0.08, 0.0, 0.0);\n"
199 << " highp vec4 yoffset = float(gl_PrimitiveIDIn) * vec4(0.02, 0.1, 0.0, 0.0);\n"
200 << "\n"
201 << " for (highp int ndx = 0; ndx < gl_in.length(); ndx++)\n"
202 << " {\n";
203 if (pointSize)
204 src << " gl_PointSize = 1.0;\n";
205 src << " gl_Position = gl_in[ndx].gl_Position + offset0 + yoffset;\n"
206 << " v_frag_FragColor = v_geom_FragColor[ndx];\n"
207 << " EmitVertex();\n"
208 << "\n";
209 if (pointSize)
210 src << " gl_PointSize = 1.0;\n";
211 src << " gl_Position = gl_in[ndx].gl_Position + offset1 + yoffset;\n"
212 << " v_frag_FragColor = v_geom_FragColor[ndx];\n"
213 << " EmitVertex();\n"
214 << "\n";
215 if (pointSize)
216 src << " gl_PointSize = 1.0;\n";
217 src << " gl_Position = gl_in[ndx].gl_Position + offset2 + yoffset;\n"
218 << " v_frag_FragColor = v_geom_FragColor[ndx];\n"
219 << " EmitVertex();\n"
220 << " EndPrimitive();\n"
221 << " }\n"
222 << "}\n";
223 return src.str();
224 }
225
226 class TriangleStripAdjacencyVertexCountTest : public GeometryExpanderRenderTest
227 {
228 public:
229 TriangleStripAdjacencyVertexCountTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices);
230 virtual TestInstance* createInstance (Context& context) const;
231 private:
232 const int m_numInputVertices;
233 };
234
TriangleStripAdjacencyVertexCountTest(TestContext & testCtx,const PrimitiveTestSpec & inputPrimitives,const int numInputVertices)235 TriangleStripAdjacencyVertexCountTest::TriangleStripAdjacencyVertexCountTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices)
236 : GeometryExpanderRenderTest (testCtx, inputPrimitives)
237 , m_numInputVertices (numInputVertices)
238 {
239 }
240
createInstance(Context & context) const241 TestInstance* TriangleStripAdjacencyVertexCountTest::createInstance (Context& context) const
242 {
243 return new GeometryInputTestInstance(context, m_primitiveType, getName(), m_numInputVertices);
244 }
245
246 } // anonymous
247
createInputGeometryShaderTests(TestContext & testCtx)248 TestCaseGroup* createInputGeometryShaderTests (TestContext& testCtx)
249 {
250 MovePtr<TestCaseGroup> inputPrimitiveGroup (new TestCaseGroup(testCtx, "input", "Different input primitives."));
251 MovePtr<TestCaseGroup> basicPrimitiveGroup (new TestCaseGroup(testCtx, "basic_primitive", "Basic Primitive geometry tests"));
252 MovePtr<TestCaseGroup> triStripAdjacencyGroup (new TestCaseGroup(testCtx, "triangle_strip_adjacency", "Different triangle_strip_adjacency vertex counts."));
253 MovePtr<TestCaseGroup> conversionPrimitiveGroup (new TestCaseGroup(testCtx, "conversion", "Different input and output primitives."));
254
255 const PrimitiveTestSpec inputPrimitives[] =
256 {
257 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
258 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP },
259 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, "line_strip", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP },
260 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
261 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
262 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
263 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, "lines_adjacency", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP },
264 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, "line_strip_adjacency", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP },
265 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, "triangles_adjacency", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }
266 };
267
268 // more basic types
269 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(inputPrimitives); ++ndx)
270 basicPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, inputPrimitives[ndx]));
271
272 // triangle strip adjacency with different vertex counts
273 for (int vertexCount = 0; vertexCount <= 12; ++vertexCount)
274 {
275 const string name = "vertex_count_" + de::toString(vertexCount);
276 const PrimitiveTestSpec primitives = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, name.c_str(), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
277
278 triStripAdjacencyGroup->addChild(new TriangleStripAdjacencyVertexCountTest(testCtx, primitives, vertexCount));
279 }
280
281 // different type conversions
282 {
283 static const PrimitiveTestSpec conversionPrimitives[] =
284 {
285 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles_to_points", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
286 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines_to_points", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
287 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points_to_lines", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP },
288 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles_to_lines", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP },
289 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points_to_triangles", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP},
290 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines_to_triangles", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP}
291 };
292
293 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(conversionPrimitives); ++ndx)
294 conversionPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, conversionPrimitives[ndx]));
295 }
296
297 inputPrimitiveGroup->addChild(basicPrimitiveGroup.release());
298 inputPrimitiveGroup->addChild(triStripAdjacencyGroup.release());
299 inputPrimitiveGroup->addChild(conversionPrimitiveGroup.release());
300 return inputPrimitiveGroup.release();
301 }
302
303 } // geometry
304 } // vkt
305