Always apply flat qualifier to double inputs, same as int/uint
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcShaderMultisampleInterpolationTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23
24 #include "glcShaderMultisampleInterpolationTests.hpp"
25 #include "deMath.h"
26 #include "deRandom.hpp"
27 #include "deStringUtil.hpp"
28 #include "gluContextInfo.hpp"
29 #include "gluDrawUtil.hpp"
30 #include "gluPixelTransfer.hpp"
31 #include "gluShaderProgram.hpp"
32 #include "glw.h"
33 #include "glwFunctions.hpp"
34 #include "tcuCommandLine.hpp"
35 #include "tcuStringTemplate.hpp"
36 #include "tcuSurface.hpp"
37 #include "tcuTestLog.hpp"
38
39 namespace tcu
40 {
41 static bool operator<(tcu::Vec4 const& k1, tcu::Vec4 const& k2)
42 {
43         if (k1.y() < k2.y())
44         {
45                 return true;
46         }
47         else if (k1.y() == k2.y())
48         {
49                 return k1.x() < k2.x();
50         }
51         else
52         {
53                 return false;
54         }
55 }
56 }
57
58 namespace deqp
59 {
60
61 using tcu::TestLog;
62 using std::string;
63 using std::vector;
64
65 static std::string specializeVersion(std::string const& source, glu::GLSLVersion version,
66                                                                          std::string const& sampler = "", std::string const& outType = "",
67                                                                          std::string const& qualifier = "", std::string const& assignment = "",
68                                                                          std::string const& condition = "")
69 {
70         DE_ASSERT(version == glu::GLSL_VERSION_310_ES || version >= glu::GLSL_VERSION_440);
71         std::map<std::string, std::string> args;
72         args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(version);
73         args["SAMPLER"]          = sampler;
74         args["OUT_TYPE"]         = outType;
75         args["QUALIFIER"]       = qualifier;
76         args["ASSIGNMENT"]   = assignment;
77         args["CONDITION"]       = condition;
78         if (version == glu::GLSL_VERSION_310_ES)
79         {
80                 args["OES_SMI_EN"] = "#extension GL_OES_shader_multisample_interpolation : enable\n";
81                 args["OES_SMI_RQ"] = "#extension GL_OES_shader_multisample_interpolation : require\n";
82                 args["OES_SMI_CH"] = "#if !GL_OES_shader_multisample_interpolation\n"
83                                                          "    this is broken\n"
84                                                          "#endif\n";
85                 args["OES_SV_EN"] = "#extension GL_OES_sample_variables : enable\n";
86         }
87         else
88         {
89                 args["OES_SMI_EN"] = "";
90                 args["OES_SMI_RQ"] = "";
91                 args["OES_SMI_CH"] = "";
92                 args["OES_SV_EN"]  = "";
93         }
94         return tcu::StringTemplate(source.c_str()).specialize(args);
95 }
96
97 class ShaderMultisampleInterpolationApiCase : public TestCase
98 {
99 public:
100         ShaderMultisampleInterpolationApiCase(Context& context, const char* name, const char* description,
101                                                                                   glu::GLSLVersion glslVersion);
102         ~ShaderMultisampleInterpolationApiCase();
103
104         IterateResult iterate();
105
106 protected:
107         glu::GLSLVersion m_glslVersion;
108 };
109
110 ShaderMultisampleInterpolationApiCase::ShaderMultisampleInterpolationApiCase(Context& context, const char* name,
111                                                                                                                                                          const char*      description,
112                                                                                                                                                          glu::GLSLVersion glslVersion)
113         : TestCase(context, name, description), m_glslVersion(glslVersion)
114 {
115         DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_440);
116 }
117
118 ShaderMultisampleInterpolationApiCase::~ShaderMultisampleInterpolationApiCase()
119 {
120 }
121
122 ShaderMultisampleInterpolationApiCase::IterateResult ShaderMultisampleInterpolationApiCase::iterate()
123 {
124         TestLog&                          log  = m_testCtx.getLog();
125         const glw::Functions& gl   = m_context.getRenderContext().getFunctions();
126         bool                              isOk = true;
127
128         if (m_glslVersion == glu::GLSL_VERSION_310_ES &&
129                 !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
130         {
131                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_OES_shader_multisample_interpolation");
132                 return STOP;
133         }
134
135         static char const* vss = "${VERSION_DECL}\n"
136                                                          "${OES_SMI_RQ}"
137                                                          "in highp vec4 a_position;\n"
138                                                          "in highp vec4 a_color;\n"
139                                                          "sample out highp vec4 v_color;\n"
140                                                          "void main()\n"
141                                                          "{\n"
142                                                          "    gl_Position = a_position;\n"
143                                                          "}\n";
144
145         {
146                 static char const* fss = "${VERSION_DECL}\n"
147                                                                  "${OES_SMI_RQ}"
148                                                                  "sample in highp vec4 v_color;\n"
149                                                                  "out highp vec4 o_color;\n"
150                                                                  "void main()\n"
151                                                                  "{\n"
152                                                                  "    o_color = v_color;\n"
153                                                                  "}\n";
154
155                 glu::ShaderProgram program(m_context.getRenderContext(),
156                                                                    glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(),
157                                                                                                                    specializeVersion(fss, m_glslVersion).c_str()));
158                 log << program;
159                 if (!program.isOk())
160                 {
161                         TCU_FAIL("Compile failed");
162                 }
163         }
164
165         {
166                 static char const* fss = "${VERSION_DECL}\n"
167                                                                  "${OES_SMI_EN}"
168                                                                  "sample in highp vec4 v_color;\n"
169                                                                  "out highp vec4 o_color;\n"
170                                                                  "void main()\n"
171                                                                  "{\n"
172                                                                  "${OES_SMI_CH}"
173                                                                  "    o_color = v_color;\n"
174                                                                  "}\n";
175
176                 glu::ShaderProgram program(m_context.getRenderContext(),
177                                                                    glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(),
178                                                                                                                    specializeVersion(fss, m_glslVersion).c_str()));
179                 log << program;
180                 if (!program.isOk())
181                 {
182                         TCU_FAIL("Compile failed");
183                 }
184         }
185
186         GLfloat minFragmentInterpolationOffset = 0.0f;
187         gl.getFloatv(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, &minFragmentInterpolationOffset);
188         if (minFragmentInterpolationOffset > -0.5f)
189         {
190                 isOk = false;
191         }
192
193         GLfloat maxFragmentInterpolationOffset = 0.0f;
194         gl.getFloatv(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, &maxFragmentInterpolationOffset);
195         if (maxFragmentInterpolationOffset < 0.5f)
196         {
197                 isOk = false;
198         }
199
200         GLint fragmentInterpolationOffsetBits = 0;
201         gl.getIntegerv(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, &fragmentInterpolationOffsetBits);
202         if (fragmentInterpolationOffsetBits < 4)
203         {
204                 isOk = false;
205         }
206
207         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
208         return STOP;
209 }
210
211 class ShaderMultisampleInterpolationBaseCase : public TestCase
212 {
213 public:
214         ShaderMultisampleInterpolationBaseCase(Context& context, const char* name, const char* description,
215                                                                                    glu::GLSLVersion glslVersion, char const* qualifier, char const* assignment,
216                                                                                    char const* condition, bool unique, GLenum internalFormat,
217                                                                                    tcu::TextureFormat const& texFormat, const char* m_sampler,
218                                                                                    const char* m_outType, GLfloat min, GLfloat max, GLint samples);
219         ~ShaderMultisampleInterpolationBaseCase();
220
221         IterateResult iterate();
222
223 protected:
224         glu::GLSLVersion   m_glslVersion;
225         std::string                m_qualifier;
226         std::string                m_assignment;
227         std::string                m_condition;
228         bool                       m_unique;
229         GLenum                     m_internalFormat;
230         tcu::TextureFormat m_texFormat;
231         std::string                m_sampler;
232         std::string                m_outType;
233         GLfloat                    m_min;
234         GLfloat                    m_max;
235         GLint                      m_samples;
236
237         enum
238         {
239                 WIDTH  = 8,
240                 HEIGHT = 8,
241         };
242
243         int countUniquePixels(tcu::ConstPixelBufferAccess const& pixels);
244         int countUniquePixels(const std::vector<tcu::Vec4>& pixels);
245 };
246
247 ShaderMultisampleInterpolationBaseCase::ShaderMultisampleInterpolationBaseCase(
248         Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion, char const* qualifier,
249         char const* assignment, char const* condition, bool unique, GLenum internalFormat,
250         tcu::TextureFormat const& texFormat, const char* sampler, const char* outType, GLfloat min, GLfloat max,
251         GLint samples)
252         : TestCase(context, name, description)
253         , m_glslVersion(glslVersion)
254         , m_qualifier(qualifier)
255         , m_assignment(assignment)
256         , m_condition(condition)
257         , m_unique(unique)
258         , m_internalFormat(internalFormat)
259         , m_texFormat(texFormat)
260         , m_sampler(sampler)
261         , m_outType(outType)
262         , m_min(min)
263         , m_max(max)
264         , m_samples(samples)
265 {
266         DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_440);
267 }
268
269 ShaderMultisampleInterpolationBaseCase::~ShaderMultisampleInterpolationBaseCase()
270 {
271 }
272
273 ShaderMultisampleInterpolationBaseCase::IterateResult ShaderMultisampleInterpolationBaseCase::iterate()
274 {
275         TestLog&                          log                     = m_testCtx.getLog();
276         const glw::Functions& gl                          = m_context.getRenderContext().getFunctions();
277         bool                              isOk                    = true;
278         bool                              supportsRgba32f = false;
279
280         if (m_glslVersion == glu::GLSL_VERSION_310_ES &&
281                 !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
282         {
283                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_OES_shader_multisample_interpolation");
284                 return STOP;
285         }
286
287         supportsRgba32f = isContextTypeGLCore(m_context.getRenderContext().getType()) ?
288                                                   true :
289                                                   (m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_float") ||
290                                                    m_context.getContextInfo().isExtensionSupported("GL_ARB_color_buffer_float"));
291
292         if (m_internalFormat == GL_RGBA32F && !supportsRgba32f)
293         {
294                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Internalformat rgba32f not supported");
295                 return STOP;
296         }
297
298         GLint maxSamples;
299         if (((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::RGBA)) ||
300                 ((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::RG)) ||
301                 ((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::R)) ||
302                 ((m_texFormat.type == tcu::TextureFormat::HALF_FLOAT) && (m_texFormat.order == tcu::TextureFormat::RGBA)))
303         {
304                 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, m_internalFormat, GL_SAMPLES, 1, &maxSamples);
305                 if (m_samples > maxSamples)
306                 {
307                         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
308                                                                         "Test sample count greater than samples that the format supports");
309                         return STOP;
310                 }
311         }
312         else if (m_texFormat.type == tcu::TextureFormat::SIGNED_INT8 ||
313                          m_texFormat.type == tcu::TextureFormat::UNSIGNED_INT8)
314         {
315                 gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &maxSamples);
316                 if (m_samples > maxSamples)
317                 {
318                         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test sample count greater than MAX_INTEGER_SAMPLES");
319                         return STOP;
320                 }
321         }
322         else
323         {
324                 gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples);
325                 if (m_samples > maxSamples)
326                 {
327                         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test sample count greater than MAX_SAMPLES");
328                         return STOP;
329                 }
330         }
331
332         // Create a multisample texture, or a regular texture if samples is zero.
333         GLuint tex;
334         gl.genTextures(1, &tex);
335         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
336         gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, m_internalFormat, WIDTH, HEIGHT, GL_FALSE);
337
338         // Create a framebuffer with the texture attached.
339         GLuint fboMs;
340         gl.genFramebuffers(1, &fboMs);
341         gl.bindFramebuffer(GL_FRAMEBUFFER, fboMs);
342         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
343         gl.viewport(0, 0, WIDTH, HEIGHT);
344
345         static deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
346
347         {
348                 // Draw with one of the fragment input qualifiers and with one of the
349                 // interpolate functions. Cross-check the result in the shader and
350                 // output the final interpolated value.
351
352                 static char const* vss = "${VERSION_DECL}\n"
353                                                                  "${OES_SMI_RQ}"
354                                                                  "layout(location = 0) in highp vec2 a_position;\n"
355                                                                  "layout(location = 1) in highp vec4 a_color;\n"
356                                                                  "out highp vec4 v_colorBase;\n"
357                                                                  "${QUALIFIER} out highp vec4 v_color;\n"
358                                                                  "void main()\n"
359                                                                  "{\n"
360                                                                  "    v_colorBase = a_color;\n"
361                                                                  "    v_color = a_color;\n"
362                                                                  "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
363                                                                  "}\n";
364
365                 static char const* fss = "${VERSION_DECL}\n"
366                                                                  "${OES_SMI_RQ}"
367                                                                  "${OES_SV_EN}"
368                                                                  "in highp vec4 v_colorBase;\n"
369                                                                  "${QUALIFIER} in highp vec4 v_color;\n"
370                                                                  "layout(location = 0) out highp ${OUT_TYPE} o_color;\n"
371                                                                  "void main()\n"
372                                                                  "{\n"
373                                                                  "    highp vec4 temp = ${ASSIGNMENT};\n"
374                                                                  "    bool condition = ${CONDITION};\n"
375                                                                  "    o_color = ${OUT_TYPE}(temp.x, temp.y, condition, 1);\n"
376                                                                  "}\n";
377
378                 glu::ShaderProgram program(
379                         m_context.getRenderContext(),
380                         glu::makeVtxFragSources(
381                                 specializeVersion(vss, m_glslVersion, m_sampler, m_outType, m_qualifier, m_assignment, m_condition)
382                                         .c_str(),
383                                 specializeVersion(fss, m_glslVersion, m_sampler, m_outType, m_qualifier, m_assignment, m_condition)
384                                         .c_str()));
385                 log << program;
386                 if (!program.isOk())
387                 {
388                         TCU_FAIL("Compile failed");
389                 }
390
391                 static float const position[] = {
392                         -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f,
393                 };
394
395                 const float color[] = {
396                         m_min, m_min, 0.0f, 1.0f, m_min, m_max, 0.0f, 1.0f, m_max, m_min, 0.0f, 1.0f, m_max, m_max, 0.0f, 1.0f,
397                 };
398
399                 gl.useProgram(program.getProgram());
400
401                 glu::VertexArrayBinding vertexArrays[] = {
402                         glu::va::Float("a_position", 2, 4, 0, &position[0]), glu::va::Float("a_color", 4, 4, 0, &color[0]),
403                 };
404                 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
405                                   &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
406
407                 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad");
408         }
409
410         gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
411         gl.deleteFramebuffers(1, &fboMs);
412
413         GLsizei width = WIDTH * m_samples;
414
415         GLuint rbo;
416         gl.genRenderbuffers(1, &rbo);
417         gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
418         gl.renderbufferStorage(GL_RENDERBUFFER, m_internalFormat, width, HEIGHT);
419
420         GLuint fbo;
421         gl.genFramebuffers(1, &fbo);
422         gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
423         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
424         gl.viewport(0, 0, width, HEIGHT);
425
426         {
427                 // Resolve the mutli-sample texture into a render-buffer sized such that
428                 // the width can hold all samples of a pixel.
429
430                 static char const* vss = "${VERSION_DECL}\n"
431                                                                  "in highp vec2 a_position;\n"
432                                                                  "void main(void)\n"
433                                                                  "{\n"
434                                                                  "   gl_Position = vec4(a_position, 0.0, 1.0);\n"
435                                                                  "}\n";
436
437                 static char const* fss = "${VERSION_DECL}\n"
438                                                                  "uniform highp ${SAMPLER}MS u_texMS;\n"
439                                                                  "uniform int u_samples;\n"
440                                                                  "layout(location = 0) out highp ${OUT_TYPE} o_color;\n"
441                                                                  "void main(void)\n"
442                                                                  "{\n"
443                                                                  "    ivec2 coord = ivec2(int(gl_FragCoord.x) / u_samples, gl_FragCoord.y);\n"
444                                                                  "    int sampleId = int(gl_FragCoord.x) % u_samples;\n"
445                                                                  "    o_color = texelFetch(u_texMS, coord, sampleId);\n"
446                                                                  "}\n";
447
448                 glu::ShaderProgram program(
449                         m_context.getRenderContext(),
450                         glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion, m_sampler, m_outType).c_str(),
451                                                                         specializeVersion(fss, m_glslVersion, m_sampler, m_outType).c_str()));
452                 log << program;
453                 if (!program.isOk())
454                 {
455                         TCU_FAIL("Compile failed");
456                 }
457
458                 static float const position[] = {
459                         -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f,
460                 };
461
462                 gl.useProgram(program.getProgram());
463                 gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_samples"), m_samples);
464                 gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_texMS"), 0);
465
466                 glu::VertexArrayBinding vertexArrays[] = {
467                         glu::va::Float("a_position", 2, 4, 0, &position[0]),
468                 };
469                 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
470                                   &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
471
472                 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad");
473         }
474
475         // Verify the results.
476         tcu::TextureLevel         results(m_texFormat, width, HEIGHT);
477         tcu::PixelBufferAccess pixels = results.getAccess();
478         std::vector<tcu::Vec4> result(pixels.getHeight() * pixels.getWidth());
479         int                                        uniquePixels;
480
481         if (pixels.getFormat().type == tcu::TextureFormat::SIGNED_INT8)
482         {
483                 std::vector<GLint> data(pixels.getHeight() * pixels.getWidth() * 4);
484                 gl.readPixels(0, 0, pixels.getWidth(), pixels.getHeight(), GL_RGBA_INTEGER, GL_INT, &data[0]);
485                 for (unsigned int i = 0; i < data.size(); i += 4)
486                 {
487                         result[i / 4] =
488                                 tcu::Vec4((GLfloat)data[i], (GLfloat)data[i + 1], (GLfloat)data[i + 2], (GLfloat)data[i + 3]);
489                 }
490                 uniquePixels = countUniquePixels(result);
491         }
492         else if (pixels.getFormat().type == tcu::TextureFormat::UNSIGNED_INT8)
493         {
494                 std::vector<GLuint> data(pixels.getHeight() * pixels.getWidth() * 4);
495                 gl.readPixels(0, 0, pixels.getWidth(), pixels.getHeight(), GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data[0]);
496                 for (unsigned int i = 0; i < data.size(); i += 4)
497                 {
498                         result[i / 4] =
499                                 tcu::Vec4((GLfloat)data[i], (GLfloat)data[i + 1], (GLfloat)data[i + 2], (GLfloat)data[i + 3]);
500                 }
501                 uniquePixels = countUniquePixels(result);
502         }
503         else
504         {
505                 glu::readPixels(m_context.getRenderContext(), 0, 0, pixels);
506                 uniquePixels = countUniquePixels(pixels);
507         }
508
509         int expectedUnique = WIDTH * HEIGHT * ((m_unique) ? m_samples : 1);
510         if (uniquePixels < expectedUnique)
511         {
512                 // There are duplicate pixel values meaning interpolation didn't work as expected.
513                 isOk = false;
514         }
515         for (int y = 0; y < pixels.getHeight(); ++y)
516         {
517                 for (int x = 0; x < pixels.getWidth(); ++x)
518                 {
519                         tcu::Vec4 pixel;
520                         if (pixels.getFormat().type == tcu::TextureFormat::SIGNED_INT8 ||
521                                 pixels.getFormat().type == tcu::TextureFormat::UNSIGNED_INT8)
522                         {
523                                 pixel = result[y * WIDTH + x];
524                         }
525                         else
526                         {
527                                 pixel = pixels.getPixel(x, y);
528                         }
529                         if (pixel.z() != 1)
530                         {
531                                 // The ${CONDITION} check in the shader failed.
532                                 isOk = false;
533                         }
534                 }
535         }
536
537         gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
538         gl.deleteFramebuffers(1, &fbo);
539
540         gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
541         gl.deleteRenderbuffers(1, &rbo);
542
543         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
544         gl.deleteTextures(1, &tex);
545
546         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
547         return STOP;
548 }
549
550 int ShaderMultisampleInterpolationBaseCase::countUniquePixels(tcu::ConstPixelBufferAccess const& pixels)
551 {
552         std::set<tcu::Vec4> uniquePixels;
553
554         for (int y = 0; y < pixels.getHeight(); ++y)
555         {
556                 for (int x = 0; x < pixels.getWidth(); ++x)
557                 {
558                         uniquePixels.insert(pixels.getPixel(x, y));
559                 }
560         }
561
562         return (int)uniquePixels.size();
563 }
564
565 int ShaderMultisampleInterpolationBaseCase::countUniquePixels(const std::vector<tcu::Vec4>& pixels)
566 {
567         std::set<tcu::Vec4> uniquePixels;
568
569         for (unsigned int i = 0; i < pixels.size(); ++i)
570         {
571                 uniquePixels.insert(pixels[i]);
572         }
573
574         return (int)uniquePixels.size();
575 }
576
577 ShaderMultisampleInterpolationTests::ShaderMultisampleInterpolationTests(Context& context, glu::GLSLVersion glslVersion)
578         : TestCaseGroup(context, "shader_multisample_interpolation", "Shader Multisample Interpolation tests")
579         , m_glslVersion(glslVersion)
580 {
581 }
582
583 ShaderMultisampleInterpolationTests::~ShaderMultisampleInterpolationTests()
584 {
585 }
586
587 void ShaderMultisampleInterpolationTests::init()
588 {
589         struct Sample
590         {
591                 char const* name;
592                 GLint           samples;
593         } samples[] = {
594                 { "samples_1", 1 }, { "samples_2", 2 }, { "samples_4", 4 },
595         };
596
597         // shader_multisample_interpolation.api
598         tcu::TestCaseGroup* apiGroup = new tcu::TestCaseGroup(m_testCtx, "api", "API verification");
599         apiGroup->addChild(new ShaderMultisampleInterpolationApiCase(m_context, "api", "API verification", m_glslVersion));
600         addChild(apiGroup);
601
602         struct Case
603         {
604                 char const* name;
605                 char const* qualifier;
606                 char const* assignment;
607                 char const* condition;
608                 bool            unique;
609         } cases[] = {
610                 { "base", "", "v_color", "true", false },
611                 { "sample", "sample", "v_color", "true", true },
612                 { "centroid", "centroid", "v_color", "true", false },
613                 { "interpolate_at_sample", "", "interpolateAtSample(v_colorBase, gl_SampleID)", "true", true },
614                 { "interpolate_at_sample_check", "sample", "interpolateAtSample(v_colorBase, gl_SampleID)", "temp == v_color",
615                   true },
616                 { "interpolate_at_centroid", "", "interpolateAtCentroid(v_colorBase)", "true", false },
617                 { "interpolate_at_centroid_check", "centroid", "interpolateAtCentroid(v_colorBase)", "temp == v_color", false },
618                 { "interpolate_at_offset", "", "interpolateAtOffset(v_colorBase, gl_SamplePosition - 0.5)", "true", true },
619                 { "interpolate_at_offset_check", "sample", "interpolateAtOffset(v_colorBase, gl_SamplePosition - 0.5)",
620                   "temp == v_color", true },
621         };
622
623         // shader_multisample_interpolation.render
624         tcu::TestCaseGroup* renderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Rendering tests");
625         addChild(renderGroup);
626         for (int caseId = 0; caseId < DE_LENGTH_OF_ARRAY(cases); ++caseId)
627         {
628                 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, cases[caseId].name, "");
629                 renderGroup->addChild(group);
630                 struct Format
631                 {
632                         char const*                name;
633                         GLenum                     internalFormat;
634                         tcu::TextureFormat textureFormat;
635                         char const*                sampler;
636                         char const*                outType;
637                         GLfloat                    min;
638                         GLfloat                    max;
639                 } formats[] = {
640                         { "rgba8", GL_RGBA8, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
641                           "sampler2D", "vec4", 0.0f, 1.0f },
642                         { "rgba8i", GL_RGBA8I, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8),
643                           "isampler2D", "ivec4", -128.0f, 127.0f },
644                         { "rgba8ui", GL_RGBA8UI, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8),
645                           "usampler2D", "uvec4", 0.0f, 255.0f },
646                         { "rgba32f", GL_RGBA32F, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT),
647                           "sampler2D", "vec4", 0.0f, 1.0f },
648                 };
649                 for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); ++format)
650                 {
651                         tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[format].name, "");
652                         group->addChild(formatGroup);
653
654                         for (int sample = 0; sample < DE_LENGTH_OF_ARRAY(samples); ++sample)
655                         {
656                                 formatGroup->addChild(new ShaderMultisampleInterpolationBaseCase(
657                                         m_context, samples[sample].name, "", m_glslVersion, cases[caseId].qualifier,
658                                         cases[caseId].assignment, cases[caseId].condition, cases[caseId].unique,
659                                         formats[format].internalFormat, formats[format].textureFormat, formats[format].sampler,
660                                         formats[format].outType, formats[format].min, formats[format].max, samples[sample].samples));
661                         }
662                 }
663         }
664 }
665
666 } // glcts