• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	virtual void				checkSupport				(Context&					context) const;
128 
129 protected:
130 	string						shaderGeometry				(bool						pointSize) const;
131 	const VkPrimitiveTopology	m_primitiveType;
132 	const VkPrimitiveTopology	m_outputType;
133 };
134 
GeometryExpanderRenderTest(TestContext & testCtx,const PrimitiveTestSpec & inputPrimitives)135 GeometryExpanderRenderTest::GeometryExpanderRenderTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives)
136 	: TestCase			(testCtx, inputPrimitives.name, inputPrimitives.name)
137 	, m_primitiveType	(inputPrimitives.primitiveType)
138 	, m_outputType		(inputPrimitives.outputType)
139 {
140 
141 }
142 
checkSupport(Context & context) const143 void GeometryExpanderRenderTest::checkSupport (Context& context) const
144 {
145 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
146 
147 	if (m_primitiveType == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
148 		context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
149 		!context.getPortabilitySubsetFeatures().triangleFans)
150 	{
151 		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
152 	}
153 }
154 
initPrograms(SourceCollections & sourceCollections) const155 void GeometryExpanderRenderTest::initPrograms (SourceCollections& sourceCollections) const
156 {
157 	{
158 		std::ostringstream src;
159 		src	<< "#version 310 es\n"
160 			<<"layout(location = 0) in highp vec4 a_position;\n"
161 			<<"layout(location = 1) in highp vec4 a_color;\n"
162 			<<"layout(location = 0) out highp vec4 v_geom_FragColor;\n"
163 			<<"void main (void)\n"
164 			<<"{\n"
165 			<<"	gl_Position = a_position;\n"
166 			<<"	v_geom_FragColor = a_color;\n"
167 			<<"}\n";
168 		sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
169 	}
170 
171 	{
172 		sourceCollections.glslSources.add("geometry") << glu::GeometrySource(shaderGeometry(false));
173 		if (m_outputType == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
174 			sourceCollections.glslSources.add("geometry_pointsize") << glu::GeometrySource(shaderGeometry(true));
175 	}
176 
177 	{
178 		std::ostringstream src;
179 		src	<< "#version 310 es\n"
180 			<<"layout(location = 0) out highp vec4 fragColor;\n"
181 			<<"layout(location = 0) in highp vec4 v_frag_FragColor;\n"
182 			<<"void main (void)\n"
183 			<<"{\n"
184 			<<"	fragColor = v_frag_FragColor;\n"
185 			<<"}\n";
186 		sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
187 	}
188 }
189 
createInstance(Context & context) const190 TestInstance* GeometryExpanderRenderTest::createInstance (Context& context) const
191 {
192 	return new GeometryInputTestInstance(context, m_primitiveType, getName());
193 }
194 
shaderGeometry(bool pointSize) const195 string GeometryExpanderRenderTest::shaderGeometry (bool pointSize) const
196 {
197 	std::ostringstream src;
198 	src	<< "#version 310 es\n"
199 		<< "#extension GL_EXT_geometry_shader : require\n";
200 	if (pointSize)
201 		src	<<"#extension GL_EXT_geometry_point_size : require\n";
202 	src	<< "layout(" << inputTypeToGLString(m_primitiveType) << ") in;\n"
203 		<< "layout(" << outputTypeToGLString(m_outputType) << ", max_vertices = " << calcOutputVertices(m_primitiveType) << ") out;\n"
204 		<< "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
205 		<< "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
206 		<< "\n"
207 		<< "void main (void)\n"
208 		<< "{\n"
209 		<< "	const highp vec4 offset0 = vec4(-0.07, -0.01, 0.0, 0.0);\n"
210 		<< "	const highp vec4 offset1 = vec4( 0.03, -0.03, 0.0, 0.0);\n"
211 		<< "	const highp vec4 offset2 = vec4(-0.01,  0.08, 0.0, 0.0);\n"
212 		<< "	highp vec4 yoffset = float(gl_PrimitiveIDIn) * vec4(0.02, 0.1, 0.0, 0.0);\n"
213 		<< "\n"
214 		<< "	for (highp int ndx = 0; ndx < gl_in.length(); ndx++)\n"
215 		<< "	{\n";
216 		if (pointSize)
217 			src	<< "		gl_PointSize = 1.0;\n";
218 	src	<< "		gl_Position = gl_in[ndx].gl_Position + offset0 + yoffset;\n"
219 		<< "		v_frag_FragColor = v_geom_FragColor[ndx];\n"
220 		<< "		EmitVertex();\n"
221 		<< "\n";
222 		if (pointSize)
223 			src	<< "		gl_PointSize = 1.0;\n";
224 	src	<< "		gl_Position = gl_in[ndx].gl_Position + offset1 + yoffset;\n"
225 		<< "		v_frag_FragColor = v_geom_FragColor[ndx];\n"
226 		<< "		EmitVertex();\n"
227 		<< "\n";
228 		if (pointSize)
229 			src	<< "		gl_PointSize = 1.0;\n";
230 	src	<< "		gl_Position = gl_in[ndx].gl_Position + offset2 + yoffset;\n"
231 		<< "		v_frag_FragColor = v_geom_FragColor[ndx];\n"
232 		<< "		EmitVertex();\n"
233 		<< "		EndPrimitive();\n"
234 		<< "	}\n"
235 		<< "}\n";
236 	return src.str();
237 }
238 
239 class TriangleStripAdjacencyVertexCountTest : public GeometryExpanderRenderTest
240 {
241 public:
242 							TriangleStripAdjacencyVertexCountTest	(TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices);
243 	virtual TestInstance*	createInstance							(Context& context) const;
244 private:
245 	const int	m_numInputVertices;
246 };
247 
TriangleStripAdjacencyVertexCountTest(TestContext & testCtx,const PrimitiveTestSpec & inputPrimitives,const int numInputVertices)248 TriangleStripAdjacencyVertexCountTest::TriangleStripAdjacencyVertexCountTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices)
249 	: GeometryExpanderRenderTest	(testCtx, inputPrimitives)
250 	, m_numInputVertices			(numInputVertices)
251 {
252 }
253 
createInstance(Context & context) const254 TestInstance* TriangleStripAdjacencyVertexCountTest::createInstance (Context& context) const
255 {
256 	return new GeometryInputTestInstance(context, m_primitiveType, getName(), m_numInputVertices);
257 }
258 
259 } // anonymous
260 
createInputGeometryShaderTests(TestContext & testCtx)261 TestCaseGroup* createInputGeometryShaderTests (TestContext& testCtx)
262 {
263 	MovePtr<TestCaseGroup> inputPrimitiveGroup		(new TestCaseGroup(testCtx, "input", "Different input primitives."));
264 	MovePtr<TestCaseGroup> basicPrimitiveGroup		(new TestCaseGroup(testCtx, "basic_primitive", "Basic Primitive geometry tests"));
265 	MovePtr<TestCaseGroup> triStripAdjacencyGroup	(new TestCaseGroup(testCtx, "triangle_strip_adjacency",	"Different triangle_strip_adjacency vertex counts."));
266 	MovePtr<TestCaseGroup> conversionPrimitiveGroup	(new TestCaseGroup(testCtx, "conversion", "Different input and output primitives."));
267 
268 	const PrimitiveTestSpec inputPrimitives[] =
269 	{
270 		{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,						"points",					VK_PRIMITIVE_TOPOLOGY_POINT_LIST		},
271 		{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,						"lines",					VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
272 		{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,						"line_strip",				VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
273 		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,					"triangles",				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	},
274 		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,					"triangle_strip",			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	},
275 		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,					"triangle_fan",				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	},
276 		{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,		"lines_adjacency",			VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
277 		{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,		"line_strip_adjacency",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
278 		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,	"triangles_adjacency",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	}
279 	};
280 
281 		// more basic types
282 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(inputPrimitives); ++ndx)
283 			basicPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, inputPrimitives[ndx]));
284 
285 		// triangle strip adjacency with different vertex counts
286 		for (int vertexCount = 0; vertexCount <= 12; ++vertexCount)
287 		{
288 			const string name = "vertex_count_" + de::toString(vertexCount);
289 			const PrimitiveTestSpec primitives = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, name.c_str(), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
290 
291 			triStripAdjacencyGroup->addChild(new TriangleStripAdjacencyVertexCountTest(testCtx, primitives, vertexCount));
292 		}
293 
294 		// different type conversions
295 		{
296 			static const PrimitiveTestSpec conversionPrimitives[] =
297 			{
298 				{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	"triangles_to_points",	VK_PRIMITIVE_TOPOLOGY_POINT_LIST	},
299 				{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		"lines_to_points",		VK_PRIMITIVE_TOPOLOGY_POINT_LIST	},
300 				{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		"points_to_lines",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP	},
301 				{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	"triangles_to_lines",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP	},
302 				{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		"points_to_triangles",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP},
303 				{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		"lines_to_triangles",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP}
304 			};
305 
306 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(conversionPrimitives); ++ndx)
307 				conversionPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, conversionPrimitives[ndx]));
308 		}
309 
310 	inputPrimitiveGroup->addChild(basicPrimitiveGroup.release());
311 	inputPrimitiveGroup->addChild(triStripAdjacencyGroup.release());
312 	inputPrimitiveGroup->addChild(conversionPrimitiveGroup.release());
313 	return inputPrimitiveGroup.release();
314 }
315 
316 } // geometry
317 } // vkt
318