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 
GeometryVaryingTestInstance(Context & context,const char * name)77 GeometryVaryingTestInstance::GeometryVaryingTestInstance (Context& context, const char* name)
78 	: GeometryExpanderRenderTestInstance	(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, name)
79 {
80 	genVertexAttribData();
81 }
82 
genVertexAttribData(void)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 
VaryingTest(TestContext & testCtx,const VaryingTestSpec & varyingTestSpec)110 VaryingTest::VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec)
111 	: TestCase			(testCtx, varyingTestSpec.name, varyingTestSpec.desc)
112 	, m_varyingTestSpec	(varyingTestSpec)
113 
114 {
115 
116 }
117 
initPrograms(SourceCollections & sourceCollections) const118 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 
createInstance(Context & context) const254 TestInstance* VaryingTest::createInstance (Context& context) const
255 {
256 	return new GeometryVaryingTestInstance(context, getName());
257 }
258 
259 } // anonymous
260 
createVaryingGeometryShaderTests(TestContext & testCtx)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