xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcGLSLVectorConstructorTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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::bind;
57 using std::function;
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         {"vec2", "vec3", "vec4"}, // vector<string>            outputTypes
80         {
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" // uint32_t extraFields;
102     },
103     {
104         {"ivec2", "ivec3", "ivec4"}, // vector<string>            outputTypes
105         {
106             // vector<vector<string>>    inputTypeLists
107             {"mat2"},
108             {"mat2x3"},
109             {"mat2x4"},
110             {"mat3"},
111             {"mat3x2"},
112             {"mat3x4"},
113             {"mat4"},
114             {"mat4x2"},
115             {"mat4x3"},
116             {"int", "mat2"},
117             {"int", "mat2x3"},
118             {"int", "mat2x4"},
119             {"int", "mat3"},
120             {"int", "mat3x2"},
121             {"int", "mat3x4"},
122             {"int", "mat4"},
123             {"int", "mat4x2"},
124             {"int", "mat4x3"},
125         },
126         "" // uint32_t extraFields;
127     },
128     {
129         {"bvec2", "bvec3", "bvec4"}, // vector<string>            outputTypes
130         {
131             // vector<vector<string>>    inputTypeLists
132             {"mat2"},
133             {"mat2x3"},
134             {"mat2x4"},
135             {"mat3"},
136             {"mat3x2"},
137             {"mat3x4"},
138             {"mat4"},
139             {"mat4x2"},
140             {"mat4x3"},
141             {"bool", "mat2"},
142             {"bool", "mat2x3"},
143             {"bool", "mat2x4"},
144             {"bool", "mat3"},
145             {"bool", "mat3x2"},
146             {"bool", "mat3x4"},
147             {"bool", "mat4"},
148             {"bool", "mat4x2"},
149             {"bool", "mat4x3"},
150         },
151         "" // uint32_t extraFields;
152     },
153 };
154 
155 struct TestParams
156 {
157     string name;
158     string description;
159     TestType testType;
160     string outputType;
161     vector<string> inputTypes;
162     string extraFields;
163 };
164 
generateTestParams()165 vector<TestParams> generateTestParams()
166 {
167     vector<TestParams> result;
168     result.reserve(64);
169     for (const auto &test : tests)
170     {
171         for (const auto &outputType : test.outputTypes)
172         {
173             for (const auto &inputTypes : test.inputTypeLists)
174             {
175                 ostringstream testNameVs, testNameFs;
176                 ostringstream testDescriptionVs, testDescriptionFs;
177                 testNameVs << outputType << "_from";
178                 testNameFs << outputType << "_from";
179                 testDescriptionVs << outputType << "(";
180                 testDescriptionFs << outputType << "(";
181                 for (vector<string>::size_type i = 0; i < inputTypes.size(); ++i)
182                 {
183                     const auto &inputType = inputTypes[i];
184                     testNameVs << "_" << inputType;
185                     testNameFs << "_" << inputType;
186                     if (i > 0)
187                     {
188                         testDescriptionVs << ",";
189                         testDescriptionFs << ",";
190                     }
191                     testDescriptionVs << inputType;
192                 }
193                 ostringstream testNameInvalidVs, testNameInvalidFs;
194                 testNameInvalidVs << testNameVs.str() << "_" << inputTypes[0] << "_invalid_vs";
195                 testNameInvalidFs << testNameFs.str() << "_" << inputTypes[0] << "_invalid_fs";
196 
197                 testNameVs << "_vs";
198                 testNameFs << "_fs";
199                 testDescriptionVs << ") vertex shader";
200                 testDescriptionFs << ") fragment shader";
201                 result.push_back({testNameVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER, outputType,
202                                   inputTypes, test.extraFields});
203                 result.push_back({testNameFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER, outputType,
204                                   inputTypes, test.extraFields});
205 
206                 vector<string> failInputTypes;
207                 failInputTypes.insert(failInputTypes.end(), inputTypes.begin(), inputTypes.end());
208                 failInputTypes.push_back(inputTypes[0]);
209                 testDescriptionVs << " invalid";
210                 testDescriptionFs << " invalid";
211                 result.push_back({testNameInvalidVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER_ERROR,
212                                   outputType, failInputTypes, test.extraFields});
213                 result.push_back({testNameInvalidFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER_ERROR,
214                                   outputType, failInputTypes, test.extraFields});
215             }
216         }
217     }
218     return result;
219 }
220 
221 const string defaultVertexShader = "${GLSL_VERSION}\n"
222                                    "in vec4 vPosition;\n"
223                                    "void main()\n"
224                                    "{\n"
225                                    "    gl_Position = vPosition;\n"
226                                    "}\n";
227 
228 const string defaultFragmentShader = "${GLSL_VERSION}\n"
229                                      "precision mediump float;\n"
230                                      "in vec4 vColor;\n"
231                                      "out vec4 my_FragColor;\n"
232                                      "void main() {\n"
233                                      "    my_FragColor = vColor;\n"
234                                      "}\n";
235 
236 const string vertexShaderTemplate = "${GLSL_VERSION}\n"
237                                     "in vec4 vPosition;\n"
238                                     "precision mediump int;\n"
239                                     "precision mediump float;\n"
240                                     "const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
241                                     "const vec4 red      = vec4(1.0, 0.0, 0.0, 1.0);\n"
242                                     "${TEST_CONSTANTS}"
243                                     "out vec4 vColor;\n"
244                                     "void main() {\n"
245                                     "    ${TEST_CODE}\n"
246                                     "    if ${TEST_CONDITION}\n"
247                                     "        vColor = green;\n"
248                                     "    else\n"
249                                     "        vColor = red;\n"
250                                     "    gl_Position = vPosition;\n"
251                                     "}\n";
252 
253 const string fragmentShaderTemplate = "${GLSL_VERSION}\n"
254                                       "precision mediump int;\n"
255                                       "precision mediump float;\n"
256                                       "const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
257                                       "const vec4 red      = vec4(1.0, 0.0, 0.0, 1.0);\n"
258                                       "${TEST_CONSTANTS}"
259                                       "out vec4 my_FragColor;\n"
260                                       "void main() {\n"
261                                       "    ${TEST_CODE}\n"
262                                       "    if ${TEST_CONDITION}\n"
263                                       "        my_FragColor = green;\n"
264                                       "    else\n"
265                                       "        my_FragColor = red;\n"
266                                       "}\n";
267 
268 const map<string, string> testConditions = {
269     {"vec2", "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound)"},
270     {"vec3", "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound)"},
271     {"vec4", "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound && "
272              "abs(v[3] - 3.0) <= errorBound)"},
273     {"ivec2", "(v[0] == 0 && v[1] == 1)"},
274     {"ivec3", "(v[0] == 0 && v[1] == 1 && v[2] == 2)"},
275     {"ivec4", "(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)"},
276     {"bvec2", "(v[0] == false && v[1] == true)"},
277     {"bvec3", "(v[0] == false && v[1] == true && v[2] == true)"},
278     {"bvec4", "(v[0] == false && v[1] == true && v[2] == true && v[3] == true)"}};
279 
280 typedef function<void(ostringstream &, size_t)> GeneratorFn;
281 
282 struct DataTypeInfo
283 {
284     size_t numElements;
285     GeneratorFn valueFn;
286     GeneratorFn beforeValueFn;
287     GeneratorFn afterValueFn;
288 };
289 
generateValueFloat(ostringstream & out,const size_t index)290 void generateValueFloat(ostringstream &out, const size_t index)
291 {
292     out << index << ".0";
293 }
294 
generateValueInt(ostringstream & out,const size_t index)295 void generateValueInt(ostringstream &out, const size_t index)
296 {
297     out << index;
298 }
299 
generateValueBool(ostringstream & out,const size_t index)300 void generateValueBool(ostringstream &out, const size_t index)
301 {
302     out << ((index != 0) ? "true" : "false");
303 }
304 
generateCtorOpen(const char * className,ostringstream & out,const size_t)305 void generateCtorOpen(const char *className, ostringstream &out, const size_t)
306 {
307     out << className << "(";
308 }
309 
generateCtorClose(ostringstream & out,const size_t)310 void generateCtorClose(ostringstream &out, const size_t)
311 {
312     out << ")";
313 }
314 
315 const map<string, DataTypeInfo> dataTypeInfos = {
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 = (int)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)
382         .specialize({{"GLSL_VERSION", glu::getGLSLVersionDeclaration(glslVersion)},
383                      {"TEST_CONSTANTS", params.extraFields},
384                      {"TEST_CODE", generateTestCode(params.outputType, params.inputTypes)},
385                      {"TEST_CONDITION", (condition != testConditions.end()) ? condition->second : ""}});
386 }
387 
388 const vector<float> positions = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};
389 
390 const vector<uint32_t> indices = {0, 1, 2, 3};
391 
392 const int RENDERTARGET_WIDTH  = 16;
393 const int RENDERTARGET_HEIGHT = 16;
394 
395 class GLSLVectorConstructorTestCase : public deqp::TestCase
396 {
397 public:
398     GLSLVectorConstructorTestCase(deqp::Context &context, glu::GLSLVersion glslVersion, const TestParams &params);
399 
400     void init(void);
401     void deinit(void);
402     IterateResult iterate();
403 
404 private:
405     void setupRenderTarget();
406     void releaseRenderTarget();
407 
408     const glu::GLSLVersion m_glslVersion;
409     const TestParams m_params;
410     glw::GLuint m_fboId;
411     glw::GLuint m_rboId;
412 
413     string m_vertexShader;
414     string m_fragmentShader;
415 };
416 
GLSLVectorConstructorTestCase(deqp::Context & context,glu::GLSLVersion glslVersion,const TestParams & params)417 GLSLVectorConstructorTestCase::GLSLVectorConstructorTestCase(deqp::Context &context, glu::GLSLVersion glslVersion,
418                                                              const TestParams &params)
419     : TestCase(context, params.name.c_str(), params.description.c_str())
420     , m_glslVersion(glslVersion)
421     , m_params(params)
422     , m_fboId(0)
423     , m_rboId(0)
424 {
425     switch (m_params.testType)
426     {
427     case TestType::VERTEX_SHADER_ERROR:
428     case TestType::VERTEX_SHADER:
429         m_vertexShader   = replacePlaceholders(vertexShaderTemplate, m_params, m_glslVersion);
430         m_fragmentShader = replacePlaceholders(defaultFragmentShader, m_params, m_glslVersion);
431         break;
432     case TestType::FRAGMENT_SHADER_ERROR:
433     case TestType::FRAGMENT_SHADER:
434         m_vertexShader   = replacePlaceholders(defaultVertexShader, m_params, m_glslVersion);
435         m_fragmentShader = replacePlaceholders(fragmentShaderTemplate, m_params, m_glslVersion);
436         break;
437     }
438 }
439 
init(void)440 void GLSLVectorConstructorTestCase::init(void)
441 {
442     deqp::TestCase::init();
443 }
444 
deinit(void)445 void GLSLVectorConstructorTestCase::deinit(void)
446 {
447     deqp::TestCase::deinit();
448 }
449 
iterate()450 GLSLVectorConstructorTestCase::IterateResult GLSLVectorConstructorTestCase::iterate()
451 {
452     const auto &renderContext = m_context.getRenderContext();
453     const auto &gl            = renderContext.getFunctions();
454     const auto textureFormat  = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
455     const auto transferFormat = glu::getTransferFormat(textureFormat);
456 
457     setupRenderTarget();
458 
459     glu::ShaderProgram program(renderContext, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader));
460     if (!program.isOk())
461     {
462         switch (m_params.testType)
463         {
464         case TestType::VERTEX_SHADER_ERROR:
465         case TestType::FRAGMENT_SHADER_ERROR:
466             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
467             return STOP;
468         default:
469             TCU_FAIL("Shader compilation failed:\nVertex shader:\n" + m_vertexShader + "\nFragment shader:\n" +
470                      m_fragmentShader);
471         }
472     }
473 
474     const vector<glu::VertexArrayBinding> vertexArrays = {
475         glu::va::Float("vPosition", 2, (int)positions.size() / 2, 0, positions.data()),
476     };
477 
478     gl.useProgram(program.getProgram());
479     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
480 
481     gl.clear(GL_COLOR_BUFFER_BIT);
482 
483     glu::draw(renderContext, program.getProgram(), static_cast<int>(vertexArrays.size()), vertexArrays.data(),
484               glu::pr::TriangleStrip(static_cast<int>(indices.size()), indices.data()));
485 
486     const auto pixelSize = tcu::getPixelSize(textureFormat);
487     vector<uint8_t> fbData(RENDERTARGET_WIDTH * RENDERTARGET_HEIGHT * pixelSize);
488 
489     if (pixelSize < 4)
490         gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
491 
492     gl.readPixels(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, transferFormat.format, transferFormat.dataType,
493                   fbData.data());
494     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
495 
496     tcu::ConstPixelBufferAccess fbAccess{textureFormat, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, 1, fbData.data()};
497     const auto expectedColor = tcu::RGBA::green().toVec();
498     bool pass                = true;
499     for (int y = 0; pass && y < RENDERTARGET_HEIGHT; ++y)
500         for (int x = 0; x < RENDERTARGET_WIDTH; ++x)
501             if (fbAccess.getPixel(x, y) != expectedColor)
502             {
503                 pass = false;
504                 break;
505             }
506 
507     releaseRenderTarget();
508 
509     const qpTestResult result = (pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL);
510     const char *desc          = (pass ? "Pass" : "Pixel mismatch; vector initialization failed");
511 
512     m_testCtx.setTestResult(result, desc);
513 
514     return STOP;
515 }
516 
setupRenderTarget()517 void GLSLVectorConstructorTestCase::setupRenderTarget()
518 {
519     const auto &renderContext = m_context.getRenderContext();
520     const auto &gl            = renderContext.getFunctions();
521 
522     gl.genFramebuffers(1, &m_fboId);
523     GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
524 
525     gl.genRenderbuffers(1, &m_rboId);
526     GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderBuffers");
527 
528     gl.bindRenderbuffer(GL_RENDERBUFFER, m_rboId);
529     GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderBuffer");
530 
531     gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
532     GLU_EXPECT_NO_ERROR(gl.getError(), "RenderBufferStorage");
533 
534     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboId);
535     GLU_EXPECT_NO_ERROR(gl.getError(), "BindFrameBuffer");
536 
537     gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rboId);
538     GLU_EXPECT_NO_ERROR(gl.getError(), "FrameBufferRenderBuffer");
539 
540     glw::GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
541     gl.drawBuffers(1, &drawBuffer);
542     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
543 
544     glw::GLfloat clearColor[4] = {0, 0, 0, 0};
545     gl.clearBufferfv(GL_COLOR, 0, clearColor);
546     GLU_EXPECT_NO_ERROR(gl.getError(), "ClearBuffers");
547 
548     gl.viewport(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
549     GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
550 }
551 
releaseRenderTarget()552 void GLSLVectorConstructorTestCase::releaseRenderTarget()
553 {
554     const auto &renderContext = m_context.getRenderContext();
555     const auto &gl            = renderContext.getFunctions();
556     if (m_fboId != 0)
557     {
558         gl.deleteFramebuffers(1, &m_fboId);
559         m_fboId = 0;
560     }
561     if (m_rboId != 0)
562     {
563         gl.deleteRenderbuffers(1, &m_rboId);
564         m_rboId = 0;
565     }
566 }
567 
568 } // namespace
569 
GLSLVectorConstructorTests(Context & context,glu::GLSLVersion glslVersion)570 GLSLVectorConstructorTests::GLSLVectorConstructorTests(Context &context, glu::GLSLVersion glslVersion)
571     : deqp::TestCaseGroup(context, "glsl_constructors", "GLSL vector constructor tests")
572     , m_glslVersion(glslVersion)
573 {
574 }
575 
~GLSLVectorConstructorTests()576 GLSLVectorConstructorTests::~GLSLVectorConstructorTests()
577 {
578 }
579 
init()580 void GLSLVectorConstructorTests::init()
581 {
582     for (const auto &params : generateTestParams())
583         addChild(new GLSLVectorConstructorTestCase(m_context, m_glslVersion, params));
584 }
585 
586 } // namespace deqp
587