1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2014-2016 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci */ /*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief 22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "deMath.h" 25e5c31af7Sopenharmony_ci#include "deRandom.hpp" 26e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 27e5c31af7Sopenharmony_ci#include "gl4cES31CompatibilityTests.hpp" 28e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 29e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp" 30e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 31e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 32e5c31af7Sopenharmony_ci#include "glw.h" 33e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 34e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 35e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 36e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 37e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cinamespace tcu 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_cistatic bool operator<(tcu::Vec4 const& k1, tcu::Vec4 const& k2) 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_ci if (k1.y() < k2.y()) 44e5c31af7Sopenharmony_ci { 45e5c31af7Sopenharmony_ci return true; 46e5c31af7Sopenharmony_ci } 47e5c31af7Sopenharmony_ci else if (k1.y() == k2.y()) 48e5c31af7Sopenharmony_ci { 49e5c31af7Sopenharmony_ci return k1.x() < k2.x(); 50e5c31af7Sopenharmony_ci } 51e5c31af7Sopenharmony_ci else 52e5c31af7Sopenharmony_ci { 53e5c31af7Sopenharmony_ci return false; 54e5c31af7Sopenharmony_ci } 55e5c31af7Sopenharmony_ci} 56e5c31af7Sopenharmony_ci} 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_cinamespace gl4cts 59e5c31af7Sopenharmony_ci{ 60e5c31af7Sopenharmony_cinamespace es31compatibility 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ciusing tcu::TestLog; 64e5c31af7Sopenharmony_ciusing std::string; 65e5c31af7Sopenharmony_ciusing std::vector; 66e5c31af7Sopenharmony_ciusing deqp::Context; 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_cistatic std::string specializeVersion(std::string const& source, glu::GLSLVersion version, 69e5c31af7Sopenharmony_ci std::string const& sampler = "", std::string const& outType = "") 70e5c31af7Sopenharmony_ci{ 71e5c31af7Sopenharmony_ci DE_ASSERT(version == glu::GLSL_VERSION_310_ES || version >= glu::GLSL_VERSION_400); 72e5c31af7Sopenharmony_ci std::map<std::string, std::string> args; 73e5c31af7Sopenharmony_ci args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(version); 74e5c31af7Sopenharmony_ci args["SAMPLER"] = sampler; 75e5c31af7Sopenharmony_ci args["OUT_TYPE"] = outType; 76e5c31af7Sopenharmony_ci if (version == glu::GLSL_VERSION_310_ES) 77e5c31af7Sopenharmony_ci { 78e5c31af7Sopenharmony_ci args["OES_SV_RQ"] = "#extension GL_OES_sample_variables : require\n"; 79e5c31af7Sopenharmony_ci args["OES_SV_EN"] = "#extension GL_OES_sample_variables : enable\n"; 80e5c31af7Sopenharmony_ci } 81e5c31af7Sopenharmony_ci else 82e5c31af7Sopenharmony_ci { 83e5c31af7Sopenharmony_ci args["OES_SV_RQ"] = ""; 84e5c31af7Sopenharmony_ci args["OES_SV_EN"] = ""; 85e5c31af7Sopenharmony_ci } 86e5c31af7Sopenharmony_ci return tcu::StringTemplate(source.c_str()).specialize(args); 87e5c31af7Sopenharmony_ci} 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ciclass SampleShadingExtensionCase : public deqp::TestCase 90e5c31af7Sopenharmony_ci{ 91e5c31af7Sopenharmony_cipublic: 92e5c31af7Sopenharmony_ci SampleShadingExtensionCase(Context& context, const char* name, const char* description, 93e5c31af7Sopenharmony_ci glu::GLSLVersion glslVersion); 94e5c31af7Sopenharmony_ci ~SampleShadingExtensionCase(); 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ci IterateResult iterate(); 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ciprotected: 99e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 100e5c31af7Sopenharmony_ci}; 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ciSampleShadingExtensionCase::SampleShadingExtensionCase(Context& context, const char* name, const char* description, 103e5c31af7Sopenharmony_ci glu::GLSLVersion glslVersion) 104e5c31af7Sopenharmony_ci : TestCase(context, name, description), m_glslVersion(glslVersion) 105e5c31af7Sopenharmony_ci{ 106e5c31af7Sopenharmony_ci DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES); 107e5c31af7Sopenharmony_ci} 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ciSampleShadingExtensionCase::~SampleShadingExtensionCase() 110e5c31af7Sopenharmony_ci{ 111e5c31af7Sopenharmony_ci} 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ciSampleShadingExtensionCase::IterateResult SampleShadingExtensionCase::iterate() 114e5c31af7Sopenharmony_ci{ 115e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci /* OpenGL support query. */ 118e5c31af7Sopenharmony_ci bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 119e5c31af7Sopenharmony_ci bool is_arb_es31_compatibility = m_context.getContextInfo().isExtensionSupported("GL_ARB_ES3_1_compatibility"); 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci if (!(is_at_least_gl_45 || is_arb_es31_compatibility)) 122e5c31af7Sopenharmony_ci { 123e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_ARB_ES3_1_compatibility"); 124e5c31af7Sopenharmony_ci return STOP; 125e5c31af7Sopenharmony_ci } 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci static char const* vss = "${VERSION_DECL}\n" 128e5c31af7Sopenharmony_ci "in highp vec4 a_position;\n" 129e5c31af7Sopenharmony_ci "void main()\n" 130e5c31af7Sopenharmony_ci "{\n" 131e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 132e5c31af7Sopenharmony_ci "}\n"; 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci { 135e5c31af7Sopenharmony_ci static char const* fss = "${VERSION_DECL}\n" 136e5c31af7Sopenharmony_ci "${OES_SV_RQ}" 137e5c31af7Sopenharmony_ci "out highp vec4 o_color;\n" 138e5c31af7Sopenharmony_ci "void main()\n" 139e5c31af7Sopenharmony_ci "{\n" 140e5c31af7Sopenharmony_ci " for (int i = 0; i < (gl_MaxSamples + 31) / 32; ++i) {\n" 141e5c31af7Sopenharmony_ci " gl_SampleMask[i] = gl_SampleMaskIn[i];\n" 142e5c31af7Sopenharmony_ci " }\n" 143e5c31af7Sopenharmony_ci " o_color = vec4(gl_SampleID, gl_SamplePosition.x, gl_SamplePosition.y, 1);\n" 144e5c31af7Sopenharmony_ci "}\n"; 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci glu::ShaderProgram programRequire(m_context.getRenderContext(), 147e5c31af7Sopenharmony_ci glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(), 148e5c31af7Sopenharmony_ci specializeVersion(fss, m_glslVersion).c_str())); 149e5c31af7Sopenharmony_ci log << programRequire; 150e5c31af7Sopenharmony_ci if (!programRequire.isOk()) 151e5c31af7Sopenharmony_ci { 152e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 153e5c31af7Sopenharmony_ci } 154e5c31af7Sopenharmony_ci } 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci { 157e5c31af7Sopenharmony_ci static char const* fss = "${VERSION_DECL}\n" 158e5c31af7Sopenharmony_ci "${OES_SV_EN}" 159e5c31af7Sopenharmony_ci "out highp vec4 o_color;\n" 160e5c31af7Sopenharmony_ci "void main()\n" 161e5c31af7Sopenharmony_ci "{\n" 162e5c31af7Sopenharmony_ci "#if !GL_OES_sample_variables\n" 163e5c31af7Sopenharmony_ci " this is broken\n" 164e5c31af7Sopenharmony_ci "#endif\n" 165e5c31af7Sopenharmony_ci " for (int i = 0; i < (gl_MaxSamples + 31) / 32; ++i) {\n" 166e5c31af7Sopenharmony_ci " gl_SampleMask[i] = gl_SampleMaskIn[i];\n" 167e5c31af7Sopenharmony_ci " }\n" 168e5c31af7Sopenharmony_ci " o_color = vec4(gl_SampleID, gl_SamplePosition.x, gl_SamplePosition.y, 1);\n" 169e5c31af7Sopenharmony_ci "}\n"; 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci glu::ShaderProgram programEnable(m_context.getRenderContext(), 172e5c31af7Sopenharmony_ci glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(), 173e5c31af7Sopenharmony_ci specializeVersion(fss, m_glslVersion).c_str())); 174e5c31af7Sopenharmony_ci log << programEnable; 175e5c31af7Sopenharmony_ci if (!programEnable.isOk()) 176e5c31af7Sopenharmony_ci { 177e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 178e5c31af7Sopenharmony_ci } 179e5c31af7Sopenharmony_ci } 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 182e5c31af7Sopenharmony_ci return STOP; 183e5c31af7Sopenharmony_ci} 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ciclass SampleShadingMaskCase : public deqp::TestCase 186e5c31af7Sopenharmony_ci{ 187e5c31af7Sopenharmony_cipublic: 188e5c31af7Sopenharmony_ci SampleShadingMaskCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion, 189e5c31af7Sopenharmony_ci GLenum internalFormat, tcu::TextureFormat const& texFormat, const char* sampler, 190e5c31af7Sopenharmony_ci const char* outType, GLint samples, GLint sampleMask); 191e5c31af7Sopenharmony_ci ~SampleShadingMaskCase(); 192e5c31af7Sopenharmony_ci 193e5c31af7Sopenharmony_ci IterateResult iterate(); 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ciprotected: 196e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 197e5c31af7Sopenharmony_ci GLenum m_internalFormat; 198e5c31af7Sopenharmony_ci tcu::TextureFormat m_texFormat; 199e5c31af7Sopenharmony_ci std::string m_sampler; 200e5c31af7Sopenharmony_ci std::string m_outType; 201e5c31af7Sopenharmony_ci GLint m_samples; 202e5c31af7Sopenharmony_ci GLint m_sampleMask; 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci enum 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci WIDTH = 16, 207e5c31af7Sopenharmony_ci HEIGHT = 16, 208e5c31af7Sopenharmony_ci MAX_SAMPLES = 4, 209e5c31af7Sopenharmony_ci }; 210e5c31af7Sopenharmony_ci}; 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ciSampleShadingMaskCase::SampleShadingMaskCase(Context& context, const char* name, const char* description, 213e5c31af7Sopenharmony_ci glu::GLSLVersion glslVersion, GLenum internalFormat, 214e5c31af7Sopenharmony_ci tcu::TextureFormat const& texFormat, const char* sampler, 215e5c31af7Sopenharmony_ci const char* outType, GLint samples, GLint sampleMask) 216e5c31af7Sopenharmony_ci : TestCase(context, name, description) 217e5c31af7Sopenharmony_ci , m_glslVersion(glslVersion) 218e5c31af7Sopenharmony_ci , m_internalFormat(internalFormat) 219e5c31af7Sopenharmony_ci , m_texFormat(texFormat) 220e5c31af7Sopenharmony_ci , m_sampler(sampler) 221e5c31af7Sopenharmony_ci , m_outType(outType) 222e5c31af7Sopenharmony_ci , m_samples(samples) 223e5c31af7Sopenharmony_ci , m_sampleMask(sampleMask) 224e5c31af7Sopenharmony_ci{ 225e5c31af7Sopenharmony_ci DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_400); 226e5c31af7Sopenharmony_ci} 227e5c31af7Sopenharmony_ci 228e5c31af7Sopenharmony_ciSampleShadingMaskCase::~SampleShadingMaskCase() 229e5c31af7Sopenharmony_ci{ 230e5c31af7Sopenharmony_ci} 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ciSampleShadingMaskCase::IterateResult SampleShadingMaskCase::iterate() 233e5c31af7Sopenharmony_ci{ 234e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 235e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 236e5c31af7Sopenharmony_ci bool isOk = true; 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ci /* OpenGL support query. */ 239e5c31af7Sopenharmony_ci bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 240e5c31af7Sopenharmony_ci bool is_arb_es31_compatibility = m_context.getContextInfo().isExtensionSupported("GL_ARB_ES3_1_compatibility"); 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci if (!(is_at_least_gl_45 || is_arb_es31_compatibility)) 243e5c31af7Sopenharmony_ci { 244e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_ARB_ES3_1_compatibility"); 245e5c31af7Sopenharmony_ci return STOP; 246e5c31af7Sopenharmony_ci } 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci GLint maxSamples; 249e5c31af7Sopenharmony_ci if (((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::RGBA)) || 250e5c31af7Sopenharmony_ci ((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::RG)) || 251e5c31af7Sopenharmony_ci ((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::R)) || 252e5c31af7Sopenharmony_ci ((m_texFormat.type == tcu::TextureFormat::HALF_FLOAT) && (m_texFormat.order == tcu::TextureFormat::RGBA))) 253e5c31af7Sopenharmony_ci { 254e5c31af7Sopenharmony_ci gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, m_internalFormat, GL_SAMPLES, 1, &maxSamples); 255e5c31af7Sopenharmony_ci if (m_samples > maxSamples) 256e5c31af7Sopenharmony_ci { 257e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, 258e5c31af7Sopenharmony_ci "Test sample count greater than samples that the format supports"); 259e5c31af7Sopenharmony_ci return STOP; 260e5c31af7Sopenharmony_ci } 261e5c31af7Sopenharmony_ci } 262e5c31af7Sopenharmony_ci else if (m_texFormat.type == tcu::TextureFormat::SIGNED_INT8 || 263e5c31af7Sopenharmony_ci m_texFormat.type == tcu::TextureFormat::UNSIGNED_INT8) 264e5c31af7Sopenharmony_ci { 265e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &maxSamples); 266e5c31af7Sopenharmony_ci if (m_samples > maxSamples) 267e5c31af7Sopenharmony_ci { 268e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test sample count greater than MAX_INTEGER_SAMPLES"); 269e5c31af7Sopenharmony_ci return STOP; 270e5c31af7Sopenharmony_ci } 271e5c31af7Sopenharmony_ci } 272e5c31af7Sopenharmony_ci else 273e5c31af7Sopenharmony_ci { 274e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples); 275e5c31af7Sopenharmony_ci if (m_samples > maxSamples) 276e5c31af7Sopenharmony_ci { 277e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test sample count greater than MAX_SAMPLES"); 278e5c31af7Sopenharmony_ci return STOP; 279e5c31af7Sopenharmony_ci } 280e5c31af7Sopenharmony_ci } 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci // Create a multisample texture, or a regular texture if samples is zero. 283e5c31af7Sopenharmony_ci GLuint tex; 284e5c31af7Sopenharmony_ci gl.genTextures(1, &tex); 285e5c31af7Sopenharmony_ci GLenum target; 286e5c31af7Sopenharmony_ci if (m_samples) 287e5c31af7Sopenharmony_ci { 288e5c31af7Sopenharmony_ci target = GL_TEXTURE_2D_MULTISAMPLE; 289e5c31af7Sopenharmony_ci gl.bindTexture(target, tex); 290e5c31af7Sopenharmony_ci gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, m_internalFormat, WIDTH, HEIGHT, GL_FALSE); 291e5c31af7Sopenharmony_ci } 292e5c31af7Sopenharmony_ci else 293e5c31af7Sopenharmony_ci { 294e5c31af7Sopenharmony_ci target = GL_TEXTURE_2D; 295e5c31af7Sopenharmony_ci gl.bindTexture(target, tex); 296e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_2D, 1, m_internalFormat, WIDTH, HEIGHT); 297e5c31af7Sopenharmony_ci if (m_texFormat.type == tcu::TextureFormat::SIGNED_INT8 || 298e5c31af7Sopenharmony_ci m_texFormat.type == tcu::TextureFormat::UNSIGNED_INT8 || m_texFormat.type == tcu::TextureFormat::FLOAT) 299e5c31af7Sopenharmony_ci { 300e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 301e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 302e5c31af7Sopenharmony_ci } 303e5c31af7Sopenharmony_ci } 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ci // Create a framebuffer with the texture attached and clear to "green". 306e5c31af7Sopenharmony_ci GLuint fboMs; 307e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &fboMs); 308e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, fboMs); 309e5c31af7Sopenharmony_ci gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, tex, 0); 310e5c31af7Sopenharmony_ci gl.viewport(0, 0, WIDTH, HEIGHT); 311e5c31af7Sopenharmony_ci if (m_texFormat.type == tcu::TextureFormat::SIGNED_INT8) 312e5c31af7Sopenharmony_ci { 313e5c31af7Sopenharmony_ci GLint color[4] = { 0, 1, 0, 1 }; 314e5c31af7Sopenharmony_ci gl.clearBufferiv(GL_COLOR, 0, color); 315e5c31af7Sopenharmony_ci } 316e5c31af7Sopenharmony_ci else if (m_texFormat.type == tcu::TextureFormat::UNSIGNED_INT8) 317e5c31af7Sopenharmony_ci { 318e5c31af7Sopenharmony_ci GLuint color[4] = { 0, 1, 0, 1 }; 319e5c31af7Sopenharmony_ci gl.clearBufferuiv(GL_COLOR, 0, color); 320e5c31af7Sopenharmony_ci } 321e5c31af7Sopenharmony_ci else 322e5c31af7Sopenharmony_ci { 323e5c31af7Sopenharmony_ci GLfloat color[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; 324e5c31af7Sopenharmony_ci gl.clearBufferfv(GL_COLOR, 0, color); 325e5c31af7Sopenharmony_ci } 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci static deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 }; 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci { 330e5c31af7Sopenharmony_ci // Draw a quad setting all samples to "red". We only expect "red" 331e5c31af7Sopenharmony_ci // to be written if the sample mask bit for that sample is 1. 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_ci static char const* vss = "${VERSION_DECL}\n" 334e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 335e5c31af7Sopenharmony_ci "void main()\n" 336e5c31af7Sopenharmony_ci "{\n" 337e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 338e5c31af7Sopenharmony_ci "}\n"; 339e5c31af7Sopenharmony_ci 340e5c31af7Sopenharmony_ci static char const* fss = "${VERSION_DECL}\n" 341e5c31af7Sopenharmony_ci "${OES_SV_RQ}" 342e5c31af7Sopenharmony_ci "layout(location = 0) out highp ${OUT_TYPE} o_color;\n" 343e5c31af7Sopenharmony_ci "uniform int u_sampleMask;\n" 344e5c31af7Sopenharmony_ci "void main()\n" 345e5c31af7Sopenharmony_ci "{\n" 346e5c31af7Sopenharmony_ci " for (int i = 0; i < (gl_NumSamples + 31) / 32; ++i) {\n" 347e5c31af7Sopenharmony_ci " gl_SampleMask[i] = u_sampleMask & gl_SampleMaskIn[i];\n" 348e5c31af7Sopenharmony_ci " }\n" 349e5c31af7Sopenharmony_ci " o_color = ${OUT_TYPE}(1, 0, 0, 1);\n" 350e5c31af7Sopenharmony_ci "}\n"; 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci glu::ShaderProgram program( 353e5c31af7Sopenharmony_ci m_context.getRenderContext(), 354e5c31af7Sopenharmony_ci glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion, m_sampler, m_outType).c_str(), 355e5c31af7Sopenharmony_ci specializeVersion(fss, m_glslVersion, m_sampler, m_outType).c_str())); 356e5c31af7Sopenharmony_ci log << program; 357e5c31af7Sopenharmony_ci if (!program.isOk()) 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci static float const position[] = { 363e5c31af7Sopenharmony_ci -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, 364e5c31af7Sopenharmony_ci }; 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci gl.useProgram(program.getProgram()); 367e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampleMask"), m_sampleMask); 368e5c31af7Sopenharmony_ci 369e5c31af7Sopenharmony_ci glu::VertexArrayBinding vertexArrays[] = { 370e5c31af7Sopenharmony_ci glu::va::Float("a_position", 2, 4, 0, &position[0]), 371e5c31af7Sopenharmony_ci }; 372e5c31af7Sopenharmony_ci glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), 373e5c31af7Sopenharmony_ci &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0])); 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad"); 376e5c31af7Sopenharmony_ci } 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 379e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &fboMs); 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci GLsizei width = WIDTH * ((m_samples) ? m_samples : 1); 382e5c31af7Sopenharmony_ci 383e5c31af7Sopenharmony_ci GLuint rbo; 384e5c31af7Sopenharmony_ci gl.genRenderbuffers(1, &rbo); 385e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, rbo); 386e5c31af7Sopenharmony_ci gl.renderbufferStorage(GL_RENDERBUFFER, m_internalFormat, width, HEIGHT); 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci GLuint fbo; 389e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &fbo); 390e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); 391e5c31af7Sopenharmony_ci gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); 392e5c31af7Sopenharmony_ci gl.viewport(0, 0, width, HEIGHT); 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ci { 395e5c31af7Sopenharmony_ci // Resolve the multi-sample texture into a render-buffer sized such that 396e5c31af7Sopenharmony_ci // the width can hold all samples of a pixel. 397e5c31af7Sopenharmony_ci static char const* vss = "${VERSION_DECL}\n" 398e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 399e5c31af7Sopenharmony_ci "void main(void)\n" 400e5c31af7Sopenharmony_ci "{\n" 401e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 402e5c31af7Sopenharmony_ci "}\n"; 403e5c31af7Sopenharmony_ci 404e5c31af7Sopenharmony_ci static char const* fss = "${VERSION_DECL}\n" 405e5c31af7Sopenharmony_ci "uniform highp ${SAMPLER} u_tex;\n" 406e5c31af7Sopenharmony_ci "uniform highp ${SAMPLER}MS u_texMS;\n" 407e5c31af7Sopenharmony_ci "uniform int u_samples;\n" 408e5c31af7Sopenharmony_ci "layout(location = 0) out highp ${OUT_TYPE} o_color;\n" 409e5c31af7Sopenharmony_ci "void main(void)\n" 410e5c31af7Sopenharmony_ci "{\n" 411e5c31af7Sopenharmony_ci " if (u_samples > 0) {\n" 412e5c31af7Sopenharmony_ci " ivec2 coord = ivec2(int(gl_FragCoord.x) / u_samples, gl_FragCoord.y);\n" 413e5c31af7Sopenharmony_ci " int sampleId = int(gl_FragCoord.x) % u_samples;\n" 414e5c31af7Sopenharmony_ci " o_color = texelFetch(u_texMS, coord, sampleId);\n" 415e5c31af7Sopenharmony_ci " } else {\n" 416e5c31af7Sopenharmony_ci " ivec2 coord = ivec2(gl_FragCoord.x, gl_FragCoord.y);\n" 417e5c31af7Sopenharmony_ci " o_color = texelFetch(u_tex, coord, 0);\n" 418e5c31af7Sopenharmony_ci " }\n" 419e5c31af7Sopenharmony_ci "}\n"; 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ci glu::ShaderProgram program( 422e5c31af7Sopenharmony_ci m_context.getRenderContext(), 423e5c31af7Sopenharmony_ci glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion, m_sampler, m_outType).c_str(), 424e5c31af7Sopenharmony_ci specializeVersion(fss, m_glslVersion, m_sampler, m_outType).c_str())); 425e5c31af7Sopenharmony_ci log << program; 426e5c31af7Sopenharmony_ci if (!program.isOk()) 427e5c31af7Sopenharmony_ci { 428e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 429e5c31af7Sopenharmony_ci } 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci static float const position[] = { 432e5c31af7Sopenharmony_ci -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, 433e5c31af7Sopenharmony_ci }; 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci gl.useProgram(program.getProgram()); 436e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_samples"), m_samples); 437e5c31af7Sopenharmony_ci if (m_samples > 0) 438e5c31af7Sopenharmony_ci { 439e5c31af7Sopenharmony_ci // only MS sampler needed, TU 1 is not used 440e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_tex"), 1); 441e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_texMS"), 0); 442e5c31af7Sopenharmony_ci } 443e5c31af7Sopenharmony_ci else 444e5c31af7Sopenharmony_ci { 445e5c31af7Sopenharmony_ci // only non-MS sampler needed, TU 1 is not used 446e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_tex"), 0); 447e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_texMS"), 1); 448e5c31af7Sopenharmony_ci } 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci glu::VertexArrayBinding vertexArrays[] = { 451e5c31af7Sopenharmony_ci glu::va::Float("a_position", 2, 4, 0, &position[0]), 452e5c31af7Sopenharmony_ci }; 453e5c31af7Sopenharmony_ci glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), 454e5c31af7Sopenharmony_ci &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0])); 455e5c31af7Sopenharmony_ci 456e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad"); 457e5c31af7Sopenharmony_ci } 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci tcu::TextureLevel textureLevel(m_texFormat, width, HEIGHT); 460e5c31af7Sopenharmony_ci tcu::PixelBufferAccess pixels = textureLevel.getAccess(); 461e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> result(pixels.getHeight() * pixels.getWidth()); 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci if (pixels.getFormat().type == tcu::TextureFormat::SIGNED_INT8) 464e5c31af7Sopenharmony_ci { 465e5c31af7Sopenharmony_ci std::vector<GLint> data(pixels.getHeight() * pixels.getWidth() * 4); 466e5c31af7Sopenharmony_ci gl.readPixels(0, 0, pixels.getWidth(), pixels.getHeight(), GL_RGBA_INTEGER, GL_INT, &data[0]); 467e5c31af7Sopenharmony_ci for (unsigned int i = 0; i < data.size(); i += 4) 468e5c31af7Sopenharmony_ci { 469e5c31af7Sopenharmony_ci result[i / 4] = 470e5c31af7Sopenharmony_ci tcu::Vec4((GLfloat)data[i], (GLfloat)data[i + 1], (GLfloat)data[i + 2], (GLfloat)data[i + 3]); 471e5c31af7Sopenharmony_ci } 472e5c31af7Sopenharmony_ci } 473e5c31af7Sopenharmony_ci else if (pixels.getFormat().type == tcu::TextureFormat::UNSIGNED_INT8) 474e5c31af7Sopenharmony_ci { 475e5c31af7Sopenharmony_ci std::vector<GLuint> data(pixels.getHeight() * pixels.getWidth() * 4); 476e5c31af7Sopenharmony_ci gl.readPixels(0, 0, pixels.getWidth(), pixels.getHeight(), GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data[0]); 477e5c31af7Sopenharmony_ci for (unsigned int i = 0; i < data.size(); i += 4) 478e5c31af7Sopenharmony_ci { 479e5c31af7Sopenharmony_ci result[i / 4] = 480e5c31af7Sopenharmony_ci tcu::Vec4((GLfloat)data[i], (GLfloat)data[i + 1], (GLfloat)data[i + 2], (GLfloat)data[i + 3]); 481e5c31af7Sopenharmony_ci } 482e5c31af7Sopenharmony_ci } 483e5c31af7Sopenharmony_ci else 484e5c31af7Sopenharmony_ci { 485e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, pixels); 486e5c31af7Sopenharmony_ci } 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_ci for (int y = 0; y < HEIGHT; ++y) 489e5c31af7Sopenharmony_ci { 490e5c31af7Sopenharmony_ci for (int x = 0; x < WIDTH; ++x) 491e5c31af7Sopenharmony_ci { 492e5c31af7Sopenharmony_ci GLint samples = (m_samples) ? m_samples : 1; 493e5c31af7Sopenharmony_ci for (int sample = 0; sample < samples; ++sample) 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci tcu::Vec4 pixel; 496e5c31af7Sopenharmony_ci if (pixels.getFormat().type == tcu::TextureFormat::SIGNED_INT8 || 497e5c31af7Sopenharmony_ci pixels.getFormat().type == tcu::TextureFormat::UNSIGNED_INT8) 498e5c31af7Sopenharmony_ci { 499e5c31af7Sopenharmony_ci pixel = result[y * WIDTH + x * samples + sample]; 500e5c31af7Sopenharmony_ci } 501e5c31af7Sopenharmony_ci else 502e5c31af7Sopenharmony_ci { 503e5c31af7Sopenharmony_ci pixel = pixels.getPixel(x * samples + sample, y); 504e5c31af7Sopenharmony_ci } 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci // Make sure only those samples where the sample mask bit is 507e5c31af7Sopenharmony_ci // non-zero have the "red" pixel values. 508e5c31af7Sopenharmony_ci if (!m_samples || (m_sampleMask & (1 << sample))) 509e5c31af7Sopenharmony_ci { 510e5c31af7Sopenharmony_ci if (pixel != tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)) 511e5c31af7Sopenharmony_ci { 512e5c31af7Sopenharmony_ci isOk = false; 513e5c31af7Sopenharmony_ci } 514e5c31af7Sopenharmony_ci } 515e5c31af7Sopenharmony_ci else 516e5c31af7Sopenharmony_ci { 517e5c31af7Sopenharmony_ci if (pixel != tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)) 518e5c31af7Sopenharmony_ci { 519e5c31af7Sopenharmony_ci isOk = false; 520e5c31af7Sopenharmony_ci } 521e5c31af7Sopenharmony_ci } 522e5c31af7Sopenharmony_ci } 523e5c31af7Sopenharmony_ci } 524e5c31af7Sopenharmony_ci } 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 527e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &fbo); 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 530e5c31af7Sopenharmony_ci gl.deleteRenderbuffers(1, &rbo); 531e5c31af7Sopenharmony_ci 532e5c31af7Sopenharmony_ci gl.bindTexture(target, 0); 533e5c31af7Sopenharmony_ci gl.deleteTextures(1, &tex); 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail"); 536e5c31af7Sopenharmony_ci return STOP; 537e5c31af7Sopenharmony_ci} 538e5c31af7Sopenharmony_ci 539e5c31af7Sopenharmony_ciclass SampleShadingPositionCase : public deqp::TestCase 540e5c31af7Sopenharmony_ci{ 541e5c31af7Sopenharmony_cipublic: 542e5c31af7Sopenharmony_ci SampleShadingPositionCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion, 543e5c31af7Sopenharmony_ci GLint samples, GLboolean fixedSampleLocations); 544e5c31af7Sopenharmony_ci ~SampleShadingPositionCase(); 545e5c31af7Sopenharmony_ci 546e5c31af7Sopenharmony_ci IterateResult iterate(); 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ciprotected: 549e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 550e5c31af7Sopenharmony_ci GLint m_samples; 551e5c31af7Sopenharmony_ci GLboolean m_fixedSampleLocations; 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci enum 554e5c31af7Sopenharmony_ci { 555e5c31af7Sopenharmony_ci WIDTH = 8, 556e5c31af7Sopenharmony_ci HEIGHT = 8, 557e5c31af7Sopenharmony_ci MAX_SAMPLES = 8, 558e5c31af7Sopenharmony_ci }; 559e5c31af7Sopenharmony_ci}; 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ciSampleShadingPositionCase::SampleShadingPositionCase(Context& context, const char* name, const char* description, 562e5c31af7Sopenharmony_ci glu::GLSLVersion glslVersion, GLint samples, 563e5c31af7Sopenharmony_ci GLboolean fixedSampleLocations) 564e5c31af7Sopenharmony_ci : TestCase(context, name, description) 565e5c31af7Sopenharmony_ci , m_glslVersion(glslVersion) 566e5c31af7Sopenharmony_ci , m_samples(samples) 567e5c31af7Sopenharmony_ci , m_fixedSampleLocations(fixedSampleLocations) 568e5c31af7Sopenharmony_ci{ 569e5c31af7Sopenharmony_ci DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_400); 570e5c31af7Sopenharmony_ci} 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ciSampleShadingPositionCase::~SampleShadingPositionCase() 573e5c31af7Sopenharmony_ci{ 574e5c31af7Sopenharmony_ci} 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ciSampleShadingPositionCase::IterateResult SampleShadingPositionCase::iterate() 577e5c31af7Sopenharmony_ci{ 578e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 579e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 580e5c31af7Sopenharmony_ci bool isOk = true; 581e5c31af7Sopenharmony_ci 582e5c31af7Sopenharmony_ci /* OpenGL support query. */ 583e5c31af7Sopenharmony_ci bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 584e5c31af7Sopenharmony_ci bool is_arb_es31_compatibility = m_context.getContextInfo().isExtensionSupported("GL_ARB_ES3_1_compatibility"); 585e5c31af7Sopenharmony_ci 586e5c31af7Sopenharmony_ci if (!(is_at_least_gl_45 || is_arb_es31_compatibility)) 587e5c31af7Sopenharmony_ci { 588e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_ARB_ES3_1_compatibility"); 589e5c31af7Sopenharmony_ci return STOP; 590e5c31af7Sopenharmony_ci } 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_ci GLint maxSamples; 593e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples); 594e5c31af7Sopenharmony_ci if (m_samples > maxSamples) 595e5c31af7Sopenharmony_ci { 596e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test sample count great than MAX_SAMPLES"); 597e5c31af7Sopenharmony_ci return STOP; 598e5c31af7Sopenharmony_ci } 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_ci // Create a multisample texture, or a regular texture if samples is zero. 601e5c31af7Sopenharmony_ci GLuint tex; 602e5c31af7Sopenharmony_ci gl.genTextures(1, &tex); 603e5c31af7Sopenharmony_ci GLenum target; 604e5c31af7Sopenharmony_ci if (m_samples) 605e5c31af7Sopenharmony_ci { 606e5c31af7Sopenharmony_ci target = GL_TEXTURE_2D_MULTISAMPLE; 607e5c31af7Sopenharmony_ci gl.bindTexture(target, tex); 608e5c31af7Sopenharmony_ci gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_RGBA8, WIDTH, HEIGHT, 609e5c31af7Sopenharmony_ci m_fixedSampleLocations); 610e5c31af7Sopenharmony_ci } 611e5c31af7Sopenharmony_ci else 612e5c31af7Sopenharmony_ci { 613e5c31af7Sopenharmony_ci target = GL_TEXTURE_2D; 614e5c31af7Sopenharmony_ci gl.bindTexture(target, tex); 615e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, WIDTH, HEIGHT); 616e5c31af7Sopenharmony_ci } 617e5c31af7Sopenharmony_ci 618e5c31af7Sopenharmony_ci // Attach the texture to the framebuffer to render to it. 619e5c31af7Sopenharmony_ci GLuint fboMs; 620e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &fboMs); 621e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, fboMs); 622e5c31af7Sopenharmony_ci gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, tex, 0); 623e5c31af7Sopenharmony_ci gl.viewport(0, 0, WIDTH, HEIGHT); 624e5c31af7Sopenharmony_ci 625e5c31af7Sopenharmony_ci // Save all the sample positions for this multisample framebuffer. 626e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> samplePositions; 627e5c31af7Sopenharmony_ci if (m_samples) 628e5c31af7Sopenharmony_ci { 629e5c31af7Sopenharmony_ci samplePositions.resize(m_samples); 630e5c31af7Sopenharmony_ci for (int sample = 0; sample < m_samples; ++sample) 631e5c31af7Sopenharmony_ci { 632e5c31af7Sopenharmony_ci GLfloat position[2]; 633e5c31af7Sopenharmony_ci gl.getMultisamplefv(GL_SAMPLE_POSITION, sample, position); 634e5c31af7Sopenharmony_ci samplePositions[sample] = tcu::Vec4(position[0], position[1], 0.0f, 1.0f); 635e5c31af7Sopenharmony_ci } 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci static deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 }; 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci { 641e5c31af7Sopenharmony_ci // Render all the sample positions to each pixel sample. 642e5c31af7Sopenharmony_ci 643e5c31af7Sopenharmony_ci static char const* vss = "${VERSION_DECL}\n" 644e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 645e5c31af7Sopenharmony_ci "void main()\n" 646e5c31af7Sopenharmony_ci "{\n" 647e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 648e5c31af7Sopenharmony_ci "}\n"; 649e5c31af7Sopenharmony_ci 650e5c31af7Sopenharmony_ci static char const* fss = "${VERSION_DECL}\n" 651e5c31af7Sopenharmony_ci "${OES_SV_RQ}" 652e5c31af7Sopenharmony_ci "layout(location = 0) out highp vec4 o_color;\n" 653e5c31af7Sopenharmony_ci "void main()\n" 654e5c31af7Sopenharmony_ci "{\n" 655e5c31af7Sopenharmony_ci " o_color = vec4(gl_SamplePosition, 0, 1);\n" 656e5c31af7Sopenharmony_ci "}\n"; 657e5c31af7Sopenharmony_ci 658e5c31af7Sopenharmony_ci glu::ShaderProgram program(m_context.getRenderContext(), 659e5c31af7Sopenharmony_ci glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(), 660e5c31af7Sopenharmony_ci specializeVersion(fss, m_glslVersion).c_str())); 661e5c31af7Sopenharmony_ci log << program; 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci if (!program.isOk()) 664e5c31af7Sopenharmony_ci { 665e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 666e5c31af7Sopenharmony_ci } 667e5c31af7Sopenharmony_ci 668e5c31af7Sopenharmony_ci const float position[] = { 669e5c31af7Sopenharmony_ci -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, 670e5c31af7Sopenharmony_ci }; 671e5c31af7Sopenharmony_ci 672e5c31af7Sopenharmony_ci gl.useProgram(program.getProgram()); 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_ci glu::VertexArrayBinding vertexArrays[] = { 675e5c31af7Sopenharmony_ci glu::va::Float("a_position", 2, 4, 0, &position[0]), 676e5c31af7Sopenharmony_ci }; 677e5c31af7Sopenharmony_ci glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), 678e5c31af7Sopenharmony_ci &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0])); 679e5c31af7Sopenharmony_ci 680e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad"); 681e5c31af7Sopenharmony_ci } 682e5c31af7Sopenharmony_ci 683e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 684e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &fboMs); 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci // Create a regular non-multisample render buffer to resolve to multisample texture into. 687e5c31af7Sopenharmony_ci // The width is increased to save all samples of the pixel. 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ci GLsizei width = WIDTH * ((m_samples) ? m_samples : 1); 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci GLuint rbo; 692e5c31af7Sopenharmony_ci gl.genRenderbuffers(1, &rbo); 693e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, rbo); 694e5c31af7Sopenharmony_ci gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, HEIGHT); 695e5c31af7Sopenharmony_ci 696e5c31af7Sopenharmony_ci GLuint fbo; 697e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &fbo); 698e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); 699e5c31af7Sopenharmony_ci gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); 700e5c31af7Sopenharmony_ci gl.viewport(0, 0, width, HEIGHT); 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci { 703e5c31af7Sopenharmony_ci // Resolve the multisample texture to the renderbuffer. 704e5c31af7Sopenharmony_ci 705e5c31af7Sopenharmony_ci static char const* vss = "${VERSION_DECL}\n" 706e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 707e5c31af7Sopenharmony_ci "void main(void)\n" 708e5c31af7Sopenharmony_ci "{\n" 709e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 710e5c31af7Sopenharmony_ci "}\n"; 711e5c31af7Sopenharmony_ci 712e5c31af7Sopenharmony_ci static char const* fss = "${VERSION_DECL}\n" 713e5c31af7Sopenharmony_ci "uniform highp sampler2D u_tex;\n" 714e5c31af7Sopenharmony_ci "uniform highp sampler2DMS u_texMS;\n" 715e5c31af7Sopenharmony_ci "uniform int u_samples;\n" 716e5c31af7Sopenharmony_ci "layout(location = 0) out highp vec4 o_color;\n" 717e5c31af7Sopenharmony_ci "void main(void)\n" 718e5c31af7Sopenharmony_ci "{\n" 719e5c31af7Sopenharmony_ci " if (u_samples > 0) {\n" 720e5c31af7Sopenharmony_ci " ivec2 coord = ivec2(int(gl_FragCoord.x) / u_samples, gl_FragCoord.y);\n" 721e5c31af7Sopenharmony_ci " int sampleId = int(gl_FragCoord.x) % u_samples;\n" 722e5c31af7Sopenharmony_ci " o_color = texelFetch(u_texMS, coord, sampleId);\n" 723e5c31af7Sopenharmony_ci " } else {\n" 724e5c31af7Sopenharmony_ci " ivec2 coord = ivec2(gl_FragCoord.x, gl_FragCoord.y);\n" 725e5c31af7Sopenharmony_ci " o_color = texelFetch(u_tex, coord, 0);\n" 726e5c31af7Sopenharmony_ci " }\n" 727e5c31af7Sopenharmony_ci "}\n"; 728e5c31af7Sopenharmony_ci 729e5c31af7Sopenharmony_ci glu::ShaderProgram program(m_context.getRenderContext(), 730e5c31af7Sopenharmony_ci glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(), 731e5c31af7Sopenharmony_ci specializeVersion(fss, m_glslVersion).c_str())); 732e5c31af7Sopenharmony_ci log << program; 733e5c31af7Sopenharmony_ci if (!program.isOk()) 734e5c31af7Sopenharmony_ci { 735e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 736e5c31af7Sopenharmony_ci } 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ci static float const position[] = { 739e5c31af7Sopenharmony_ci -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, 740e5c31af7Sopenharmony_ci }; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci gl.useProgram(program.getProgram()); 743e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_samples"), m_samples); 744e5c31af7Sopenharmony_ci if (m_samples > 0) 745e5c31af7Sopenharmony_ci { 746e5c31af7Sopenharmony_ci // only MS sampler needed, TU 1 is not used 747e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_tex"), 1); 748e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_texMS"), 0); 749e5c31af7Sopenharmony_ci } 750e5c31af7Sopenharmony_ci else 751e5c31af7Sopenharmony_ci { 752e5c31af7Sopenharmony_ci // only non-MS sampler needed, TU 1 is not used 753e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_tex"), 0); 754e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_texMS"), 1); 755e5c31af7Sopenharmony_ci } 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_ci glu::VertexArrayBinding vertexArrays[] = { 758e5c31af7Sopenharmony_ci glu::va::Float("a_position", 2, 4, 0, &position[0]), 759e5c31af7Sopenharmony_ci }; 760e5c31af7Sopenharmony_ci glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), 761e5c31af7Sopenharmony_ci &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0])); 762e5c31af7Sopenharmony_ci 763e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad"); 764e5c31af7Sopenharmony_ci } 765e5c31af7Sopenharmony_ci 766e5c31af7Sopenharmony_ci // Read the renderbuffer pixels and verify we get back what we're expecting. 767e5c31af7Sopenharmony_ci tcu::TextureLevel results(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, 768e5c31af7Sopenharmony_ci HEIGHT); 769e5c31af7Sopenharmony_ci tcu::PixelBufferAccess pixels = results.getAccess(); 770e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, pixels); 771e5c31af7Sopenharmony_ci if (m_samples) 772e5c31af7Sopenharmony_ci { 773e5c31af7Sopenharmony_ci // If m_fixedSampleLocations are used make sure the first pixel's samples 774e5c31af7Sopenharmony_ci // all match the SAMPLE_POSITION state saved earlier. 775e5c31af7Sopenharmony_ci std::set<tcu::Vec4> fixedSampleLocations; 776e5c31af7Sopenharmony_ci if (m_fixedSampleLocations) 777e5c31af7Sopenharmony_ci { 778e5c31af7Sopenharmony_ci for (int sample = 0; sample < m_samples; ++sample) 779e5c31af7Sopenharmony_ci { 780e5c31af7Sopenharmony_ci tcu::Vec4 pixel = pixels.getPixel(sample, 0); 781e5c31af7Sopenharmony_ci fixedSampleLocations.insert(pixel); 782e5c31af7Sopenharmony_ci if (deFloatAbs(pixel.x() - samplePositions[sample].x()) > 0.01 || 783e5c31af7Sopenharmony_ci deFloatAbs(pixel.y() - samplePositions[sample].y()) > 0.01) 784e5c31af7Sopenharmony_ci { 785e5c31af7Sopenharmony_ci 786e5c31af7Sopenharmony_ci isOk = false; 787e5c31af7Sopenharmony_ci } 788e5c31af7Sopenharmony_ci } 789e5c31af7Sopenharmony_ci } 790e5c31af7Sopenharmony_ci 791e5c31af7Sopenharmony_ci // Verify all samples of every pixel to make sure each position is unique. 792e5c31af7Sopenharmony_ci for (int y = 0; y < HEIGHT; ++y) 793e5c31af7Sopenharmony_ci { 794e5c31af7Sopenharmony_ci for (int x = 0; x < WIDTH; ++x) 795e5c31af7Sopenharmony_ci { 796e5c31af7Sopenharmony_ci std::set<tcu::Vec4> uniquePixels; 797e5c31af7Sopenharmony_ci for (int sample = 0; sample < m_samples; ++sample) 798e5c31af7Sopenharmony_ci { 799e5c31af7Sopenharmony_ci uniquePixels.insert(pixels.getPixel(x * m_samples + sample, y)); 800e5c31af7Sopenharmony_ci } 801e5c31af7Sopenharmony_ci if ((GLint)uniquePixels.size() != m_samples) 802e5c31af7Sopenharmony_ci { 803e5c31af7Sopenharmony_ci isOk = false; 804e5c31af7Sopenharmony_ci } 805e5c31af7Sopenharmony_ci // For the m_fixedSampleLocations case make sure each position 806e5c31af7Sopenharmony_ci // matches the sample positions of pixel(0, 0) saved earlier. 807e5c31af7Sopenharmony_ci if (m_fixedSampleLocations) 808e5c31af7Sopenharmony_ci { 809e5c31af7Sopenharmony_ci if (fixedSampleLocations != uniquePixels) 810e5c31af7Sopenharmony_ci { 811e5c31af7Sopenharmony_ci isOk = false; 812e5c31af7Sopenharmony_ci } 813e5c31af7Sopenharmony_ci } 814e5c31af7Sopenharmony_ci } 815e5c31af7Sopenharmony_ci } 816e5c31af7Sopenharmony_ci } 817e5c31af7Sopenharmony_ci else 818e5c31af7Sopenharmony_ci { 819e5c31af7Sopenharmony_ci // For the non-multisample case make sure all the positions are (0.5,0.5). 820e5c31af7Sopenharmony_ci for (int y = 0; y < pixels.getHeight(); ++y) 821e5c31af7Sopenharmony_ci { 822e5c31af7Sopenharmony_ci for (int x = 0; x < pixels.getWidth(); ++x) 823e5c31af7Sopenharmony_ci { 824e5c31af7Sopenharmony_ci tcu::Vec4 pixel = pixels.getPixel(x, y); 825e5c31af7Sopenharmony_ci if (deFloatAbs(pixel.x() - 0.5f) > 0.01 || deFloatAbs(pixel.y() - 0.5f) > 0.01 || pixel.z() != 0.0f || 826e5c31af7Sopenharmony_ci pixel.w() != 1.0f) 827e5c31af7Sopenharmony_ci { 828e5c31af7Sopenharmony_ci isOk = false; 829e5c31af7Sopenharmony_ci } 830e5c31af7Sopenharmony_ci } 831e5c31af7Sopenharmony_ci } 832e5c31af7Sopenharmony_ci } 833e5c31af7Sopenharmony_ci 834e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 835e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &fbo); 836e5c31af7Sopenharmony_ci 837e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 838e5c31af7Sopenharmony_ci gl.deleteRenderbuffers(1, &rbo); 839e5c31af7Sopenharmony_ci 840e5c31af7Sopenharmony_ci gl.bindTexture(target, 0); 841e5c31af7Sopenharmony_ci gl.deleteTextures(1, &tex); 842e5c31af7Sopenharmony_ci 843e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail"); 844e5c31af7Sopenharmony_ci return STOP; 845e5c31af7Sopenharmony_ci} 846e5c31af7Sopenharmony_ci 847e5c31af7Sopenharmony_ciSampleVariablesTests::SampleVariablesTests(Context& context, glu::GLSLVersion glslVersion) 848e5c31af7Sopenharmony_ci : TestCaseGroup(context, "sample_variables", "Sample Variables tests"), m_glslVersion(glslVersion) 849e5c31af7Sopenharmony_ci{ 850e5c31af7Sopenharmony_ci} 851e5c31af7Sopenharmony_ci 852e5c31af7Sopenharmony_ciSampleVariablesTests::~SampleVariablesTests() 853e5c31af7Sopenharmony_ci{ 854e5c31af7Sopenharmony_ci} 855e5c31af7Sopenharmony_ci 856e5c31af7Sopenharmony_civoid SampleVariablesTests::init() 857e5c31af7Sopenharmony_ci{ 858e5c31af7Sopenharmony_ci de::Random rnd(m_context.getTestContext().getCommandLine().getBaseSeed()); 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_ci struct Sample 861e5c31af7Sopenharmony_ci { 862e5c31af7Sopenharmony_ci char const* name; 863e5c31af7Sopenharmony_ci GLint samples; 864e5c31af7Sopenharmony_ci } samples[] = { 865e5c31af7Sopenharmony_ci { "samples_0", 0 }, { "samples_1", 1 }, { "samples_2", 2 }, { "samples_4", 4 }, { "samples_8", 8 }, 866e5c31af7Sopenharmony_ci }; 867e5c31af7Sopenharmony_ci 868e5c31af7Sopenharmony_ci // sample_variables.extension 869e5c31af7Sopenharmony_ci if (m_glslVersion == glu::GLSL_VERSION_310_ES) 870e5c31af7Sopenharmony_ci { 871e5c31af7Sopenharmony_ci addChild(new SampleShadingExtensionCase(m_context, "extension", "#extension verification", m_glslVersion)); 872e5c31af7Sopenharmony_ci } 873e5c31af7Sopenharmony_ci 874e5c31af7Sopenharmony_ci // sample_variables.mask 875e5c31af7Sopenharmony_ci tcu::TestCaseGroup* maskGroup = new tcu::TestCaseGroup(m_testCtx, "mask", "gl_SampleMask tests"); 876e5c31af7Sopenharmony_ci addChild(maskGroup); 877e5c31af7Sopenharmony_ci struct Format 878e5c31af7Sopenharmony_ci { 879e5c31af7Sopenharmony_ci char const* name; 880e5c31af7Sopenharmony_ci GLenum internalFormat; 881e5c31af7Sopenharmony_ci tcu::TextureFormat textureFormat; 882e5c31af7Sopenharmony_ci char const* sampler; 883e5c31af7Sopenharmony_ci char const* outType; 884e5c31af7Sopenharmony_ci } formats[] = { 885e5c31af7Sopenharmony_ci { "rgba8", GL_RGBA8, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), "sampler2D", 886e5c31af7Sopenharmony_ci "vec4" }, 887e5c31af7Sopenharmony_ci { "rgba8i", GL_RGBA8I, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8), 888e5c31af7Sopenharmony_ci "isampler2D", "ivec4" }, 889e5c31af7Sopenharmony_ci { "rgba8ui", GL_RGBA8UI, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8), 890e5c31af7Sopenharmony_ci "usampler2D", "uvec4" }, 891e5c31af7Sopenharmony_ci { "rgba32f", GL_RGBA32F, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), "sampler2D", 892e5c31af7Sopenharmony_ci "vec4" }, 893e5c31af7Sopenharmony_ci }; 894e5c31af7Sopenharmony_ci for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); ++format) 895e5c31af7Sopenharmony_ci { 896e5c31af7Sopenharmony_ci tcu::TestCaseGroup* maskFormatGroup = new tcu::TestCaseGroup(m_testCtx, formats[format].name, ""); 897e5c31af7Sopenharmony_ci maskGroup->addChild(maskFormatGroup); 898e5c31af7Sopenharmony_ci 899e5c31af7Sopenharmony_ci for (int sample = 0; sample < DE_LENGTH_OF_ARRAY(samples); ++sample) 900e5c31af7Sopenharmony_ci { 901e5c31af7Sopenharmony_ci tcu::TestCaseGroup* maskFormatSampleGroup = new tcu::TestCaseGroup(m_testCtx, samples[sample].name, ""); 902e5c31af7Sopenharmony_ci maskFormatGroup->addChild(maskFormatSampleGroup); 903e5c31af7Sopenharmony_ci 904e5c31af7Sopenharmony_ci maskFormatSampleGroup->addChild( 905e5c31af7Sopenharmony_ci new SampleShadingMaskCase(m_context, "mask_zero", "", m_glslVersion, formats[format].internalFormat, 906e5c31af7Sopenharmony_ci formats[format].textureFormat, formats[format].sampler, 907e5c31af7Sopenharmony_ci formats[format].outType, samples[sample].samples, 0)); 908e5c31af7Sopenharmony_ci 909e5c31af7Sopenharmony_ci for (int mask = 0; mask < SAMPLE_MASKS; ++mask) 910e5c31af7Sopenharmony_ci { 911e5c31af7Sopenharmony_ci std::stringstream ss; 912e5c31af7Sopenharmony_ci ss << "mask_" << mask; 913e5c31af7Sopenharmony_ci maskFormatSampleGroup->addChild(new SampleShadingMaskCase( 914e5c31af7Sopenharmony_ci m_context, ss.str().c_str(), "", m_glslVersion, formats[format].internalFormat, 915e5c31af7Sopenharmony_ci formats[format].textureFormat, formats[format].sampler, formats[format].outType, 916e5c31af7Sopenharmony_ci samples[sample].samples, rnd.getUint32())); 917e5c31af7Sopenharmony_ci } 918e5c31af7Sopenharmony_ci } 919e5c31af7Sopenharmony_ci } 920e5c31af7Sopenharmony_ci 921e5c31af7Sopenharmony_ci // sample_variables.position 922e5c31af7Sopenharmony_ci tcu::TestCaseGroup* positionGroup = new tcu::TestCaseGroup(m_testCtx, "position", "gl_SamplePosition tests"); 923e5c31af7Sopenharmony_ci addChild(positionGroup); 924e5c31af7Sopenharmony_ci struct Fixed 925e5c31af7Sopenharmony_ci { 926e5c31af7Sopenharmony_ci char const* name; 927e5c31af7Sopenharmony_ci GLboolean fixedSampleLocations; 928e5c31af7Sopenharmony_ci } fixed[] = { 929e5c31af7Sopenharmony_ci { "non-fixed", GL_FALSE }, { "fixed", GL_TRUE }, 930e5c31af7Sopenharmony_ci }; 931e5c31af7Sopenharmony_ci for (int j = 0; j < DE_LENGTH_OF_ARRAY(fixed); ++j) 932e5c31af7Sopenharmony_ci { 933e5c31af7Sopenharmony_ci tcu::TestCaseGroup* positionFixedGroup = new tcu::TestCaseGroup(m_testCtx, fixed[j].name, ""); 934e5c31af7Sopenharmony_ci positionGroup->addChild(positionFixedGroup); 935e5c31af7Sopenharmony_ci for (int sample = 0; sample < DE_LENGTH_OF_ARRAY(samples); ++sample) 936e5c31af7Sopenharmony_ci { 937e5c31af7Sopenharmony_ci positionFixedGroup->addChild(new SampleShadingPositionCase(m_context, samples[sample].name, "", 938e5c31af7Sopenharmony_ci m_glslVersion, samples[sample].samples, 939e5c31af7Sopenharmony_ci fixed[j].fixedSampleLocations)); 940e5c31af7Sopenharmony_ci } 941e5c31af7Sopenharmony_ci } 942e5c31af7Sopenharmony_ci} 943e5c31af7Sopenharmony_ci 944e5c31af7Sopenharmony_ci} // es31compatibility 945e5c31af7Sopenharmony_ci} // gl4cts 946