Home | History | Annotate | Download | only in geometry
      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 
     74 GeometryInputTestInstance::GeometryInputTestInstance	(Context&						context,
     75 														 const VkPrimitiveTopology		primitiveType,
     76 														 const char*					name)
     77 	: GeometryExpanderRenderTestInstance	(context, primitiveType, name)
     78 {
     79 	genVertexAttribData();
     80 }
     81 
     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 
     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 
    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 
    142 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 
    177 TestInstance* GeometryExpanderRenderTest::createInstance (Context& context) const
    178 {
    179 	return new GeometryInputTestInstance(context, m_primitiveType, getName());
    180 }
    181 
    182 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 
    235 TriangleStripAdjacencyVertexCountTest::TriangleStripAdjacencyVertexCountTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices)
    236 	: GeometryExpanderRenderTest	(testCtx, inputPrimitives)
    237 	, m_numInputVertices			(numInputVertices)
    238 {
    239 }
    240 
    241 TestInstance* TriangleStripAdjacencyVertexCountTest::createInstance (Context& context) const
    242 {
    243 	return new GeometryInputTestInstance(context, m_primitiveType, getName(), m_numInputVertices);
    244 }
    245 
    246 } // anonymous
    247 
    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