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 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 
     80 GeometryEmitTestInstance::GeometryEmitTestInstance (Context& context, const char* name)
     81 	: GeometryExpanderRenderTestInstance	(context, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, name)
     82 {
     83 	genVertexAttribData();
     84 }
     85 
     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 
    105 protected:
    106 	string					shaderGeometry	(bool						pointSize) const;
    107 	const EmitTestSpec	m_emitTestSpec;
    108 };
    109 
    110 EmitTest::EmitTest (TestContext& testCtx, const EmitTestSpec& emitTestSpec)
    111 	: TestCase			(testCtx, emitTestSpec.name, emitTestSpec.desc)
    112 	, m_emitTestSpec	(emitTestSpec)
    113 
    114 {
    115 
    116 }
    117 
    118 void EmitTest::initPrograms (SourceCollections& sourceCollections) const
    119 {
    120 	{
    121 		std::ostringstream src;
    122 		src	<< "#version 310 es\n"
    123 			<< "layout(location = 0) in highp vec4 a_position;\n"
    124 			<< "layout(location = 1) in highp vec4 a_color;\n"
    125 			<< "layout(location = 0) out highp vec4 v_geom_FragColor;\n"
    126 			<< "void main (void)\n"
    127 			<< "{\n"
    128 			<< "	gl_Position = a_position;\n"
    129 			<< "	v_geom_FragColor = a_color;\n"
    130 			<< "}\n";
    131 		sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
    132 	}
    133 
    134 	{
    135 		sourceCollections.glslSources.add("geometry") << glu::GeometrySource(shaderGeometry(false));
    136 		if(m_emitTestSpec.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
    137 			sourceCollections.glslSources.add("geometry_pointsize") << glu::GeometrySource(shaderGeometry(true));
    138 	}
    139 
    140 	{
    141 		std::ostringstream src;
    142 		src	<< "#version 310 es\n"
    143 			<< "layout(location = 0) out mediump vec4 fragColor;\n"
    144 			<< "layout(location = 0) in highp vec4 v_frag_FragColor;\n"
    145 			<< "void main (void)\n"
    146 			<< "{\n"
    147 			<< "	fragColor = v_frag_FragColor;\n"
    148 			<<"}\n";
    149 		sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
    150 	}
    151 }
    152 
    153 TestInstance* EmitTest::createInstance (Context& context) const
    154 {
    155 	return new GeometryEmitTestInstance(context, getName());
    156 }
    157 
    158 string EmitTest::shaderGeometry (bool pointSize) const
    159 {
    160 	std::ostringstream src;
    161 	src	<< "#version 310 es\n"
    162 		<< "#extension GL_EXT_geometry_shader : require\n";
    163 	if (pointSize)
    164 		src	<<"#extension GL_EXT_geometry_point_size : require\n";
    165 	src	<< "layout(points) in;\n"
    166 		<< "layout(" << outputTypeToGLString(m_emitTestSpec.primitiveTopology) << ", max_vertices = " << (m_emitTestSpec.emitCountA + m_emitTestSpec.emitCountB +1) << ") out;\n"
    167 		<< "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
    168 		<< "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
    169 		<< "void main (void)\n"
    170 		<< "{\n"
    171 		<< "	const highp vec4 position0 = vec4(-0.5,  0.5, 0.0, 0.0);\n"
    172 		<< "	const highp vec4 position1 = vec4( 0.0,  0.1, 0.0, 0.0);\n"
    173 		<< "	const highp vec4 position2 = vec4( 0.5,  0.5, 0.0, 0.0);\n"
    174 		<< "	const highp vec4 position3 = vec4( 0.7, -0.2, 0.0, 0.0);\n"
    175 		<< "	const highp vec4 position4 = vec4( 0.2,  0.2, 0.0, 0.0);\n"
    176 		<< "	const highp vec4 position5 = vec4( 0.4, -0.3, 0.0, 0.0);\n";
    177 	for (int i = 0; i < m_emitTestSpec.emitCountA; ++i)
    178 	{
    179 		if (pointSize)
    180 			src	<< "	gl_PointSize = 1.0;\n";
    181 		src <<	"	gl_Position = gl_in[0].gl_Position + position" << i << ";\n"
    182 				"	gl_PrimitiveID = gl_PrimitiveIDIn;\n"
    183 				"	v_frag_FragColor = v_geom_FragColor[0];\n"
    184 				"	EmitVertex();\n"
    185 				"\n";
    186 	}
    187 
    188 	for (int i = 0; i < m_emitTestSpec.endCountA; ++i)
    189 		src << "	EndPrimitive();\n";
    190 
    191 	for (int i = 0; i < m_emitTestSpec.emitCountB; ++i)
    192 	{
    193 		if (pointSize)
    194 			src	<< "	gl_PointSize = 1.0;\n";
    195 		src <<	"	gl_Position = gl_in[0].gl_Position + position" << (m_emitTestSpec.emitCountA + i) << ";\n"
    196 				"	gl_PrimitiveID = gl_PrimitiveIDIn;\n"
    197 				"	v_frag_FragColor = v_geom_FragColor[0];\n"
    198 				"	EmitVertex();\n"
    199 				"\n";
    200 	}
    201 
    202 	for (int i = 0; i < m_emitTestSpec.endCountB; ++i)
    203 		src << "	EndPrimitive();\n";
    204 	src	<< "}\n";
    205 	return src.str();
    206 }
    207 
    208 } // anonymous
    209 
    210 TestCaseGroup* createEmitGeometryShaderTests (TestContext& testCtx)
    211 {
    212 	MovePtr<TestCaseGroup> emitGroup	(new TestCaseGroup(testCtx, "emit", "Different emit counts."));
    213 
    214 	// emit different amounts
    215 	{
    216 		EmitTestSpec emitTests[] =
    217 		{
    218 			{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		0,	0,	0,	0,	"points"		,	""},
    219 			{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		0,	1,	0,	0,	"points"		,	""},
    220 			{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		1,	1,	0,	0,	"points"		,	""},
    221 			{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		0,	2,	0,	0,	"points"		,	""},
    222 			{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		1,	2,	0,	0,	"points"		,	""},
    223 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		0,	0,	0,	0,	"line_strip"	,	""},
    224 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		0,	1,	0,	0,	"line_strip"	,	""},
    225 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		1,	1,	0,	0,	"line_strip"	,	""},
    226 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		2,	1,	0,	0,	"line_strip"	,	""},
    227 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		0,	2,	0,	0,	"line_strip"	,	""},
    228 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		1,	2,	0,	0,	"line_strip"	,	""},
    229 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		2,	2,	0,	0,	"line_strip"	,	""},
    230 			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		2,	2,	2,	0,	"line_strip"	,	""},
    231 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	0,	0,	0,	0,	"triangle_strip",	""},
    232 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	0,	1,	0,	0,	"triangle_strip",	""},
    233 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	1,	1,	0,	0,	"triangle_strip",	""},
    234 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	2,	1,	0,	0,	"triangle_strip",	""},
    235 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	3,	1,	0,	0,	"triangle_strip",	""},
    236 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	0,	2,	0,	0,	"triangle_strip",	""},
    237 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	1,	2,	0,	0,	"triangle_strip",	""},
    238 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	2,	2,	0,	0,	"triangle_strip",	""},
    239 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	3,	2,	0,	0,	"triangle_strip",	""},
    240 			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	3,	2,	3,	0,	"triangle_strip",	""},
    241 		};
    242 
    243 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(emitTests); ++ndx)
    244 		{
    245 			emitTests[ndx].name = std::string(emitTests[ndx].name) + "_emit_" + de::toString(emitTests[ndx].emitCountA) + "_end_" + de::toString(emitTests[ndx].endCountA);
    246 			emitTests[ndx].desc = std::string(emitTests[ndx].name) + " output, emit " + de::toString(emitTests[ndx].emitCountA) + " vertices, call EndPrimitive " + de::toString(emitTests[ndx].endCountA) + " times";
    247 
    248 			if (emitTests[ndx].emitCountB)
    249 			{
    250 				emitTests[ndx].name += "_emit_" + de::toString(emitTests[ndx].emitCountB) + "_end_" + de::toString(emitTests[ndx].endCountB);
    251 				emitTests[ndx].desc += ", emit " + de::toString(emitTests[ndx].emitCountB) + " vertices, call EndPrimitive " + de::toString(emitTests[ndx].endCountB) + " times";
    252 			}
    253 
    254 			emitGroup->addChild(new EmitTest(testCtx, emitTests[ndx]));
    255 		}
    256 	}
    257 
    258 	return emitGroup.release();
    259 }
    260 
    261 } // geometry
    262 } // vkt
    263