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 Varying Geometry Shader Tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktGeometryVaryingGeometryShaderTests.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::TestStatus;
     52 using tcu::TestContext;
     53 using tcu::TestCaseGroup;
     54 using std::string;
     55 using de::MovePtr;
     56 
     57 typedef enum VertexOutputs		{VERTEXT_NO_OP = -1,VERTEXT_ZERO, VERTEXT_ONE}	VertexOut;
     58 typedef enum GeometryOutputs	{GEOMETRY_ZERO, GEOMETRY_ONE, GEOMETRY_TWO}		GeometryOut;
     59 
     60 struct VaryingTestSpec
     61 {
     62 	VertexOutputs	vertexOutputs;
     63 	GeometryOutputs	geometryOutputs;
     64 	const string	name;
     65 	const string	desc;
     66 };
     67 
     68 class GeometryVaryingTestInstance : public GeometryExpanderRenderTestInstance
     69 {
     70 public:
     71 			GeometryVaryingTestInstance	(Context&		context,
     72 										 const char*	name);
     73 
     74 	void	genVertexAttribData			(void);
     75 };
     76 
     77 GeometryVaryingTestInstance::GeometryVaryingTestInstance (Context& context, const char* name)
     78 	: GeometryExpanderRenderTestInstance	(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, name)
     79 {
     80 	genVertexAttribData();
     81 }
     82 
     83 void GeometryVaryingTestInstance::genVertexAttribData (void)
     84 {
     85 	m_numDrawVertices = 3;
     86 	m_vertexPosData.resize(m_numDrawVertices);
     87 	m_vertexPosData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f);
     88 	m_vertexPosData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f);
     89 	m_vertexPosData[2] = tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f);
     90 
     91 	m_vertexAttrData.resize(m_numDrawVertices);
     92 	m_vertexAttrData[0] = tcu::Vec4(0.7f, 0.4f, 0.6f, 1.0f);
     93 	m_vertexAttrData[1] = tcu::Vec4(0.9f, 0.2f, 0.5f, 1.0f);
     94 	m_vertexAttrData[2] = tcu::Vec4(0.1f, 0.8f, 0.3f, 1.0f);
     95 }
     96 
     97 class VaryingTest : public TestCase
     98 {
     99 public:
    100 							VaryingTest		(TestContext&				testCtx,
    101 											 const VaryingTestSpec&		varyingTestSpec);
    102 
    103 	void					initPrograms	(SourceCollections&			sourceCollections) const;
    104 	virtual TestInstance*	createInstance	(Context&					context) const;
    105 
    106 protected:
    107 	const VaryingTestSpec	m_varyingTestSpec;
    108 };
    109 
    110 VaryingTest::VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec)
    111 	: TestCase			(testCtx, varyingTestSpec.name, varyingTestSpec.desc)
    112 	, m_varyingTestSpec	(varyingTestSpec)
    113 
    114 {
    115 
    116 }
    117 
    118 void VaryingTest::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 		switch(m_varyingTestSpec.vertexOutputs)
    126 		{
    127 			case VERTEXT_NO_OP:
    128 				src	<< "void main (void)\n"
    129 					<< "{\n"
    130 					<< "}\n";
    131 				break;
    132 			case VERTEXT_ZERO:
    133 				src	<< "void main (void)\n"
    134 					<< "{\n"
    135 					<< "	gl_Position = a_position;\n"
    136 					<< "}\n";
    137 				break;
    138 			case VERTEXT_ONE:
    139 				src	<<"layout(location = 0) out highp vec4 v_geom_0;\n"
    140 					<< "void main (void)\n"
    141 					<< "{\n"
    142 					<< "	gl_Position = a_position;\n"
    143 					<< "	v_geom_0 = a_color;\n"
    144 					<< "}\n";
    145 				break;
    146 			default:
    147 				DE_ASSERT(0);
    148 		}
    149 		sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
    150 	}
    151 
    152 	{
    153 		std::ostringstream src;
    154 		src	<< "#version 310 es\n"
    155 			<< "#extension GL_EXT_geometry_shader : require\n"
    156 			<< "layout(triangles) in;\n"
    157 			<< "layout(triangle_strip, max_vertices = 3) out;\n";
    158 
    159 		if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
    160 			src	<< "layout(location = 0) in highp vec4 v_geom_0[];\n";
    161 
    162 		if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE)
    163 			src	<< "layout(location = 0) out highp vec4 v_frag_0;\n";
    164 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
    165 			src	<< "layout(location = 1) out highp vec4 v_frag_1;\n";
    166 
    167 		src	<< "void main (void)\n"
    168 			<< "{\n"
    169 			<< "	highp vec4 offset = vec4(-0.2, -0.2, 0.0, 0.0);\n"
    170 			<< "	highp vec4 inputColor;\n"
    171 			<< "\n";
    172 		if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
    173 			src	<< "	inputColor = v_geom_0[0];\n";
    174 		else
    175 			src	<< "	inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
    176 
    177 		if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
    178 			src	<< "	gl_Position = vec4(0.0, 0.0, 0.0, 1.0) + offset;\n";
    179 		if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
    180 			src	<< "	gl_Position = gl_in[0].gl_Position + offset;\n";
    181 
    182 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
    183 			src	<< "	v_frag_0 = inputColor;\n";
    184 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
    185 			src	<< "	v_frag_0 = inputColor * 0.5;\n"
    186 				<< "	v_frag_1 = inputColor.yxzw * 0.5;\n";
    187 
    188 		src	<< "	EmitVertex();\n"
    189 			<< "\n";
    190 		if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
    191 			src	<< "	inputColor = v_geom_0[1];\n";
    192 		else
    193 			src	<< "	inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
    194 
    195 		if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
    196 				src	<< "	gl_Position = vec4(1.0, 0.0, 0.0, 1.0) + offset;\n";
    197 		if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
    198 				src	<< "	gl_Position = gl_in[1].gl_Position + offset;\n";
    199 
    200 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
    201 			src	<< "	v_frag_0 = inputColor;\n";
    202 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
    203 			src	<< "	v_frag_0 = inputColor * 0.5;\n"
    204 				<< "	v_frag_1 = inputColor.yxzw * 0.5;\n";
    205 
    206 		src	<< "	EmitVertex();\n"
    207 			<< "\n";
    208 
    209 		if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE)
    210 			src	<< "	inputColor = v_geom_0[2];\n";
    211 		else
    212 			src	<< "	inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
    213 
    214 		if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP)
    215 				src	<< "	gl_Position = vec4(1.0, 1.0, 0.0, 1.0) + offset;\n";
    216 		if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO)
    217 				src	<< "	gl_Position = gl_in[2].gl_Position + offset;\n";
    218 
    219 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
    220 			src	<< "	v_frag_0 = inputColor;\n";
    221 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
    222 			src	<< "	v_frag_0 = inputColor * 0.5;\n"
    223 				<< "	v_frag_1 = inputColor.yxzw * 0.5;\n";
    224 
    225 		src	<< "	EmitVertex();\n"
    226 			<< "\n"
    227 			<< "	EndPrimitive();\n"
    228 			<< "}\n";
    229 		sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
    230 	}
    231 
    232 	{
    233 		std::ostringstream src;
    234 		src	<< "#version 310 es\n"
    235 			<<"layout(location = 0) out highp vec4 fragColor;\n";
    236 		if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE)
    237 			src	<<"layout(location = 0) in highp vec4 v_frag_0;\n";
    238 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
    239 			src	<<"layout(location = 1) in highp vec4 v_frag_1;\n";
    240 
    241 		src	<<"void main (void)\n"
    242 			<<"{\n";
    243 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ZERO)
    244 			src	<<"fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n";
    245 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE)
    246 			src	<<"	fragColor = v_frag_0;\n";
    247 		if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO)
    248 			src	<<"	fragColor = v_frag_0 + v_frag_1.yxzw;\n";
    249 		src	<<"}\n";
    250 		sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
    251 	}
    252 }
    253 
    254 TestInstance* VaryingTest::createInstance (Context& context) const
    255 {
    256 	return new GeometryVaryingTestInstance(context, getName());
    257 }
    258 
    259 } // anonymous
    260 
    261 TestCaseGroup* createVaryingGeometryShaderTests (TestContext& testCtx)
    262 {
    263 	MovePtr<TestCaseGroup> varyingGroup	(new TestCaseGroup(testCtx, "varying",  "Test varyings."));
    264 
    265 	// varying
    266 	{
    267 		static const VaryingTestSpec varyingTests[] =
    268 		{
    269 			{ VERTEXT_NO_OP,	GEOMETRY_ONE,	"vertex_no_op_geometry_out_1", "vertex_no_op_geometry_out_1" },
    270 			{ VERTEXT_ZERO,		GEOMETRY_ONE,	"vertex_out_0_geometry_out_1", "vertex_out_0_geometry_out_1" },
    271 			{ VERTEXT_ZERO,		GEOMETRY_TWO,	"vertex_out_0_geometry_out_2", "vertex_out_0_geometry_out_2" },
    272 			{ VERTEXT_ONE,		GEOMETRY_ZERO,	"vertex_out_1_geometry_out_0", "vertex_out_1_geometry_out_0" },
    273 			{ VERTEXT_ONE,		GEOMETRY_TWO,	"vertex_out_1_geometry_out_2", "vertex_out_1_geometry_out_2" },
    274 		};
    275 
    276 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(varyingTests); ++ndx)
    277 			varyingGroup->addChild(new VaryingTest(testCtx, varyingTests[ndx]));
    278 	}
    279 
    280 	return varyingGroup.release();
    281 }
    282 
    283 } // geometry
    284 } // vkt
    285