• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  * Copyright (c) 2016 The Khronos Group Inc.
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 GLSL vector constructor tests.
23  */ /*-------------------------------------------------------------------*/
24 #include "glcGLSLVectorConstructorTests.hpp"
25 
26 #include "gluDefs.hpp"
27 #include "gluTextureUtil.hpp"
28 #include "gluDrawUtil.hpp"
29 #include "gluShaderProgram.hpp"
30 
31 #include "glwDefs.hpp"
32 #include "glwFunctions.hpp"
33 #include "glwEnums.hpp"
34 
35 #include "tcuTestLog.hpp"
36 #include "tcuRenderTarget.hpp"
37 #include "tcuStringTemplate.hpp"
38 
39 #include <functional>
40 #include <map>
41 #include <vector>
42 #include <sstream>
43 #include <string>
44 #include <tuple>
45 
46 namespace deqp
47 {
48 
49 namespace
50 {
51 using std::string;
52 
53 using std::map;
54 using std::vector;
55 
56 using std::function;
57 using std::bind;
58 using namespace std::placeholders;
59 
60 using std::ostringstream;
61 
62 enum struct TestType
63 {
64 	VERTEX_SHADER_ERROR = 0,
65 	FRAGMENT_SHADER_ERROR,
66 	VERTEX_SHADER,
67 	FRAGMENT_SHADER
68 };
69 
70 struct TestDefinition
71 {
72 	vector<string>			outputTypes;
73 	vector<vector<string>>	inputTypeLists;
74 	string					extraFields;
75 };
76 
77 const TestDefinition					tests[]					=
78 {
79 	{
80 		{ "vec2", "vec3", "vec4" },								// vector<string>			outputTypes
81 		{														// vector<vector<string>>	inputTypeLists
82 			{ "mat2" },
83 			{ "mat2x3" },
84 			{ "mat2x4" },
85 			{ "mat3" },
86 			{ "mat3x2" },
87 			{ "mat3x4" },
88 			{ "mat4" },
89 			{ "mat4x2" },
90 			{ "mat4x3" },
91 			{ "float", "mat2" },
92 			{ "float", "mat2x3" },
93 			{ "float", "mat2x4" },
94 			{ "float", "mat3" },
95 			{ "float", "mat3x2" },
96 			{ "float", "mat3x4" },
97 			{ "float", "mat4" },
98 			{ "float", "mat4x2" },
99 			{ "float", "mat4x3" },
100 		},
101 		"const float errorBound = 1.0E-5;\n"					// deUint32					extraFields;
102 	},
103 	{
104 		{ "ivec2", "ivec3", "ivec4" },							// vector<string>			outputTypes
105 		{														// vector<vector<string>>	inputTypeLists
106 			{ "mat2" },
107 			{ "mat2x3" },
108 			{ "mat2x4" },
109 			{ "mat3" },
110 			{ "mat3x2" },
111 			{ "mat3x4" },
112 			{ "mat4" },
113 			{ "mat4x2" },
114 			{ "mat4x3" },
115 			{ "int", "mat2" },
116 			{ "int", "mat2x3" },
117 			{ "int", "mat2x4" },
118 			{ "int", "mat3" },
119 			{ "int", "mat3x2" },
120 			{ "int", "mat3x4" },
121 			{ "int", "mat4" },
122 			{ "int", "mat4x2" },
123 			{ "int", "mat4x3" },
124 		},
125 		""														// deUint32					extraFields;
126 	},
127 	{
128 		{ "bvec2", "bvec3", "bvec4" },							// vector<string>			outputTypes
129 		{														// vector<vector<string>>	inputTypeLists
130 			{ "mat2" },
131 			{ "mat2x3" },
132 			{ "mat2x4" },
133 			{ "mat3" },
134 			{ "mat3x2" },
135 			{ "mat3x4" },
136 			{ "mat4" },
137 			{ "mat4x2" },
138 			{ "mat4x3" },
139 			{ "bool", "mat2" },
140 			{ "bool", "mat2x3" },
141 			{ "bool", "mat2x4" },
142 			{ "bool", "mat3" },
143 			{ "bool", "mat3x2" },
144 			{ "bool", "mat3x4" },
145 			{ "bool", "mat4" },
146 			{ "bool", "mat4x2" },
147 			{ "bool", "mat4x3" },
148 		},
149 		""														// deUint32					extraFields;
150 	},
151 };
152 
153 struct TestParams
154 {
155 	string			name;
156 	string			description;
157 	TestType		testType;
158 	string			outputType;
159 	vector<string>	inputTypes;
160 	string			extraFields;
161 };
162 
generateTestParams()163 vector<TestParams> generateTestParams()
164 {
165 	vector<TestParams> result;
166 	result.reserve(64);
167 	for(const auto& test : tests)
168 	{
169 		for(const auto& outputType : test.outputTypes)
170 		{
171 			for(const auto& inputTypes : test.inputTypeLists)
172 			{
173 				ostringstream testNameVs, testNameFs;
174 				ostringstream testDescriptionVs, testDescriptionFs;
175 				testNameVs << outputType << "_from";
176 				testNameFs << outputType << "_from";
177 				testDescriptionVs << outputType << "(";
178 				testDescriptionFs << outputType << "(";
179 				for(vector<string>::size_type i = 0; i < inputTypes.size(); ++i)
180 				{
181 					const auto& inputType = inputTypes[i];
182 					testNameVs << "_" << inputType;
183 					testNameFs << "_" << inputType;
184 					if (i > 0) {
185 						testDescriptionVs << ",";
186 						testDescriptionFs << ",";
187 					}
188 					testDescriptionVs << inputType;
189 				}
190 				ostringstream testNameInvalidVs, testNameInvalidFs;
191 				testNameInvalidVs << testNameVs.str() << "_" << inputTypes[0] << "_invalid_vs";
192 				testNameInvalidFs << testNameFs.str() << "_" << inputTypes[0] << "_invalid_fs";
193 
194 				testNameVs << "_vs";
195 				testNameFs << "_fs";
196 				testDescriptionVs << ") vertex shader";
197 				testDescriptionFs << ") fragment shader";
198 				result.push_back({ testNameVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER, outputType, inputTypes, test.extraFields });
199 				result.push_back({ testNameFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER, outputType, inputTypes, test.extraFields });
200 
201 				vector<string> failInputTypes;
202 				failInputTypes.insert(failInputTypes.end(), inputTypes.begin(), inputTypes.end());
203 				failInputTypes.push_back(inputTypes[0]);
204 				testDescriptionVs << " invalid";
205 				testDescriptionFs << " invalid";
206 				result.push_back({ testNameInvalidVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER_ERROR, outputType, failInputTypes, test.extraFields });
207 				result.push_back({ testNameInvalidFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER_ERROR, outputType, failInputTypes, test.extraFields });
208 
209 			}
210 		}
211 	}
212 	return result;
213 }
214 
215 const string									defaultVertexShader		=
216 	"${GLSL_VERSION}\n"
217 	"in vec4 vPosition;\n"
218 	"void main()\n"
219 	"{\n"
220 	"    gl_Position = vPosition;\n"
221 	"}\n";
222 
223 const string									defaultFragmentShader	=
224 	"${GLSL_VERSION}\n"
225 	"precision mediump float;\n"
226 	"in vec4 vColor;\n"
227 	"out vec4 my_FragColor;\n"
228 	"void main() {\n"
229 	"    my_FragColor = vColor;\n"
230 	"}\n";
231 
232 const string									vertexShaderTemplate	=
233 	"${GLSL_VERSION}\n"
234 	"in vec4 vPosition;\n"
235 	"precision mediump int;\n"
236 	"precision mediump float;\n"
237 	"const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
238 	"const vec4 red	  = vec4(1.0, 0.0, 0.0, 1.0);\n"
239 	"${TEST_CONSTANTS}"
240 	"out vec4 vColor;\n"
241 	"void main() {\n"
242 	"    ${TEST_CODE}\n"
243 	"    if ${TEST_CONDITION}\n"
244 	"        vColor = green;\n"
245 	"    else\n"
246 	"        vColor = red;\n"
247 	"    gl_Position = vPosition;\n"
248 	"}\n";
249 
250 const string									fragmentShaderTemplate	=
251 	"${GLSL_VERSION}\n"
252 	"precision mediump int;\n"
253 	"precision mediump float;\n"
254 	"const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
255 	"const vec4 red	  = vec4(1.0, 0.0, 0.0, 1.0);\n"
256 	"${TEST_CONSTANTS}"
257 	"out vec4 my_FragColor;\n"
258 	"void main() {\n"
259 	"    ${TEST_CODE}\n"
260 	"    if ${TEST_CONDITION}\n"
261 	"        my_FragColor = green;\n"
262 	"    else\n"
263 	"        my_FragColor = red;\n"
264 	"}\n";
265 
266 const map<string, string>						testConditions			=
267 {
268 	{ "vec2"	, "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound)" },
269 	{ "vec3"	, "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound)" },
270 	{ "vec4"	, "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound && abs(v[3] - 3.0) <= errorBound)" },
271 	{ "ivec2"	, "(v[0] == 0 && v[1] == 1)" },
272 	{ "ivec3"	, "(v[0] == 0 && v[1] == 1 && v[2] == 2)" },
273 	{ "ivec4"	, "(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)" },
274 	{ "bvec2"	, "(v[0] == false && v[1] == true)" },
275 	{ "bvec3"	, "(v[0] == false && v[1] == true && v[2] == true)" },
276 	{ "bvec4"	, "(v[0] == false && v[1] == true && v[2] == true && v[3] == true)" }
277 };
278 
279 typedef function<void (ostringstream&, size_t)> GeneratorFn;
280 
281 struct DataTypeInfo
282 {
283 	size_t			numElements;
284 	GeneratorFn		valueFn;
285 	GeneratorFn		beforeValueFn;
286 	GeneratorFn		afterValueFn;
287 };
288 
generateValueFloat(ostringstream & out,const size_t index)289 void generateValueFloat(ostringstream& out, const size_t index)
290 {
291 	out << index << ".0";
292 }
293 
generateValueInt(ostringstream & out,const size_t index)294 void generateValueInt(ostringstream& out, const size_t index)
295 {
296 	out << index;
297 }
298 
generateValueBool(ostringstream & out,const size_t index)299 void generateValueBool(ostringstream& out, const size_t index)
300 {
301 	out << ((index != 0) ? "true" : "false");
302 }
303 
generateCtorOpen(const char * className,ostringstream & out,const size_t)304 void generateCtorOpen(const char* className, ostringstream& out, const size_t)
305 {
306 	out << className << "(";
307 }
308 
generateCtorClose(ostringstream & out,const size_t)309 void generateCtorClose(ostringstream &out, const size_t)
310 {
311 	out << ")";
312 }
313 
314 const map<string, DataTypeInfo>					dataTypeInfos			=
315 {
316 	//				numElements	, valueFn			, beforeValueFn								, afterValueFn
317 	{ "float"	, { 1			, generateValueFloat, DE_NULL									, DE_NULL			} },
318 	{ "vec2"	, { 2			, generateValueFloat, bind(generateCtorOpen, "vec2", _1, _2)	, generateCtorClose	} },
319 	{ "vec3"	, { 3			, generateValueFloat, bind(generateCtorOpen, "vec3", _1, _2)	, generateCtorClose	} },
320 	{ "vec4"	, { 4			, generateValueFloat, bind(generateCtorOpen, "vec4", _1, _2)	, generateCtorClose	} },
321 	{ "int"		, { 1			, generateValueInt	, DE_NULL									, DE_NULL			} },
322 	{ "ivec2"	, { 2			, generateValueInt	, bind(generateCtorOpen, "ivec2", _1, _2)	, generateCtorClose	} },
323 	{ "ivec3"	, { 3			, generateValueInt	, bind(generateCtorOpen, "ivec3", _1, _2)	, generateCtorClose	} },
324 	{ "ivec4"	, { 4			, generateValueInt	, bind(generateCtorOpen, "ivec4", _1, _2)	, generateCtorClose	} },
325 	{ "bool"	, { 1			, generateValueBool	, DE_NULL									, DE_NULL			} },
326 	{ "bvec2"	, { 2			, generateValueBool	, bind(generateCtorOpen, "bvec2", _1, _2)	, generateCtorClose	} },
327 	{ "bvec3"	, { 3			, generateValueBool	, bind(generateCtorOpen, "bvec3", _1, _2)	, generateCtorClose	} },
328 	{ "bvec4"	, { 4			, generateValueBool	, bind(generateCtorOpen, "bvec4", _1, _2)	, generateCtorClose	} },
329 	{ "mat2"	, { 4			, generateValueFloat, bind(generateCtorOpen, "mat2", _1, _2)	, generateCtorClose	} },
330 	{ "mat2x3"	, { 6			, generateValueFloat, bind(generateCtorOpen, "mat2x3", _1, _2)	, generateCtorClose	} },
331 	{ "mat2x4"	, { 8			, generateValueFloat, bind(generateCtorOpen, "mat2x4", _1, _2)	, generateCtorClose	} },
332 	{ "mat3"	, { 9			, generateValueFloat, bind(generateCtorOpen, "mat3", _1, _2)	, generateCtorClose	} },
333 	{ "mat3x2"	, { 6			, generateValueFloat, bind(generateCtorOpen, "mat3x2", _1, _2)	, generateCtorClose	} },
334 	{ "mat3x4"	, { 12			, generateValueFloat, bind(generateCtorOpen, "mat3x4", _1, _2)	, generateCtorClose	} },
335 	{ "mat4"	, { 16			, generateValueFloat, bind(generateCtorOpen, "mat4", _1, _2)	, generateCtorClose	} },
336 	{ "mat4x2"	, { 8			, generateValueFloat, bind(generateCtorOpen, "mat4x2", _1, _2)	, generateCtorClose	} },
337 	{ "mat4x3"	, { 12			, generateValueFloat, bind(generateCtorOpen, "mat4x3", _1, _2)	, generateCtorClose	} },
338 };
339 
generateTestCode(const string & outputType,const vector<string> & inputTypes)340 string generateTestCode(const string& outputType, const vector<string>& inputTypes)
341 {
342 	ostringstream output;
343 	const auto outputTypeInfo = dataTypeInfos.find(outputType);
344 	DE_ASSERT(outputTypeInfo != dataTypeInfos.end());
345 
346 	output << outputType << " v = ";
347 	if (outputTypeInfo->second.beforeValueFn != DE_NULL)
348 		outputTypeInfo->second.beforeValueFn(output, -1);
349 	int outputElementsRemaining = outputTypeInfo->second.numElements;
350 	int outputElementIndex = 0;
351 	for(size_t i = 0; i < inputTypes.size() && outputElementsRemaining > 0; ++i)
352 	{
353 		const auto& inputType = inputTypes[i];
354 		const auto inputTypeInfo = dataTypeInfos.find(inputType);
355 		DE_ASSERT(inputTypeInfo != dataTypeInfos.end());
356 
357 		if (outputElementIndex > 0)
358 			output << ", ";
359 		if (inputTypeInfo->second.beforeValueFn != DE_NULL)
360 			inputTypeInfo->second.beforeValueFn(output, i);
361 		for(size_t j = 0; j < inputTypeInfo->second.numElements; ++j)
362 		{
363 			if (j > 0)
364 				output << ", ";
365 
366 			inputTypeInfo->second.valueFn(output, outputElementIndex++);
367 			--outputElementsRemaining;
368 		}
369 		if (inputTypeInfo->second.afterValueFn != DE_NULL)
370 			inputTypeInfo->second.afterValueFn(output, i);
371 	}
372 	if (outputTypeInfo->second.afterValueFn != DE_NULL)
373 		outputTypeInfo->second.afterValueFn(output, -1);
374 	output << ";";
375 	return output.str();
376 }
377 
replacePlaceholders(const string & shaderTemplate,const TestParams & params,const glu::GLSLVersion glslVersion)378 string replacePlaceholders(const string& shaderTemplate, const TestParams& params, const glu::GLSLVersion glslVersion)
379 {
380 	const auto condition = testConditions.find(params.outputType);
381 	return tcu::StringTemplate(shaderTemplate).specialize(
382 	{
383 		{ "GLSL_VERSION"	, glu::getGLSLVersionDeclaration(glslVersion) },
384 		{ "TEST_CONSTANTS"	, params.extraFields },
385 		{ "TEST_CODE"		, generateTestCode(params.outputType, params.inputTypes) },
386 		{ "TEST_CONDITION"	, (condition != testConditions.end()) ? condition->second : "" }
387 	});
388 }
389 
390 const vector<float>								positions				=
391 {
392 	-1.0f, -1.0f,
393 	 1.0f, -1.0f,
394 	-1.0f,	1.0f,
395 	 1.0f,	1.0f
396 };
397 
398 const vector<deUint32>							indices					= { 0, 1, 2, 3 };
399 
400 const int										RENDERTARGET_WIDTH		= 16;
401 const int										RENDERTARGET_HEIGHT		= 16;
402 
403 class GLSLVectorConstructorTestCase : public deqp::TestCase
404 {
405 public:
406 	GLSLVectorConstructorTestCase(deqp::Context& context, glu::GLSLVersion glslVersion, const TestParams& params);
407 
408 	void init(void);
409 	void deinit(void);
410 	IterateResult iterate();
411 
412 private:
413 	void setupRenderTarget();
414 	void releaseRenderTarget();
415 
416 	const glu::GLSLVersion		m_glslVersion;
417 	const TestParams			m_params;
418 	glw::GLuint					m_fboId;
419 	glw::GLuint					m_rboId;
420 
421 	string						m_vertexShader;
422 	string						m_fragmentShader;
423 };
424 
GLSLVectorConstructorTestCase(deqp::Context & context,glu::GLSLVersion glslVersion,const TestParams & params)425 GLSLVectorConstructorTestCase::GLSLVectorConstructorTestCase(deqp::Context& context, glu::GLSLVersion glslVersion, const TestParams& params)
426 	: TestCase(context, params.name.c_str(), params.description.c_str())
427 	, m_glslVersion(glslVersion)
428 	, m_params(params)
429 	, m_fboId(0)
430 	, m_rboId(0)
431 {
432 	switch(m_params.testType)
433 	{
434 	case TestType::VERTEX_SHADER_ERROR:
435 	case TestType::VERTEX_SHADER:
436 		m_vertexShader = replacePlaceholders(vertexShaderTemplate, m_params, m_glslVersion);
437 		m_fragmentShader = replacePlaceholders(defaultFragmentShader, m_params, m_glslVersion);
438 		break;
439 	case TestType::FRAGMENT_SHADER_ERROR:
440 	case TestType::FRAGMENT_SHADER:
441 		m_vertexShader = replacePlaceholders(defaultVertexShader, m_params, m_glslVersion);
442 		m_fragmentShader = replacePlaceholders(fragmentShaderTemplate, m_params, m_glslVersion);
443 		break;
444 	}
445 }
446 
init(void)447 void GLSLVectorConstructorTestCase::init(void)
448 {
449 	deqp::TestCase::init();
450 }
451 
deinit(void)452 void GLSLVectorConstructorTestCase::deinit(void)
453 {
454 	deqp::TestCase::deinit();
455 }
456 
iterate()457 GLSLVectorConstructorTestCase::IterateResult GLSLVectorConstructorTestCase::iterate()
458 {
459 	const auto&								renderContext	= m_context.getRenderContext();
460 	const auto&								gl				= renderContext.getFunctions();
461 	const auto								textureFormat	= tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_INT8);
462 	const auto								transferFormat	= glu::getTransferFormat(textureFormat);
463 
464 	setupRenderTarget();
465 
466 	glu::ShaderProgram program(renderContext, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader));
467 	if (!program.isOk())
468 	{
469 		switch(m_params.testType)
470 		{
471 		case TestType::VERTEX_SHADER_ERROR:
472 		case TestType::FRAGMENT_SHADER_ERROR:
473 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
474 			return STOP;
475 		default:
476 			TCU_FAIL("Shader compilation failed:\nVertex shader:\n" + m_vertexShader + "\nFragment shader:\n" + m_fragmentShader);
477 		}
478 	}
479 
480 	const vector<glu::VertexArrayBinding>	vertexArrays	=
481 	{
482 		glu::va::Float("vPosition", 2, positions.size(), 0, positions.data()),
483 	};
484 
485 	gl.useProgram(program.getProgram());
486 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
487 
488 	gl.clear(GL_COLOR_BUFFER_BIT);
489 
490 	glu::draw(renderContext, program.getProgram(),
491 			  static_cast<int>(vertexArrays.size()), vertexArrays.data(),
492 			  glu::pr::TriangleStrip(static_cast<int>(indices.size()), indices.data()));
493 
494 	const auto								pixelSize		= tcu::getPixelSize(textureFormat);
495 	vector<deUint8>							fbData			(RENDERTARGET_WIDTH * RENDERTARGET_HEIGHT * pixelSize);
496 
497 	if (pixelSize < 4)
498 		gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
499 
500 	gl.readPixels(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, transferFormat.format, transferFormat.dataType, fbData.data());
501 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
502 
503 	tcu::ConstPixelBufferAccess				fbAccess		{ textureFormat, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, 1, fbData.data() };
504 	const auto								expectedColor	= tcu::RGBA::green().toVec();
505 	bool pass = true;
506 	for(int y = 0; pass && y < RENDERTARGET_HEIGHT; ++y)
507 		for(int x = 0; x < RENDERTARGET_WIDTH; ++x)
508 			if (fbAccess.getPixel(x,y) != expectedColor)
509 			{
510 				pass = false;
511 				break;
512 			}
513 
514 	releaseRenderTarget();
515 
516 	const qpTestResult						result			= (pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL);
517 	const char*								desc			= (pass ? "Pass" : "Pixel mismatch; vector initialization failed");
518 
519 	m_testCtx.setTestResult(result, desc);
520 
521 	return STOP;
522 }
523 
setupRenderTarget()524 void GLSLVectorConstructorTestCase::setupRenderTarget()
525 {
526 	const auto&		renderContext	= m_context.getRenderContext();
527 	const auto&		gl				= renderContext.getFunctions();
528 
529 	gl.genFramebuffers(1, &m_fboId);
530 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
531 
532 	gl.genRenderbuffers(1, &m_rboId);
533 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderBuffers");
534 
535 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rboId);
536 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderBuffer");
537 
538 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
539 	GLU_EXPECT_NO_ERROR(gl.getError(), "RenderBufferStorage");
540 
541 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboId);
542 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFrameBuffer");
543 
544 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rboId);
545 	GLU_EXPECT_NO_ERROR(gl.getError(), "FrameBufferRenderBuffer");
546 
547 	glw::GLenum		drawBuffer		= GL_COLOR_ATTACHMENT0;
548 	gl.drawBuffers(1, &drawBuffer);
549 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
550 
551 	glw::GLfloat	clearColor[4]	= { 0, 0, 0, 0 };
552 	gl.clearBufferfv(GL_COLOR, 0, clearColor);
553 	GLU_EXPECT_NO_ERROR(gl.getError(), "ClearBuffers");
554 
555 	gl.viewport(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
556 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
557 }
558 
releaseRenderTarget()559 void GLSLVectorConstructorTestCase::releaseRenderTarget()
560 {
561 	const auto&	renderContext	= m_context.getRenderContext();
562 	const auto&	gl				= renderContext.getFunctions();
563 	if (m_fboId != 0)
564 	{
565 		gl.deleteFramebuffers(1, &m_fboId);
566 		m_fboId = 0;
567 	}
568 	if (m_rboId != 0)
569 	{
570 		gl.deleteRenderbuffers(1, &m_rboId);
571 		m_rboId = 0;
572 	}
573 }
574 
575 }
576 
GLSLVectorConstructorTests(Context & context,glu::GLSLVersion glslVersion)577 GLSLVectorConstructorTests::GLSLVectorConstructorTests(Context& context, glu::GLSLVersion glslVersion)
578 	: deqp::TestCaseGroup(context, "glsl_constructors", "GLSL vector constructor tests")
579 	, m_glslVersion(glslVersion)
580 {
581 }
582 
~GLSLVectorConstructorTests()583 GLSLVectorConstructorTests::~GLSLVectorConstructorTests()
584 {
585 }
586 
init()587 void GLSLVectorConstructorTests::init()
588 {
589 	for(const auto& params : generateTestParams())
590 		addChild(new GLSLVectorConstructorTestCase(m_context, m_glslVersion, params));
591 }
592 
593 } // deqp
594