1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 2.0 Module 3e5c31af7Sopenharmony_ci * ------------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 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 Special float stress tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es2sSpecialFloatTests.hpp" 25e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 26e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 27e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 28e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 29e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 30e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 31e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 32e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 33e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 34e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 35e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp" 36e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 37e5c31af7Sopenharmony_ci#include "deMath.h" 38e5c31af7Sopenharmony_ci#include "deRandom.hpp" 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include <limits> 41e5c31af7Sopenharmony_ci#include <sstream> 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ciusing namespace glw; 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_cinamespace deqp 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_cinamespace gles2 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_cinamespace Stress 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_cinamespace 52e5c31af7Sopenharmony_ci{ 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_cistatic const int TEST_CANVAS_SIZE = 256; 55e5c31af7Sopenharmony_cistatic const int TEST_TEXTURE_SIZE = 128; 56e5c31af7Sopenharmony_cistatic const int TEST_TEXTURE_CUBE_SIZE = 32; 57e5c31af7Sopenharmony_cistatic const deUint32 s_specialFloats[] = 58e5c31af7Sopenharmony_ci{ 59e5c31af7Sopenharmony_ci 0x00000000, // zero 60e5c31af7Sopenharmony_ci 0x80000000, // negative zero 61e5c31af7Sopenharmony_ci 0x3F800000, // one 62e5c31af7Sopenharmony_ci 0xBF800000, // negative one 63e5c31af7Sopenharmony_ci 0x00800000, // minimum positive normalized value 64e5c31af7Sopenharmony_ci 0x80800000, // maximum negative normalized value 65e5c31af7Sopenharmony_ci 0x00000001, // minimum positive denorm value 66e5c31af7Sopenharmony_ci 0x80000001, // maximum negative denorm value 67e5c31af7Sopenharmony_ci 0x7F7FFFFF, // maximum finite value. 68e5c31af7Sopenharmony_ci 0xFF7FFFFF, // minimum finite value. 69e5c31af7Sopenharmony_ci 0x7F800000, // inf 70e5c31af7Sopenharmony_ci 0xFF800000, // -inf 71e5c31af7Sopenharmony_ci 0x34000000, // epsilon 72e5c31af7Sopenharmony_ci 0xB4000000, // negative epsilon 73e5c31af7Sopenharmony_ci 0x7FC00000, // quiet_NaN 74e5c31af7Sopenharmony_ci 0xFFC00000, // negative quiet_NaN 75e5c31af7Sopenharmony_ci 0x7FC00001, // signaling_NaN 76e5c31af7Sopenharmony_ci 0xFFC00001, // negative signaling_NaN 77e5c31af7Sopenharmony_ci 0x7FEAAAAA, // quiet payloaded NaN (payload of repeated pattern of 101010...) 78e5c31af7Sopenharmony_ci 0xFFEAAAAA, // negative quiet payloaded NaN ( .. ) 79e5c31af7Sopenharmony_ci 0x7FAAAAAA, // signaling payloaded NaN ( .. ) 80e5c31af7Sopenharmony_ci 0xFFAAAAAA, // negative signaling payloaded NaN ( .. ) 81e5c31af7Sopenharmony_ci}; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_cistatic const char* const s_colorPassthroughFragmentShaderSource = "varying mediump vec4 v_out;\n" 84e5c31af7Sopenharmony_ci "void main ()\n" 85e5c31af7Sopenharmony_ci "{\n" 86e5c31af7Sopenharmony_ci " gl_FragColor = v_out;\n" 87e5c31af7Sopenharmony_ci "}\n"; 88e5c31af7Sopenharmony_cistatic const char* const s_attrPassthroughVertexShaderSource = "attribute highp vec4 a_pos;\n" 89e5c31af7Sopenharmony_ci "attribute highp vec4 a_attr;\n" 90e5c31af7Sopenharmony_ci "varying mediump vec4 v_attr;\n" 91e5c31af7Sopenharmony_ci "void main ()\n" 92e5c31af7Sopenharmony_ci "{\n" 93e5c31af7Sopenharmony_ci " v_attr = a_attr;\n" 94e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 95e5c31af7Sopenharmony_ci "}\n"; 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ciclass RenderCase : public TestCase 98e5c31af7Sopenharmony_ci{ 99e5c31af7Sopenharmony_cipublic: 100e5c31af7Sopenharmony_ci enum RenderTargetType 101e5c31af7Sopenharmony_ci { 102e5c31af7Sopenharmony_ci RENDERTARGETTYPE_SCREEN, 103e5c31af7Sopenharmony_ci RENDERTARGETTYPE_FBO 104e5c31af7Sopenharmony_ci }; 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ci RenderCase (Context& context, const char* name, const char* desc, RenderTargetType renderTargetType = RENDERTARGETTYPE_SCREEN); 107e5c31af7Sopenharmony_ci virtual ~RenderCase (void); 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci virtual void init (void); 110e5c31af7Sopenharmony_ci virtual void deinit (void); 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ciprotected: 113e5c31af7Sopenharmony_ci bool checkResultImage (const tcu::Surface& result); 114e5c31af7Sopenharmony_ci bool drawTestPattern (bool useTexture); 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci virtual std::string genVertexSource (void) const = 0; 117e5c31af7Sopenharmony_ci virtual std::string genFragmentSource (void) const = 0; 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci const glu::ShaderProgram* m_program; 120e5c31af7Sopenharmony_ci const RenderTargetType m_renderTargetType; 121e5c31af7Sopenharmony_ci}; 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ciRenderCase::RenderCase (Context& context, const char* name, const char* desc, RenderTargetType renderTargetType) 124e5c31af7Sopenharmony_ci : TestCase (context, name, desc) 125e5c31af7Sopenharmony_ci , m_program (DE_NULL) 126e5c31af7Sopenharmony_ci , m_renderTargetType (renderTargetType) 127e5c31af7Sopenharmony_ci{ 128e5c31af7Sopenharmony_ci} 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ciRenderCase::~RenderCase (void) 131e5c31af7Sopenharmony_ci{ 132e5c31af7Sopenharmony_ci deinit(); 133e5c31af7Sopenharmony_ci} 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_civoid RenderCase::init (void) 136e5c31af7Sopenharmony_ci{ 137e5c31af7Sopenharmony_ci const int width = m_context.getRenderTarget().getWidth(); 138e5c31af7Sopenharmony_ci const int height = m_context.getRenderTarget().getHeight(); 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci // check target size 141e5c31af7Sopenharmony_ci if (m_renderTargetType == RENDERTARGETTYPE_SCREEN) 142e5c31af7Sopenharmony_ci { 143e5c31af7Sopenharmony_ci if (width < TEST_CANVAS_SIZE || height < TEST_CANVAS_SIZE) 144e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(std::string("Render target size must be at least ") + de::toString(TEST_CANVAS_SIZE) + "x" + de::toString(TEST_CANVAS_SIZE)); 145e5c31af7Sopenharmony_ci } 146e5c31af7Sopenharmony_ci else if (m_renderTargetType == RENDERTARGETTYPE_FBO) 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci GLint maxTexSize = 0; 149e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci if (maxTexSize < TEST_CANVAS_SIZE) 152e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_CANVAS_SIZE)); 153e5c31af7Sopenharmony_ci } 154e5c31af7Sopenharmony_ci else 155e5c31af7Sopenharmony_ci DE_ASSERT(false); 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci // gen shader 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shader." << tcu::TestLog::EndMessage; 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource()) << glu::FragmentSource(genFragmentSource())); 162e5c31af7Sopenharmony_ci m_testCtx.getLog() << *m_program; 163e5c31af7Sopenharmony_ci 164e5c31af7Sopenharmony_ci if (!m_program->isOk()) 165e5c31af7Sopenharmony_ci throw tcu::TestError("shader compile failed"); 166e5c31af7Sopenharmony_ci} 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_civoid RenderCase::deinit (void) 169e5c31af7Sopenharmony_ci{ 170e5c31af7Sopenharmony_ci if (m_program) 171e5c31af7Sopenharmony_ci { 172e5c31af7Sopenharmony_ci delete m_program; 173e5c31af7Sopenharmony_ci m_program = DE_NULL; 174e5c31af7Sopenharmony_ci } 175e5c31af7Sopenharmony_ci} 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_cibool RenderCase::checkResultImage (const tcu::Surface& result) 178e5c31af7Sopenharmony_ci{ 179e5c31af7Sopenharmony_ci tcu::Surface errorMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 180e5c31af7Sopenharmony_ci bool error = false; 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image." << tcu::TestLog::EndMessage; 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci for (int y = 0; y < TEST_CANVAS_SIZE; ++y) 185e5c31af7Sopenharmony_ci for (int x = 0; x < TEST_CANVAS_SIZE; ++x) 186e5c31af7Sopenharmony_ci { 187e5c31af7Sopenharmony_ci const tcu::RGBA col = result.getPixel(x, y); 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci if (col.getGreen() == 255) 190e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, tcu::RGBA::green()); 191e5c31af7Sopenharmony_ci else 192e5c31af7Sopenharmony_ci { 193e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, tcu::RGBA::red()); 194e5c31af7Sopenharmony_ci error = true; 195e5c31af7Sopenharmony_ci } 196e5c31af7Sopenharmony_ci } 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_ci if (error) 199e5c31af7Sopenharmony_ci { 200e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Result image has missing or invalid pixels" << tcu::TestLog::EndMessage; 201e5c31af7Sopenharmony_ci m_testCtx.getLog() 202e5c31af7Sopenharmony_ci << tcu::TestLog::ImageSet("Results", "Result verification") 203e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Result", "Result", result) 204e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Error mask", "Error mask", errorMask) 205e5c31af7Sopenharmony_ci << tcu::TestLog::EndImageSet; 206e5c31af7Sopenharmony_ci } 207e5c31af7Sopenharmony_ci else 208e5c31af7Sopenharmony_ci { 209e5c31af7Sopenharmony_ci m_testCtx.getLog() 210e5c31af7Sopenharmony_ci << tcu::TestLog::ImageSet("Results", "Result verification") 211e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Result", "Result", result) 212e5c31af7Sopenharmony_ci << tcu::TestLog::EndImageSet; 213e5c31af7Sopenharmony_ci } 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci return !error; 216e5c31af7Sopenharmony_ci} 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_cibool RenderCase::drawTestPattern (bool useTexture) 219e5c31af7Sopenharmony_ci{ 220e5c31af7Sopenharmony_ci static const tcu::Vec4 fullscreenQuad[4] = 221e5c31af7Sopenharmony_ci { 222e5c31af7Sopenharmony_ci tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), 223e5c31af7Sopenharmony_ci tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), 224e5c31af7Sopenharmony_ci tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), 225e5c31af7Sopenharmony_ci tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), 226e5c31af7Sopenharmony_ci }; 227e5c31af7Sopenharmony_ci const char* const vertexSource = "attribute highp vec4 a_pos;\n" 228e5c31af7Sopenharmony_ci "varying mediump vec4 v_position;\n" 229e5c31af7Sopenharmony_ci "void main ()\n" 230e5c31af7Sopenharmony_ci "{\n" 231e5c31af7Sopenharmony_ci " v_position = a_pos;\n" 232e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 233e5c31af7Sopenharmony_ci "}\n"; 234e5c31af7Sopenharmony_ci const char* const fragmentSourceNoTex = "varying mediump vec4 v_position;\n" 235e5c31af7Sopenharmony_ci "void main ()\n" 236e5c31af7Sopenharmony_ci "{\n" 237e5c31af7Sopenharmony_ci " gl_FragColor = vec4((v_position.x + 1.0) * 0.5, 1.0, 1.0, 1.0);\n" 238e5c31af7Sopenharmony_ci "}\n"; 239e5c31af7Sopenharmony_ci const char* const fragmentSourceTex = "uniform mediump sampler2D u_sampler;\n" 240e5c31af7Sopenharmony_ci "varying mediump vec4 v_position;\n" 241e5c31af7Sopenharmony_ci "void main ()\n" 242e5c31af7Sopenharmony_ci "{\n" 243e5c31af7Sopenharmony_ci " gl_FragColor = texture2D(u_sampler, v_position.xy);\n" 244e5c31af7Sopenharmony_ci "}\n"; 245e5c31af7Sopenharmony_ci const char* const fragmentSource = (useTexture) ? (fragmentSourceTex) : (fragmentSourceNoTex); 246e5c31af7Sopenharmony_ci const tcu::RGBA formatThreshold = m_context.getRenderTarget().getPixelFormat().getColorThreshold(); 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci tcu::Surface resultImage (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 249e5c31af7Sopenharmony_ci tcu::Surface errorMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 250e5c31af7Sopenharmony_ci bool error = false; 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a test pattern to detect " << ((useTexture) ? ("texture sampling") : ("")) << " side-effects." << tcu::TestLog::EndMessage; 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ci // draw pattern 255e5c31af7Sopenharmony_ci { 256e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 257e5c31af7Sopenharmony_ci const glu::ShaderProgram patternProgram (m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource)); 258e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(patternProgram.getProgram(), "a_pos"); 259e5c31af7Sopenharmony_ci GLuint textureID = 0; 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci if (useTexture) 262e5c31af7Sopenharmony_ci { 263e5c31af7Sopenharmony_ci const int textureSize = 32; 264e5c31af7Sopenharmony_ci std::vector<tcu::Vector<deUint8, 4> > buffer(textureSize*textureSize); 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ci for (int x = 0; x < textureSize; ++x) 267e5c31af7Sopenharmony_ci for (int y = 0; y < textureSize; ++y) 268e5c31af7Sopenharmony_ci { 269e5c31af7Sopenharmony_ci // sum of two axis aligned gradients. Each gradient is 127 at the edges and 0 at the center. 270e5c31af7Sopenharmony_ci // pattern is symmetric (x and y) => no discontinuity near boundary => no need to worry of results with LINEAR filtering near boundaries 271e5c31af7Sopenharmony_ci const deUint8 redComponent = (deUint8)de::clamp(de::abs((float)x / (float)textureSize - 0.5f) * 255.0f + de::abs((float)y / (float)textureSize - 0.5f) * 255.0f, 0.0f, 255.0f); 272e5c31af7Sopenharmony_ci 273e5c31af7Sopenharmony_ci buffer[x * textureSize + y] = tcu::Vector<deUint8, 4>(redComponent, 255, 255, 255); 274e5c31af7Sopenharmony_ci } 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci gl.genTextures(1, &textureID); 277e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, textureID); 278e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureSize, textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer[0].getPtr()); 279e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 280e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 281e5c31af7Sopenharmony_ci } 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 284e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 285e5c31af7Sopenharmony_ci gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 286e5c31af7Sopenharmony_ci gl.useProgram(patternProgram.getProgram()); 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci if (useTexture) 289e5c31af7Sopenharmony_ci gl.uniform1i(gl.getUniformLocation(patternProgram.getProgram(), "u_sampler"), 0); 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &fullscreenQuad[0]); 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 294e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 295e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 296e5c31af7Sopenharmony_ci 297e5c31af7Sopenharmony_ci gl.useProgram(0); 298e5c31af7Sopenharmony_ci gl.finish(); 299e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "RenderCase::drawTestPattern"); 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci if (textureID) 302e5c31af7Sopenharmony_ci gl.deleteTextures(1, &textureID); 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess()); 305e5c31af7Sopenharmony_ci } 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ci // verify pattern 308e5c31af7Sopenharmony_ci for (int y = 0; y < TEST_CANVAS_SIZE; ++y) 309e5c31af7Sopenharmony_ci for (int x = 0; x < TEST_CANVAS_SIZE; ++x) 310e5c31af7Sopenharmony_ci { 311e5c31af7Sopenharmony_ci const float texGradientPosX = deFloatFrac((float)x * 2.0f / (float)TEST_CANVAS_SIZE); 312e5c31af7Sopenharmony_ci const float texGradientPosY = deFloatFrac((float)y * 2.0f / (float)TEST_CANVAS_SIZE); 313e5c31af7Sopenharmony_ci const deUint8 texRedComponent = (deUint8)de::clamp(de::abs(texGradientPosX - 0.5f) * 255.0f + de::abs(texGradientPosY - 0.5f) * 255.0f, 0.0f, 255.0f); 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci const tcu::RGBA refColTexture = tcu::RGBA(texRedComponent, 255, 255, 255); 316e5c31af7Sopenharmony_ci const tcu::RGBA refColGradient = tcu::RGBA((int)((float)x / (float)TEST_CANVAS_SIZE * 255.0f), 255, 255, 255); 317e5c31af7Sopenharmony_ci const tcu::RGBA& refCol = (useTexture) ? (refColTexture) : (refColGradient); 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci const int colorThreshold = 10; 320e5c31af7Sopenharmony_ci const tcu::RGBA col = resultImage.getPixel(x, y); 321e5c31af7Sopenharmony_ci const tcu::IVec4 colorDiff = tcu::abs(col.toIVec() - refCol.toIVec()); 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_ci if (colorDiff.x() > formatThreshold.getRed() + colorThreshold || 324e5c31af7Sopenharmony_ci colorDiff.y() > formatThreshold.getGreen() + colorThreshold || 325e5c31af7Sopenharmony_ci colorDiff.z() > formatThreshold.getBlue() + colorThreshold) 326e5c31af7Sopenharmony_ci { 327e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, tcu::RGBA::red()); 328e5c31af7Sopenharmony_ci error = true; 329e5c31af7Sopenharmony_ci } 330e5c31af7Sopenharmony_ci else 331e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, tcu::RGBA::green()); 332e5c31af7Sopenharmony_ci } 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ci // report error 335e5c31af7Sopenharmony_ci if (error) 336e5c31af7Sopenharmony_ci { 337e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Test pattern has missing/invalid pixels" << tcu::TestLog::EndMessage; 338e5c31af7Sopenharmony_ci m_testCtx.getLog() 339e5c31af7Sopenharmony_ci << tcu::TestLog::ImageSet("Results", "Result verification") 340e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Result", "Result", resultImage) 341e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Error mask", "Error mask", errorMask) 342e5c31af7Sopenharmony_ci << tcu::TestLog::EndImageSet; 343e5c31af7Sopenharmony_ci } 344e5c31af7Sopenharmony_ci else 345e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No side-effects found." << tcu::TestLog::EndMessage; 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci return !error; 348e5c31af7Sopenharmony_ci} 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ciclass FramebufferRenderCase : public RenderCase 351e5c31af7Sopenharmony_ci{ 352e5c31af7Sopenharmony_cipublic: 353e5c31af7Sopenharmony_ci enum FrameBufferType 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci FBO_DEFAULT = 0, 356e5c31af7Sopenharmony_ci FBO_RGBA, 357e5c31af7Sopenharmony_ci FBO_RGBA4, 358e5c31af7Sopenharmony_ci FBO_RGB5_A1, 359e5c31af7Sopenharmony_ci FBO_RGB565, 360e5c31af7Sopenharmony_ci FBO_RGBA_FLOAT16, 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci FBO_LAST 363e5c31af7Sopenharmony_ci }; 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci FramebufferRenderCase (Context& context, const char* name, const char* desc, FrameBufferType fboType); 366e5c31af7Sopenharmony_ci virtual ~FramebufferRenderCase (void); 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci virtual void init (void); 369e5c31af7Sopenharmony_ci virtual void deinit (void); 370e5c31af7Sopenharmony_ci IterateResult iterate (void); 371e5c31af7Sopenharmony_ci 372e5c31af7Sopenharmony_ci virtual void testFBO (void) = DE_NULL; 373e5c31af7Sopenharmony_ci 374e5c31af7Sopenharmony_ciprotected: 375e5c31af7Sopenharmony_ci const FrameBufferType m_fboType; 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ciprivate: 378e5c31af7Sopenharmony_ci GLuint m_texID; 379e5c31af7Sopenharmony_ci GLuint m_fboID; 380e5c31af7Sopenharmony_ci}; 381e5c31af7Sopenharmony_ci 382e5c31af7Sopenharmony_ciFramebufferRenderCase::FramebufferRenderCase (Context& context, const char* name, const char* desc, FrameBufferType fboType) 383e5c31af7Sopenharmony_ci : RenderCase (context, name, desc, (fboType == FBO_DEFAULT) ? (RENDERTARGETTYPE_SCREEN) : (RENDERTARGETTYPE_FBO)) 384e5c31af7Sopenharmony_ci , m_fboType (fboType) 385e5c31af7Sopenharmony_ci , m_texID (0) 386e5c31af7Sopenharmony_ci , m_fboID (0) 387e5c31af7Sopenharmony_ci{ 388e5c31af7Sopenharmony_ci DE_ASSERT(m_fboType < FBO_LAST); 389e5c31af7Sopenharmony_ci} 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_ciFramebufferRenderCase::~FramebufferRenderCase (void) 392e5c31af7Sopenharmony_ci{ 393e5c31af7Sopenharmony_ci deinit(); 394e5c31af7Sopenharmony_ci} 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_civoid FramebufferRenderCase::init (void) 397e5c31af7Sopenharmony_ci{ 398e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci // check requirements 401e5c31af7Sopenharmony_ci if (m_fboType == FBO_RGBA_FLOAT16) 402e5c31af7Sopenharmony_ci { 403e5c31af7Sopenharmony_ci // half float texture is allowed (OES_texture_half_float) and it is color renderable (EXT_color_buffer_half_float) 404e5c31af7Sopenharmony_ci if (!m_context.getContextInfo().isExtensionSupported("GL_OES_texture_half_float") || 405e5c31af7Sopenharmony_ci !m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_half_float")) 406e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Color renderable half float texture required."); 407e5c31af7Sopenharmony_ci } 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ci // gen shader 410e5c31af7Sopenharmony_ci RenderCase::init(); 411e5c31af7Sopenharmony_ci 412e5c31af7Sopenharmony_ci // create render target 413e5c31af7Sopenharmony_ci if (m_fboType == FBO_DEFAULT) 414e5c31af7Sopenharmony_ci { 415e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Using default framebuffer." << tcu::TestLog::EndMessage; 416e5c31af7Sopenharmony_ci } 417e5c31af7Sopenharmony_ci else 418e5c31af7Sopenharmony_ci { 419e5c31af7Sopenharmony_ci GLuint internalFormat = 0; 420e5c31af7Sopenharmony_ci GLuint format = 0; 421e5c31af7Sopenharmony_ci GLuint type = 0; 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci#if !defined(GL_HALF_FLOAT_OES) 424e5c31af7Sopenharmony_ci# define GL_HALF_FLOAT_OES 0x8D61 425e5c31af7Sopenharmony_ci#endif 426e5c31af7Sopenharmony_ci 427e5c31af7Sopenharmony_ci switch (m_fboType) 428e5c31af7Sopenharmony_ci { 429e5c31af7Sopenharmony_ci case FBO_RGBA: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_BYTE; break; 430e5c31af7Sopenharmony_ci case FBO_RGBA4: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_SHORT_4_4_4_4; break; 431e5c31af7Sopenharmony_ci case FBO_RGB5_A1: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_SHORT_5_5_5_1; break; 432e5c31af7Sopenharmony_ci case FBO_RGB565: internalFormat = GL_RGB; format = GL_RGB; type = GL_UNSIGNED_SHORT_5_6_5; break; 433e5c31af7Sopenharmony_ci case FBO_RGBA_FLOAT16: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_HALF_FLOAT_OES; break; 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci default: 436e5c31af7Sopenharmony_ci DE_ASSERT(false); 437e5c31af7Sopenharmony_ci break; 438e5c31af7Sopenharmony_ci } 439e5c31af7Sopenharmony_ci 440e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 441e5c31af7Sopenharmony_ci << "Creating fbo. Texture internalFormat = " << glu::getTextureFormatStr(internalFormat) 442e5c31af7Sopenharmony_ci << ", format = " << glu::getTextureFormatStr(format) 443e5c31af7Sopenharmony_ci << ", type = " << glu::getTypeStr(type) 444e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_ci // gen texture 447e5c31af7Sopenharmony_ci gl.genTextures(1, &m_texID); 448e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, m_texID); 449e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, 0, format, type, DE_NULL); 450e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "texture init"); 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci // gen fbo 453e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_fboID); 454e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID); 455e5c31af7Sopenharmony_ci gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texID, 0); 456e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "fbo init"); 457e5c31af7Sopenharmony_ci 458e5c31af7Sopenharmony_ci if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 459e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("could not create fbo for testing."); 460e5c31af7Sopenharmony_ci } 461e5c31af7Sopenharmony_ci} 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_civoid FramebufferRenderCase::deinit (void) 464e5c31af7Sopenharmony_ci{ 465e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci if (m_texID) 468e5c31af7Sopenharmony_ci { 469e5c31af7Sopenharmony_ci gl.deleteTextures(1, &m_texID); 470e5c31af7Sopenharmony_ci m_texID = 0; 471e5c31af7Sopenharmony_ci } 472e5c31af7Sopenharmony_ci 473e5c31af7Sopenharmony_ci if (m_fboID) 474e5c31af7Sopenharmony_ci { 475e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &m_fboID); 476e5c31af7Sopenharmony_ci m_fboID = 0; 477e5c31af7Sopenharmony_ci } 478e5c31af7Sopenharmony_ci} 479e5c31af7Sopenharmony_ci 480e5c31af7Sopenharmony_ciFramebufferRenderCase::IterateResult FramebufferRenderCase::iterate (void) 481e5c31af7Sopenharmony_ci{ 482e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ci // bind fbo (or don't if we are using default) 485e5c31af7Sopenharmony_ci if (m_fboID) 486e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID); 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_ci // do something with special floats 489e5c31af7Sopenharmony_ci testFBO(); 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci return STOP; 492e5c31af7Sopenharmony_ci} 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 495e5c31af7Sopenharmony_ci * \brief Tests special floats as vertex attributes 496e5c31af7Sopenharmony_ci * 497e5c31af7Sopenharmony_ci * Tests that special floats transferred to the shader using vertex 498e5c31af7Sopenharmony_ci * attributes do not change the results of normal floating point 499e5c31af7Sopenharmony_ci * calculations. Special floats are put to 4-vector's x and y components and 500e5c31af7Sopenharmony_ci * value 1.0 is put to z and w. The resulting fragment's green channel 501e5c31af7Sopenharmony_ci * should be 1.0 everywhere. 502e5c31af7Sopenharmony_ci * 503e5c31af7Sopenharmony_ci * After the calculation test a test pattern is drawn to detect possible 504e5c31af7Sopenharmony_ci * floating point operation anomalies. 505e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 506e5c31af7Sopenharmony_ciclass VertexAttributeCase : public RenderCase 507e5c31af7Sopenharmony_ci{ 508e5c31af7Sopenharmony_cipublic: 509e5c31af7Sopenharmony_ci enum Storage 510e5c31af7Sopenharmony_ci { 511e5c31af7Sopenharmony_ci STORAGE_BUFFER = 0, 512e5c31af7Sopenharmony_ci STORAGE_CLIENT, 513e5c31af7Sopenharmony_ci 514e5c31af7Sopenharmony_ci STORAGE_LAST 515e5c31af7Sopenharmony_ci }; 516e5c31af7Sopenharmony_ci enum ShaderType 517e5c31af7Sopenharmony_ci { 518e5c31af7Sopenharmony_ci TYPE_VERTEX = 0, 519e5c31af7Sopenharmony_ci TYPE_FRAGMENT, 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_ci TYPE_LAST 522e5c31af7Sopenharmony_ci }; 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci VertexAttributeCase (Context& context, const char* name, const char* desc, Storage storage, ShaderType type); 525e5c31af7Sopenharmony_ci ~VertexAttributeCase (void); 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_ci void init (void); 528e5c31af7Sopenharmony_ci void deinit (void); 529e5c31af7Sopenharmony_ci IterateResult iterate (void); 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ciprivate: 532e5c31af7Sopenharmony_ci std::string genVertexSource (void) const; 533e5c31af7Sopenharmony_ci std::string genFragmentSource (void) const; 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci const Storage m_storage; 536e5c31af7Sopenharmony_ci const ShaderType m_type; 537e5c31af7Sopenharmony_ci GLuint m_positionVboID; 538e5c31af7Sopenharmony_ci GLuint m_attribVboID; 539e5c31af7Sopenharmony_ci GLuint m_elementVboID; 540e5c31af7Sopenharmony_ci}; 541e5c31af7Sopenharmony_ci 542e5c31af7Sopenharmony_ciVertexAttributeCase::VertexAttributeCase (Context& context, const char* name, const char* desc, Storage storage, ShaderType type) 543e5c31af7Sopenharmony_ci : RenderCase (context, name, desc) 544e5c31af7Sopenharmony_ci , m_storage (storage) 545e5c31af7Sopenharmony_ci , m_type (type) 546e5c31af7Sopenharmony_ci , m_positionVboID (0) 547e5c31af7Sopenharmony_ci , m_attribVboID (0) 548e5c31af7Sopenharmony_ci , m_elementVboID (0) 549e5c31af7Sopenharmony_ci{ 550e5c31af7Sopenharmony_ci DE_ASSERT(storage < STORAGE_LAST); 551e5c31af7Sopenharmony_ci DE_ASSERT(type < TYPE_LAST); 552e5c31af7Sopenharmony_ci} 553e5c31af7Sopenharmony_ci 554e5c31af7Sopenharmony_ciVertexAttributeCase::~VertexAttributeCase (void) 555e5c31af7Sopenharmony_ci{ 556e5c31af7Sopenharmony_ci deinit(); 557e5c31af7Sopenharmony_ci} 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_civoid VertexAttributeCase::init (void) 560e5c31af7Sopenharmony_ci{ 561e5c31af7Sopenharmony_ci RenderCase::init(); 562e5c31af7Sopenharmony_ci 563e5c31af7Sopenharmony_ci // init gl resources 564e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 565e5c31af7Sopenharmony_ci { 566e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_positionVboID); 569e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_attribVboID); 570e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_elementVboID); 571e5c31af7Sopenharmony_ci } 572e5c31af7Sopenharmony_ci} 573e5c31af7Sopenharmony_ci 574e5c31af7Sopenharmony_civoid VertexAttributeCase::deinit (void) 575e5c31af7Sopenharmony_ci{ 576e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_ci RenderCase::deinit(); 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci if (m_attribVboID) 581e5c31af7Sopenharmony_ci { 582e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_attribVboID); 583e5c31af7Sopenharmony_ci m_attribVboID = 0; 584e5c31af7Sopenharmony_ci } 585e5c31af7Sopenharmony_ci 586e5c31af7Sopenharmony_ci if (m_positionVboID) 587e5c31af7Sopenharmony_ci { 588e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_positionVboID); 589e5c31af7Sopenharmony_ci m_positionVboID = 0; 590e5c31af7Sopenharmony_ci } 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_ci if (m_elementVboID) 593e5c31af7Sopenharmony_ci { 594e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_elementVboID); 595e5c31af7Sopenharmony_ci m_elementVboID = 0; 596e5c31af7Sopenharmony_ci } 597e5c31af7Sopenharmony_ci} 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_ciVertexAttributeCase::IterateResult VertexAttributeCase::iterate (void) 600e5c31af7Sopenharmony_ci{ 601e5c31af7Sopenharmony_ci // Create a [s_specialFloats] X [s_specialFloats] grid of vertices with each vertex having 2 [s_specialFloats] values 602e5c31af7Sopenharmony_ci // and calculate some basic operations with the floating point values. If all goes well, nothing special should happen 603e5c31af7Sopenharmony_ci 604e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> gridVertices (DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats)); 605e5c31af7Sopenharmony_ci std::vector<tcu::UVec4> gridAttributes (DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats)); 606e5c31af7Sopenharmony_ci std::vector<deUint16> indices ((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6); 607e5c31af7Sopenharmony_ci tcu::Surface resultImage (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 608e5c31af7Sopenharmony_ci 609e5c31af7Sopenharmony_ci // vertices 610e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x) 611e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y) 612e5c31af7Sopenharmony_ci { 613e5c31af7Sopenharmony_ci const deUint32 one = 0x3F800000; 614e5c31af7Sopenharmony_ci const float posX = (float)x / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) - 1] to [-1, 1] 615e5c31af7Sopenharmony_ci const float posY = (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f; 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f); 618e5c31af7Sopenharmony_ci gridAttributes[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] = tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one); 619e5c31af7Sopenharmony_ci } 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci // tiles 622e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x) 623e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y) 624e5c31af7Sopenharmony_ci { 625e5c31af7Sopenharmony_ci const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6; 626e5c31af7Sopenharmony_ci 627e5c31af7Sopenharmony_ci indices[baseNdx + 0] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0)); 628e5c31af7Sopenharmony_ci indices[baseNdx + 1] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1)); 629e5c31af7Sopenharmony_ci indices[baseNdx + 2] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0)); 630e5c31af7Sopenharmony_ci 631e5c31af7Sopenharmony_ci indices[baseNdx + 3] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0)); 632e5c31af7Sopenharmony_ci indices[baseNdx + 4] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1)); 633e5c31af7Sopenharmony_ci indices[baseNdx + 5] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1)); 634e5c31af7Sopenharmony_ci } 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a grid with the shader. Setting a_attr for each vertex to (special, special, 1, 1)." << tcu::TestLog::EndMessage; 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci // Draw grid 639e5c31af7Sopenharmony_ci { 640e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 641e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(m_program->getProgram(), "a_pos"); 642e5c31af7Sopenharmony_ci const GLint attribLoc = gl.getAttribLocation(m_program->getProgram(), "a_attr"); 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 645e5c31af7Sopenharmony_ci { 646e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID); 647e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridVertices.size() * sizeof(tcu::Vec4)), &gridVertices[0], GL_STATIC_DRAW); 648e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate"); 649e5c31af7Sopenharmony_ci 650e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID); 651e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridAttributes.size() * sizeof(tcu::UVec4)), &gridAttributes[0], GL_STATIC_DRAW); 652e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate"); 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementVboID); 655e5c31af7Sopenharmony_ci gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size() * sizeof(deUint16)), &indices[0], GL_STATIC_DRAW); 656e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate"); 657e5c31af7Sopenharmony_ci } 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 660e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 661e5c31af7Sopenharmony_ci gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 662e5c31af7Sopenharmony_ci gl.useProgram(m_program->getProgram()); 663e5c31af7Sopenharmony_ci 664e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 665e5c31af7Sopenharmony_ci { 666e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID); 667e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID); 670e5c31af7Sopenharmony_ci gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 671e5c31af7Sopenharmony_ci 672e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 673e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(attribLoc); 674e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, DE_NULL); 675e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 676e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(attribLoc); 677e5c31af7Sopenharmony_ci 678e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, 0); 679e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 680e5c31af7Sopenharmony_ci } 681e5c31af7Sopenharmony_ci else if (m_storage == STORAGE_CLIENT) 682e5c31af7Sopenharmony_ci { 683e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]); 684e5c31af7Sopenharmony_ci gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridAttributes[0]); 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 687e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(attribLoc); 688e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]); 689e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 690e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(attribLoc); 691e5c31af7Sopenharmony_ci } 692e5c31af7Sopenharmony_ci else 693e5c31af7Sopenharmony_ci DE_ASSERT(false); 694e5c31af7Sopenharmony_ci 695e5c31af7Sopenharmony_ci gl.useProgram(0); 696e5c31af7Sopenharmony_ci gl.finish(); 697e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate"); 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess()); 700e5c31af7Sopenharmony_ci } 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci // verify everywhere was drawn (all pixels have Green = 255) 703e5c31af7Sopenharmony_ci if (!checkResultImage(resultImage)) 704e5c31af7Sopenharmony_ci { 705e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments"); 706e5c31af7Sopenharmony_ci return STOP; 707e5c31af7Sopenharmony_ci } 708e5c31af7Sopenharmony_ci 709e5c31af7Sopenharmony_ci // test drawing still works 710e5c31af7Sopenharmony_ci if (!drawTestPattern(false)) 711e5c31af7Sopenharmony_ci { 712e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed"); 713e5c31af7Sopenharmony_ci return STOP; 714e5c31af7Sopenharmony_ci } 715e5c31af7Sopenharmony_ci 716e5c31af7Sopenharmony_ci // all ok 717e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 718e5c31af7Sopenharmony_ci return STOP; 719e5c31af7Sopenharmony_ci} 720e5c31af7Sopenharmony_ci 721e5c31af7Sopenharmony_cistd::string VertexAttributeCase::genVertexSource (void) const 722e5c31af7Sopenharmony_ci{ 723e5c31af7Sopenharmony_ci if (m_type == TYPE_VERTEX) 724e5c31af7Sopenharmony_ci return 725e5c31af7Sopenharmony_ci "attribute highp vec4 a_pos;\n" 726e5c31af7Sopenharmony_ci "attribute highp vec4 a_attr;\n" 727e5c31af7Sopenharmony_ci "varying mediump vec4 v_out;\n" 728e5c31af7Sopenharmony_ci "void main ()\n" 729e5c31af7Sopenharmony_ci "{\n" 730e5c31af7Sopenharmony_ci " highp vec2 a1 = a_attr.xz + a_attr.yw; // add\n" 731e5c31af7Sopenharmony_ci " highp vec2 a2 = a_attr.xz - a_attr.yw; // sub\n" 732e5c31af7Sopenharmony_ci " highp vec2 a3 = a_attr.xz * a_attr.yw; // mul\n" 733e5c31af7Sopenharmony_ci " highp vec2 a4 = a_attr.xz / a_attr.yw; // div\n" 734e5c31af7Sopenharmony_ci " highp vec2 a5 = a_attr.xz + a_attr.yw * a_attr.xz; // fma\n" 735e5c31af7Sopenharmony_ci "\n" 736e5c31af7Sopenharmony_ci " highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n" 737e5c31af7Sopenharmony_ci " v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n" 738e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 739e5c31af7Sopenharmony_ci "}\n"; 740e5c31af7Sopenharmony_ci else 741e5c31af7Sopenharmony_ci return s_attrPassthroughVertexShaderSource; 742e5c31af7Sopenharmony_ci} 743e5c31af7Sopenharmony_ci 744e5c31af7Sopenharmony_cistd::string VertexAttributeCase::genFragmentSource (void) const 745e5c31af7Sopenharmony_ci{ 746e5c31af7Sopenharmony_ci if (m_type == TYPE_VERTEX) 747e5c31af7Sopenharmony_ci return s_colorPassthroughFragmentShaderSource; 748e5c31af7Sopenharmony_ci else 749e5c31af7Sopenharmony_ci return 750e5c31af7Sopenharmony_ci "varying mediump vec4 v_attr;\n" 751e5c31af7Sopenharmony_ci "void main ()\n" 752e5c31af7Sopenharmony_ci "{\n" 753e5c31af7Sopenharmony_ci " mediump vec2 a1 = v_attr.xz + v_attr.yw; // add\n" 754e5c31af7Sopenharmony_ci " mediump vec2 a2 = v_attr.xz - v_attr.yw; // sub\n" 755e5c31af7Sopenharmony_ci " mediump vec2 a3 = v_attr.xz * v_attr.yw; // mul\n" 756e5c31af7Sopenharmony_ci " mediump vec2 a4 = v_attr.xz / v_attr.yw; // div\n" 757e5c31af7Sopenharmony_ci " mediump vec2 a5 = v_attr.xz + v_attr.yw * v_attr.xz; // fma\n" 758e5c31af7Sopenharmony_ci "\n" 759e5c31af7Sopenharmony_ci " const mediump float epsilon = 0.1; // allow small differences. To results to be wrong they must be more wrong than that.\n" 760e5c31af7Sopenharmony_ci " mediump float green = 1.0 + epsilon - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n" 761e5c31af7Sopenharmony_ci " gl_FragColor = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n" 762e5c31af7Sopenharmony_ci "}\n"; 763e5c31af7Sopenharmony_ci} 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 766e5c31af7Sopenharmony_ci * \brief Tests special floats as uniforms 767e5c31af7Sopenharmony_ci * 768e5c31af7Sopenharmony_ci * Tests that special floats transferred to the shader as uniforms do 769e5c31af7Sopenharmony_ci * not change the results of normal floating point calculations. Special 770e5c31af7Sopenharmony_ci * floats are put to 4-vector's x and y components and value 1.0 is put to 771e5c31af7Sopenharmony_ci * z and w. The resulting fragment's green channel should be 1.0 772e5c31af7Sopenharmony_ci * everywhere. 773e5c31af7Sopenharmony_ci * 774e5c31af7Sopenharmony_ci * After the calculation test a test pattern is drawn to detect possible 775e5c31af7Sopenharmony_ci * floating point operation anomalies. 776e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 777e5c31af7Sopenharmony_ciclass UniformCase : public RenderCase 778e5c31af7Sopenharmony_ci{ 779e5c31af7Sopenharmony_cipublic: 780e5c31af7Sopenharmony_ci enum ShaderType 781e5c31af7Sopenharmony_ci { 782e5c31af7Sopenharmony_ci TYPE_VERTEX = 0, 783e5c31af7Sopenharmony_ci TYPE_FRAGMENT, 784e5c31af7Sopenharmony_ci }; 785e5c31af7Sopenharmony_ci 786e5c31af7Sopenharmony_ci UniformCase (Context& context, const char* name, const char* desc, ShaderType type); 787e5c31af7Sopenharmony_ci ~UniformCase (void); 788e5c31af7Sopenharmony_ci 789e5c31af7Sopenharmony_ci void init (void); 790e5c31af7Sopenharmony_ci void deinit (void); 791e5c31af7Sopenharmony_ci IterateResult iterate (void); 792e5c31af7Sopenharmony_ci 793e5c31af7Sopenharmony_ciprivate: 794e5c31af7Sopenharmony_ci std::string genVertexSource (void) const; 795e5c31af7Sopenharmony_ci std::string genFragmentSource (void) const; 796e5c31af7Sopenharmony_ci 797e5c31af7Sopenharmony_ci const ShaderType m_type; 798e5c31af7Sopenharmony_ci}; 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_ciUniformCase::UniformCase (Context& context, const char* name, const char* desc, ShaderType type) 801e5c31af7Sopenharmony_ci : RenderCase (context, name, desc) 802e5c31af7Sopenharmony_ci , m_type (type) 803e5c31af7Sopenharmony_ci{ 804e5c31af7Sopenharmony_ci} 805e5c31af7Sopenharmony_ci 806e5c31af7Sopenharmony_ciUniformCase::~UniformCase (void) 807e5c31af7Sopenharmony_ci{ 808e5c31af7Sopenharmony_ci deinit(); 809e5c31af7Sopenharmony_ci} 810e5c31af7Sopenharmony_ci 811e5c31af7Sopenharmony_civoid UniformCase::init (void) 812e5c31af7Sopenharmony_ci{ 813e5c31af7Sopenharmony_ci RenderCase::init(); 814e5c31af7Sopenharmony_ci} 815e5c31af7Sopenharmony_ci 816e5c31af7Sopenharmony_civoid UniformCase::deinit (void) 817e5c31af7Sopenharmony_ci{ 818e5c31af7Sopenharmony_ci RenderCase::deinit(); 819e5c31af7Sopenharmony_ci} 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ciUniformCase::IterateResult UniformCase::iterate (void) 822e5c31af7Sopenharmony_ci{ 823e5c31af7Sopenharmony_ci // Create a [s_specialFloats] X [s_specialFloats] grid of tile with each tile having 2 [s_specialFloats] values 824e5c31af7Sopenharmony_ci // and calculate some basic operations with the floating point values. If all goes well, nothing special should happen 825e5c31af7Sopenharmony_ci 826e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> gridVertices ((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1)); 827e5c31af7Sopenharmony_ci std::vector<deUint16> indices (DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6); 828e5c31af7Sopenharmony_ci tcu::Surface resultImage (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 829e5c31af7Sopenharmony_ci 830e5c31af7Sopenharmony_ci // vertices 831e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x) 832e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y) 833e5c31af7Sopenharmony_ci { 834e5c31af7Sopenharmony_ci const float posX = (float)x / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) ] to [-1, 1] 835e5c31af7Sopenharmony_ci const float posY = (float)y / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f; 836e5c31af7Sopenharmony_ci 837e5c31af7Sopenharmony_ci gridVertices[x * (DE_LENGTH_OF_ARRAY(s_specialFloats)+1) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f); 838e5c31af7Sopenharmony_ci } 839e5c31af7Sopenharmony_ci 840e5c31af7Sopenharmony_ci // tiles 841e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x) 842e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y) 843e5c31af7Sopenharmony_ci { 844e5c31af7Sopenharmony_ci const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats)) + y) * 6; 845e5c31af7Sopenharmony_ci 846e5c31af7Sopenharmony_ci indices[baseNdx + 0] = (deUint16)((x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0)); 847e5c31af7Sopenharmony_ci indices[baseNdx + 1] = (deUint16)((x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1)); 848e5c31af7Sopenharmony_ci indices[baseNdx + 2] = (deUint16)((x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0)); 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ci indices[baseNdx + 3] = (deUint16)((x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+0)); 851e5c31af7Sopenharmony_ci indices[baseNdx + 4] = (deUint16)((x+1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1)); 852e5c31af7Sopenharmony_ci indices[baseNdx + 5] = (deUint16)((x+0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y+1)); 853e5c31af7Sopenharmony_ci } 854e5c31af7Sopenharmony_ci 855e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a grid with the shader. Setting u_special for vertex each tile to (special, special, 1, 1)." << tcu::TestLog::EndMessage; 856e5c31af7Sopenharmony_ci 857e5c31af7Sopenharmony_ci // Draw grid 858e5c31af7Sopenharmony_ci { 859e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 860e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(m_program->getProgram(), "a_pos"); 861e5c31af7Sopenharmony_ci const GLint specialLoc = gl.getUniformLocation(m_program->getProgram(), "u_special"); 862e5c31af7Sopenharmony_ci 863e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 864e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 865e5c31af7Sopenharmony_ci gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 866e5c31af7Sopenharmony_ci gl.useProgram(m_program->getProgram()); 867e5c31af7Sopenharmony_ci 868e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]); 869e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 870e5c31af7Sopenharmony_ci 871e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x) 872e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y) 873e5c31af7Sopenharmony_ci { 874e5c31af7Sopenharmony_ci const deUint32 one = 0x3F800000; 875e5c31af7Sopenharmony_ci const tcu::UVec4 uniformValue = tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one); 876e5c31af7Sopenharmony_ci const int indexIndex = (x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y) * 6; 877e5c31af7Sopenharmony_ci 878e5c31af7Sopenharmony_ci gl.uniform4fv(specialLoc, 1, (const float*)uniformValue.getPtr()); 879e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]); 880e5c31af7Sopenharmony_ci } 881e5c31af7Sopenharmony_ci 882e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_ci gl.useProgram(0); 885e5c31af7Sopenharmony_ci gl.finish(); 886e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UniformCase::iterate"); 887e5c31af7Sopenharmony_ci 888e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess()); 889e5c31af7Sopenharmony_ci } 890e5c31af7Sopenharmony_ci 891e5c31af7Sopenharmony_ci // verify everywhere was drawn (all pixels have Green = 255) 892e5c31af7Sopenharmony_ci if (!checkResultImage(resultImage)) 893e5c31af7Sopenharmony_ci { 894e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments"); 895e5c31af7Sopenharmony_ci return STOP; 896e5c31af7Sopenharmony_ci } 897e5c31af7Sopenharmony_ci 898e5c31af7Sopenharmony_ci // test drawing still works 899e5c31af7Sopenharmony_ci if (!drawTestPattern(false)) 900e5c31af7Sopenharmony_ci { 901e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed"); 902e5c31af7Sopenharmony_ci return STOP; 903e5c31af7Sopenharmony_ci } 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ci // all ok 906e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 907e5c31af7Sopenharmony_ci return STOP; 908e5c31af7Sopenharmony_ci} 909e5c31af7Sopenharmony_ci 910e5c31af7Sopenharmony_cistd::string UniformCase::genVertexSource (void) const 911e5c31af7Sopenharmony_ci{ 912e5c31af7Sopenharmony_ci if (m_type == TYPE_VERTEX) 913e5c31af7Sopenharmony_ci return 914e5c31af7Sopenharmony_ci "attribute highp vec4 a_pos;\n" 915e5c31af7Sopenharmony_ci "uniform highp vec4 u_special;\n" 916e5c31af7Sopenharmony_ci "varying mediump vec4 v_out;\n" 917e5c31af7Sopenharmony_ci "void main ()\n" 918e5c31af7Sopenharmony_ci "{\n" 919e5c31af7Sopenharmony_ci " highp vec2 a1 = u_special.xz + u_special.yw; // add\n" 920e5c31af7Sopenharmony_ci " highp vec2 a2 = u_special.xz - u_special.yw; // sub\n" 921e5c31af7Sopenharmony_ci " highp vec2 a3 = u_special.xz * u_special.yw; // mul\n" 922e5c31af7Sopenharmony_ci " highp vec2 a4 = u_special.xz / u_special.yw; // div\n" 923e5c31af7Sopenharmony_ci " highp vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n" 924e5c31af7Sopenharmony_ci "\n" 925e5c31af7Sopenharmony_ci " highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n" 926e5c31af7Sopenharmony_ci " v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n" 927e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 928e5c31af7Sopenharmony_ci "}\n"; 929e5c31af7Sopenharmony_ci else 930e5c31af7Sopenharmony_ci return 931e5c31af7Sopenharmony_ci "attribute highp vec4 a_pos;\n" 932e5c31af7Sopenharmony_ci "void main ()\n" 933e5c31af7Sopenharmony_ci "{\n" 934e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 935e5c31af7Sopenharmony_ci "}\n"; 936e5c31af7Sopenharmony_ci} 937e5c31af7Sopenharmony_ci 938e5c31af7Sopenharmony_cistd::string UniformCase::genFragmentSource (void) const 939e5c31af7Sopenharmony_ci{ 940e5c31af7Sopenharmony_ci if (m_type == TYPE_VERTEX) 941e5c31af7Sopenharmony_ci return s_colorPassthroughFragmentShaderSource; 942e5c31af7Sopenharmony_ci else 943e5c31af7Sopenharmony_ci return 944e5c31af7Sopenharmony_ci "uniform mediump vec4 u_special;\n" 945e5c31af7Sopenharmony_ci "void main ()\n" 946e5c31af7Sopenharmony_ci "{\n" 947e5c31af7Sopenharmony_ci " mediump vec2 a1 = u_special.xz + u_special.yw; // add\n" 948e5c31af7Sopenharmony_ci " mediump vec2 a2 = u_special.xz - u_special.yw; // sub\n" 949e5c31af7Sopenharmony_ci " mediump vec2 a3 = u_special.xz * u_special.yw; // mul\n" 950e5c31af7Sopenharmony_ci " mediump vec2 a4 = u_special.xz / u_special.yw; // div\n" 951e5c31af7Sopenharmony_ci " mediump vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n" 952e5c31af7Sopenharmony_ci " mediump vec2 a6 = mod(u_special.xz, u_special.yw);\n" 953e5c31af7Sopenharmony_ci " mediump vec2 a7 = mix(u_special.xz, u_special.yw, a6);\n" 954e5c31af7Sopenharmony_ci "\n" 955e5c31af7Sopenharmony_ci " mediump float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y + a6.y + a7.y) - 7.0);\n" 956e5c31af7Sopenharmony_ci " gl_FragColor = vec4(a1.x*a3.x, green, a5.x*a4.x + a2.x*a7.x, 1.0);\n" 957e5c31af7Sopenharmony_ci "}\n"; 958e5c31af7Sopenharmony_ci} 959e5c31af7Sopenharmony_ci 960e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 961e5c31af7Sopenharmony_ci * \brief Tests special floats as texture samping arguments 962e5c31af7Sopenharmony_ci * 963e5c31af7Sopenharmony_ci * Tests that special floats given as texture coordinates or LOD levels 964e5c31af7Sopenharmony_ci * to sampling functions do not return invalid values (values not in the 965e5c31af7Sopenharmony_ci * texture). Every texel's green component is 1.0. 966e5c31af7Sopenharmony_ci * 967e5c31af7Sopenharmony_ci * After the calculation test a test pattern is drawn to detect possible 968e5c31af7Sopenharmony_ci * texture sampling anomalies. 969e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 970e5c31af7Sopenharmony_ciclass TextureSamplerCase : public RenderCase 971e5c31af7Sopenharmony_ci{ 972e5c31af7Sopenharmony_cipublic: 973e5c31af7Sopenharmony_ci enum ShaderType 974e5c31af7Sopenharmony_ci { 975e5c31af7Sopenharmony_ci TYPE_VERTEX = 0, 976e5c31af7Sopenharmony_ci TYPE_FRAGMENT, 977e5c31af7Sopenharmony_ci 978e5c31af7Sopenharmony_ci TYPE_LAST 979e5c31af7Sopenharmony_ci }; 980e5c31af7Sopenharmony_ci enum TestType 981e5c31af7Sopenharmony_ci { 982e5c31af7Sopenharmony_ci TEST_TEX_COORD = 0, 983e5c31af7Sopenharmony_ci TEST_LOD, 984e5c31af7Sopenharmony_ci TEST_TEX_COORD_CUBE, 985e5c31af7Sopenharmony_ci 986e5c31af7Sopenharmony_ci TEST_LAST 987e5c31af7Sopenharmony_ci }; 988e5c31af7Sopenharmony_ci 989e5c31af7Sopenharmony_ci TextureSamplerCase (Context& context, const char* name, const char* desc, ShaderType type, TestType testType); 990e5c31af7Sopenharmony_ci ~TextureSamplerCase (void); 991e5c31af7Sopenharmony_ci 992e5c31af7Sopenharmony_ci void init (void); 993e5c31af7Sopenharmony_ci void deinit (void); 994e5c31af7Sopenharmony_ci IterateResult iterate (void); 995e5c31af7Sopenharmony_ci 996e5c31af7Sopenharmony_ciprivate: 997e5c31af7Sopenharmony_ci std::string genVertexSource (void) const; 998e5c31af7Sopenharmony_ci std::string genFragmentSource (void) const; 999e5c31af7Sopenharmony_ci 1000e5c31af7Sopenharmony_ci const ShaderType m_type; 1001e5c31af7Sopenharmony_ci const TestType m_testType; 1002e5c31af7Sopenharmony_ci GLuint m_textureID; 1003e5c31af7Sopenharmony_ci}; 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_ciTextureSamplerCase::TextureSamplerCase (Context& context, const char* name, const char* desc, ShaderType type, TestType testType) 1006e5c31af7Sopenharmony_ci : RenderCase (context, name, desc) 1007e5c31af7Sopenharmony_ci , m_type (type) 1008e5c31af7Sopenharmony_ci , m_testType (testType) 1009e5c31af7Sopenharmony_ci , m_textureID (0) 1010e5c31af7Sopenharmony_ci{ 1011e5c31af7Sopenharmony_ci DE_ASSERT(type < TYPE_LAST); 1012e5c31af7Sopenharmony_ci DE_ASSERT(testType < TEST_LAST); 1013e5c31af7Sopenharmony_ci} 1014e5c31af7Sopenharmony_ci 1015e5c31af7Sopenharmony_ciTextureSamplerCase::~TextureSamplerCase (void) 1016e5c31af7Sopenharmony_ci{ 1017e5c31af7Sopenharmony_ci deinit(); 1018e5c31af7Sopenharmony_ci} 1019e5c31af7Sopenharmony_ci 1020e5c31af7Sopenharmony_civoid TextureSamplerCase::init (void) 1021e5c31af7Sopenharmony_ci{ 1022e5c31af7Sopenharmony_ci // requirements 1023e5c31af7Sopenharmony_ci { 1024e5c31af7Sopenharmony_ci GLint maxTextureSize = 0; 1025e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 1026e5c31af7Sopenharmony_ci if (maxTextureSize < TEST_TEXTURE_SIZE) 1027e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") + de::toString(TEST_TEXTURE_SIZE)); 1028e5c31af7Sopenharmony_ci } 1029e5c31af7Sopenharmony_ci 1030e5c31af7Sopenharmony_ci // vertex shader supports textures? 1031e5c31af7Sopenharmony_ci if (m_type == TYPE_VERTEX) 1032e5c31af7Sopenharmony_ci { 1033e5c31af7Sopenharmony_ci GLint maxVertexTexUnits = 0; 1034e5c31af7Sopenharmony_ci m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTexUnits); 1035e5c31af7Sopenharmony_ci if (maxVertexTexUnits < 1) 1036e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS must be at least 1"); 1037e5c31af7Sopenharmony_ci } 1038e5c31af7Sopenharmony_ci 1039e5c31af7Sopenharmony_ci RenderCase::init(); 1040e5c31af7Sopenharmony_ci 1041e5c31af7Sopenharmony_ci // gen texture 1042e5c31af7Sopenharmony_ci { 1043e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1044e5c31af7Sopenharmony_ci std::vector<deUint8> texData (TEST_TEXTURE_SIZE*TEST_TEXTURE_SIZE*4); 1045e5c31af7Sopenharmony_ci de::Random rnd (12345); 1046e5c31af7Sopenharmony_ci 1047e5c31af7Sopenharmony_ci gl.genTextures(1, &m_textureID); 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci for (int x = 0; x < TEST_TEXTURE_SIZE; ++x) 1050e5c31af7Sopenharmony_ci for (int y = 0; y < TEST_TEXTURE_SIZE; ++y) 1051e5c31af7Sopenharmony_ci { 1052e5c31af7Sopenharmony_ci // RGBA8, green and alpha channel are always 255 for verification 1053e5c31af7Sopenharmony_ci texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 0] = rnd.getUint32() & 0xFF; 1054e5c31af7Sopenharmony_ci texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 1] = 0xFF; 1055e5c31af7Sopenharmony_ci texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 2] = rnd.getUint32() & 0xFF; 1056e5c31af7Sopenharmony_ci texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 3] = 0xFF; 1057e5c31af7Sopenharmony_ci } 1058e5c31af7Sopenharmony_ci 1059e5c31af7Sopenharmony_ci if (m_testType == TEST_TEX_COORD) 1060e5c31af7Sopenharmony_ci { 1061e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Creating a 2D texture with a test pattern." << tcu::TestLog::EndMessage; 1062e5c31af7Sopenharmony_ci 1063e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, m_textureID); 1064e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]); 1065e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1066e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1067e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init"); 1068e5c31af7Sopenharmony_ci } 1069e5c31af7Sopenharmony_ci else if (m_testType == TEST_LOD) 1070e5c31af7Sopenharmony_ci { 1071e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Creating a mipmapped 2D texture with a test pattern." << tcu::TestLog::EndMessage; 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, m_textureID); 1074e5c31af7Sopenharmony_ci 1075e5c31af7Sopenharmony_ci for (int level = 0; (TEST_TEXTURE_SIZE >> level); ++level) 1076e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_2D, level, GL_RGBA, TEST_TEXTURE_SIZE >> level, TEST_TEXTURE_SIZE >> level, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]); 1077e5c31af7Sopenharmony_ci 1078e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1079e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 1080e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init"); 1081e5c31af7Sopenharmony_ci } 1082e5c31af7Sopenharmony_ci else if (m_testType == TEST_TEX_COORD_CUBE) 1083e5c31af7Sopenharmony_ci { 1084e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TEST_TEXTURE_CUBE_SIZE <= TEST_TEXTURE_SIZE); 1085e5c31af7Sopenharmony_ci 1086e5c31af7Sopenharmony_ci static const GLenum faces[] = 1087e5c31af7Sopenharmony_ci { 1088e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1089e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1090e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1091e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1092e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1093e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1094e5c31af7Sopenharmony_ci }; 1095e5c31af7Sopenharmony_ci 1096e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Creating a cube map with a test pattern." << tcu::TestLog::EndMessage; 1097e5c31af7Sopenharmony_ci 1098e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID); 1099e5c31af7Sopenharmony_ci 1100e5c31af7Sopenharmony_ci for (int faceNdx = 0; faceNdx < DE_LENGTH_OF_ARRAY(faces); ++faceNdx) 1101e5c31af7Sopenharmony_ci gl.texImage2D(faces[faceNdx], 0, GL_RGBA, TEST_TEXTURE_CUBE_SIZE, TEST_TEXTURE_CUBE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]); 1102e5c31af7Sopenharmony_ci 1103e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1104e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1105e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init"); 1106e5c31af7Sopenharmony_ci } 1107e5c31af7Sopenharmony_ci else 1108e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1109e5c31af7Sopenharmony_ci } 1110e5c31af7Sopenharmony_ci} 1111e5c31af7Sopenharmony_ci 1112e5c31af7Sopenharmony_civoid TextureSamplerCase::deinit (void) 1113e5c31af7Sopenharmony_ci{ 1114e5c31af7Sopenharmony_ci RenderCase::deinit(); 1115e5c31af7Sopenharmony_ci 1116e5c31af7Sopenharmony_ci if (m_textureID) 1117e5c31af7Sopenharmony_ci { 1118e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1119e5c31af7Sopenharmony_ci 1120e5c31af7Sopenharmony_ci gl.deleteTextures(1, &m_textureID); 1121e5c31af7Sopenharmony_ci m_textureID = 0; 1122e5c31af7Sopenharmony_ci } 1123e5c31af7Sopenharmony_ci} 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_ciTextureSamplerCase::IterateResult TextureSamplerCase::iterate (void) 1126e5c31af7Sopenharmony_ci{ 1127e5c31af7Sopenharmony_ci // Draw a grid and texture it with a texture and sample it using special special values. The result samples should all have the green channel at 255 as per the test image. 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> gridVertices (DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats)); 1130e5c31af7Sopenharmony_ci std::vector<tcu::UVec2> gridTexCoords (DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats)); 1131e5c31af7Sopenharmony_ci std::vector<deUint16> indices ((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6); 1132e5c31af7Sopenharmony_ci tcu::Surface resultImage (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_ci // vertices 1135e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x) 1136e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y) 1137e5c31af7Sopenharmony_ci { 1138e5c31af7Sopenharmony_ci const float posX = (float)x / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) - 1] to [-1, 1] 1139e5c31af7Sopenharmony_ci const float posY = (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f; 1140e5c31af7Sopenharmony_ci 1141e5c31af7Sopenharmony_ci gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f); 1142e5c31af7Sopenharmony_ci gridTexCoords[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] = tcu::UVec2(s_specialFloats[x], s_specialFloats[y]); 1143e5c31af7Sopenharmony_ci } 1144e5c31af7Sopenharmony_ci 1145e5c31af7Sopenharmony_ci // tiles 1146e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x) 1147e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y) 1148e5c31af7Sopenharmony_ci { 1149e5c31af7Sopenharmony_ci const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6; 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_ci indices[baseNdx + 0] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0)); 1152e5c31af7Sopenharmony_ci indices[baseNdx + 1] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1)); 1153e5c31af7Sopenharmony_ci indices[baseNdx + 2] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0)); 1154e5c31af7Sopenharmony_ci 1155e5c31af7Sopenharmony_ci indices[baseNdx + 3] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+0)); 1156e5c31af7Sopenharmony_ci indices[baseNdx + 4] = (deUint16)((x+1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1)); 1157e5c31af7Sopenharmony_ci indices[baseNdx + 5] = (deUint16)((x+0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y+1)); 1158e5c31af7Sopenharmony_ci } 1159e5c31af7Sopenharmony_ci 1160e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a textured grid with the shader. Sampling from the texture using special floating point values." << tcu::TestLog::EndMessage; 1161e5c31af7Sopenharmony_ci 1162e5c31af7Sopenharmony_ci // Draw grid 1163e5c31af7Sopenharmony_ci { 1164e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1165e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(m_program->getProgram(), "a_pos"); 1166e5c31af7Sopenharmony_ci const GLint texCoordLoc = gl.getAttribLocation(m_program->getProgram(), "a_attr"); 1167e5c31af7Sopenharmony_ci const GLint samplerLoc = gl.getUniformLocation(m_program->getProgram(), "u_sampler"); 1168e5c31af7Sopenharmony_ci 1169e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1170e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1171e5c31af7Sopenharmony_ci gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1172e5c31af7Sopenharmony_ci gl.useProgram(m_program->getProgram()); 1173e5c31af7Sopenharmony_ci 1174e5c31af7Sopenharmony_ci gl.uniform1i(samplerLoc, 0); 1175e5c31af7Sopenharmony_ci if (m_testType != TEST_TEX_COORD_CUBE) 1176e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, m_textureID); 1177e5c31af7Sopenharmony_ci else 1178e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID); 1179e5c31af7Sopenharmony_ci 1180e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]); 1181e5c31af7Sopenharmony_ci gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, &gridTexCoords[0]); 1182e5c31af7Sopenharmony_ci 1183e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 1184e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(texCoordLoc); 1185e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]); 1186e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 1187e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(texCoordLoc); 1188e5c31af7Sopenharmony_ci 1189e5c31af7Sopenharmony_ci gl.useProgram(0); 1190e5c31af7Sopenharmony_ci gl.finish(); 1191e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::iterate"); 1192e5c31af7Sopenharmony_ci 1193e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess()); 1194e5c31af7Sopenharmony_ci } 1195e5c31af7Sopenharmony_ci 1196e5c31af7Sopenharmony_ci // verify everywhere was drawn and samples were from the texture (all pixels have Green = 255) 1197e5c31af7Sopenharmony_ci if (!checkResultImage(resultImage)) 1198e5c31af7Sopenharmony_ci { 1199e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments"); 1200e5c31af7Sopenharmony_ci return STOP; 1201e5c31af7Sopenharmony_ci } 1202e5c31af7Sopenharmony_ci 1203e5c31af7Sopenharmony_ci // test drawing and textures still works 1204e5c31af7Sopenharmony_ci if (!drawTestPattern(true)) 1205e5c31af7Sopenharmony_ci { 1206e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed"); 1207e5c31af7Sopenharmony_ci return STOP; 1208e5c31af7Sopenharmony_ci } 1209e5c31af7Sopenharmony_ci 1210e5c31af7Sopenharmony_ci // all ok 1211e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1212e5c31af7Sopenharmony_ci return STOP; 1213e5c31af7Sopenharmony_ci} 1214e5c31af7Sopenharmony_ci 1215e5c31af7Sopenharmony_cistd::string TextureSamplerCase::genVertexSource (void) const 1216e5c31af7Sopenharmony_ci{ 1217e5c31af7Sopenharmony_ci // vertex shader is passthrough, fragment does the calculations 1218e5c31af7Sopenharmony_ci if (m_type == TYPE_FRAGMENT) 1219e5c31af7Sopenharmony_ci return s_attrPassthroughVertexShaderSource; 1220e5c31af7Sopenharmony_ci 1221e5c31af7Sopenharmony_ci // vertex shader does the calculations 1222e5c31af7Sopenharmony_ci std::ostringstream buf; 1223e5c31af7Sopenharmony_ci buf << "attribute highp vec4 a_pos;\n" 1224e5c31af7Sopenharmony_ci "attribute highp vec2 a_attr;\n"; 1225e5c31af7Sopenharmony_ci 1226e5c31af7Sopenharmony_ci if (m_testType != TEST_TEX_COORD_CUBE) 1227e5c31af7Sopenharmony_ci buf << "uniform highp sampler2D u_sampler;\n"; 1228e5c31af7Sopenharmony_ci else 1229e5c31af7Sopenharmony_ci buf << "uniform highp samplerCube u_sampler;\n"; 1230e5c31af7Sopenharmony_ci 1231e5c31af7Sopenharmony_ci buf << "varying mediump vec4 v_out;\n" 1232e5c31af7Sopenharmony_ci "void main ()\n" 1233e5c31af7Sopenharmony_ci "{\n"; 1234e5c31af7Sopenharmony_ci 1235e5c31af7Sopenharmony_ci if (m_testType == TEST_TEX_COORD) 1236e5c31af7Sopenharmony_ci buf << " v_out = texture2DLod(u_sampler, a_attr, 0.0);\n"; 1237e5c31af7Sopenharmony_ci else if (m_testType == TEST_LOD) 1238e5c31af7Sopenharmony_ci buf << " v_out = texture2DLod(u_sampler, a_attr, a_attr.x);\n"; 1239e5c31af7Sopenharmony_ci else if (m_testType == TEST_TEX_COORD_CUBE) 1240e5c31af7Sopenharmony_ci buf << " v_out = textureCubeLod(u_sampler, vec3(a_attr, a_attr.x+a_attr.y), 0.0);\n"; 1241e5c31af7Sopenharmony_ci else 1242e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1243e5c31af7Sopenharmony_ci 1244e5c31af7Sopenharmony_ci buf << "\n" 1245e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 1246e5c31af7Sopenharmony_ci "}\n"; 1247e5c31af7Sopenharmony_ci 1248e5c31af7Sopenharmony_ci return buf.str(); 1249e5c31af7Sopenharmony_ci} 1250e5c31af7Sopenharmony_ci 1251e5c31af7Sopenharmony_cistd::string TextureSamplerCase::genFragmentSource (void) const 1252e5c31af7Sopenharmony_ci{ 1253e5c31af7Sopenharmony_ci // fragment shader is passthrough 1254e5c31af7Sopenharmony_ci if (m_type == TYPE_VERTEX) 1255e5c31af7Sopenharmony_ci return s_colorPassthroughFragmentShaderSource; 1256e5c31af7Sopenharmony_ci 1257e5c31af7Sopenharmony_ci // fragment shader does the calculations 1258e5c31af7Sopenharmony_ci std::ostringstream buf; 1259e5c31af7Sopenharmony_ci if (m_testType != TEST_TEX_COORD_CUBE) 1260e5c31af7Sopenharmony_ci buf << "uniform mediump sampler2D u_sampler;\n"; 1261e5c31af7Sopenharmony_ci else 1262e5c31af7Sopenharmony_ci buf << "uniform mediump samplerCube u_sampler;\n"; 1263e5c31af7Sopenharmony_ci 1264e5c31af7Sopenharmony_ci buf << "varying mediump vec4 v_attr;\n" 1265e5c31af7Sopenharmony_ci "void main ()\n" 1266e5c31af7Sopenharmony_ci "{\n"; 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci if (m_testType == TEST_TEX_COORD) 1269e5c31af7Sopenharmony_ci buf << " gl_FragColor = texture2D(u_sampler, v_attr.xy);\n"; 1270e5c31af7Sopenharmony_ci else if (m_testType == TEST_LOD) 1271e5c31af7Sopenharmony_ci buf << " gl_FragColor = texture2D(u_sampler, v_attr.xy, v_attr.x);\n"; 1272e5c31af7Sopenharmony_ci else if (m_testType == TEST_TEX_COORD_CUBE) 1273e5c31af7Sopenharmony_ci buf << " gl_FragColor = textureCube(u_sampler, vec3(v_attr.xy, v_attr.x + v_attr.y));\n"; 1274e5c31af7Sopenharmony_ci else 1275e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1276e5c31af7Sopenharmony_ci 1277e5c31af7Sopenharmony_ci buf << "}\n"; 1278e5c31af7Sopenharmony_ci 1279e5c31af7Sopenharmony_ci return buf.str(); 1280e5c31af7Sopenharmony_ci} 1281e5c31af7Sopenharmony_ci 1282e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1283e5c31af7Sopenharmony_ci * \brief Tests special floats as fragment shader outputs 1284e5c31af7Sopenharmony_ci * 1285e5c31af7Sopenharmony_ci * Tests that outputting special floats from a fragment shader does not change 1286e5c31af7Sopenharmony_ci * the normal floating point values of outputted from a fragment shader. Special 1287e5c31af7Sopenharmony_ci * floats are outputted in the green component, normal floating point values 1288e5c31af7Sopenharmony_ci * in the red and blue component. Potential changes are tested by rendering 1289e5c31af7Sopenharmony_ci * test pattern two times with different floating point values. The resulting 1290e5c31af7Sopenharmony_ci * images' red and blue channels should be equal. 1291e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1292e5c31af7Sopenharmony_ciclass OutputCase : public FramebufferRenderCase 1293e5c31af7Sopenharmony_ci{ 1294e5c31af7Sopenharmony_cipublic: 1295e5c31af7Sopenharmony_ci OutputCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type); 1296e5c31af7Sopenharmony_ci ~OutputCase (void); 1297e5c31af7Sopenharmony_ci 1298e5c31af7Sopenharmony_ci void testFBO (void); 1299e5c31af7Sopenharmony_ci 1300e5c31af7Sopenharmony_ciprivate: 1301e5c31af7Sopenharmony_ci std::string genVertexSource (void) const; 1302e5c31af7Sopenharmony_ci std::string genFragmentSource (void) const; 1303e5c31af7Sopenharmony_ci}; 1304e5c31af7Sopenharmony_ci 1305e5c31af7Sopenharmony_ciOutputCase::OutputCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type) 1306e5c31af7Sopenharmony_ci : FramebufferRenderCase (context, name, desc, type) 1307e5c31af7Sopenharmony_ci{ 1308e5c31af7Sopenharmony_ci} 1309e5c31af7Sopenharmony_ci 1310e5c31af7Sopenharmony_ciOutputCase::~OutputCase (void) 1311e5c31af7Sopenharmony_ci{ 1312e5c31af7Sopenharmony_ci deinit(); 1313e5c31af7Sopenharmony_ci} 1314e5c31af7Sopenharmony_ci 1315e5c31af7Sopenharmony_civoid OutputCase::testFBO (void) 1316e5c31af7Sopenharmony_ci{ 1317e5c31af7Sopenharmony_ci // Create a 1 X [s_specialFloats] grid of tiles (stripes). 1318e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> gridVertices ((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) * 2); 1319e5c31af7Sopenharmony_ci std::vector<deUint16> indices (DE_LENGTH_OF_ARRAY(s_specialFloats) * 6); 1320e5c31af7Sopenharmony_ci tcu::TextureFormat textureFormat (tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16) ? (tcu::TextureFormat::FLOAT) : (tcu::TextureFormat::UNORM_INT8)); 1321e5c31af7Sopenharmony_ci tcu::TextureLevel specialImage (textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1322e5c31af7Sopenharmony_ci tcu::TextureLevel normalImage (textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1323e5c31af7Sopenharmony_ci 1324e5c31af7Sopenharmony_ci // vertices 1325e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y) 1326e5c31af7Sopenharmony_ci { 1327e5c31af7Sopenharmony_ci const float posY = (float)y / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f; // map from [0, len(s_specialFloats) ] to [-1, 1] 1328e5c31af7Sopenharmony_ci 1329e5c31af7Sopenharmony_ci gridVertices[y * 2 + 0] = tcu::Vec4(-1.0, posY, 0.0f, 1.0f); 1330e5c31af7Sopenharmony_ci gridVertices[y * 2 + 1] = tcu::Vec4( 1.0, posY, 0.0f, 1.0f); 1331e5c31af7Sopenharmony_ci } 1332e5c31af7Sopenharmony_ci 1333e5c31af7Sopenharmony_ci // tiles 1334e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y) 1335e5c31af7Sopenharmony_ci { 1336e5c31af7Sopenharmony_ci const int baseNdx = y * 6; 1337e5c31af7Sopenharmony_ci 1338e5c31af7Sopenharmony_ci indices[baseNdx + 0] = (deUint16)((y + 0) * 2); 1339e5c31af7Sopenharmony_ci indices[baseNdx + 1] = (deUint16)((y + 1) * 2); 1340e5c31af7Sopenharmony_ci indices[baseNdx + 2] = (deUint16)((y + 1) * 2 + 1); 1341e5c31af7Sopenharmony_ci 1342e5c31af7Sopenharmony_ci indices[baseNdx + 3] = (deUint16)((y + 0) * 2); 1343e5c31af7Sopenharmony_ci indices[baseNdx + 4] = (deUint16)((y + 1) * 2 + 1); 1344e5c31af7Sopenharmony_ci indices[baseNdx + 5] = (deUint16)((y + 0) * 2 + 1); 1345e5c31af7Sopenharmony_ci } 1346e5c31af7Sopenharmony_ci 1347e5c31af7Sopenharmony_ci // Draw grids 1348e5c31af7Sopenharmony_ci { 1349e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1350e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(m_program->getProgram(), "a_pos"); 1351e5c31af7Sopenharmony_ci const GLint specialLoc = gl.getUniformLocation(m_program->getProgram(), "u_special"); 1352e5c31af7Sopenharmony_ci 1353e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1354e5c31af7Sopenharmony_ci gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1355e5c31af7Sopenharmony_ci gl.useProgram(m_program->getProgram()); 1356e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw"); 1357e5c31af7Sopenharmony_ci 1358e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]); 1359e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 1360e5c31af7Sopenharmony_ci 1361e5c31af7Sopenharmony_ci // draw 2 passes. Special and normal. 1362e5c31af7Sopenharmony_ci for (int passNdx = 0; passNdx < 2; ++passNdx) 1363e5c31af7Sopenharmony_ci { 1364e5c31af7Sopenharmony_ci const bool specialPass = (passNdx == 0); 1365e5c31af7Sopenharmony_ci 1366e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Pass " << passNdx << ": Drawing stripes with the shader. Setting u_special for each stripe to (" << ((specialPass) ? ("special") : ("1.0")) << ")." << tcu::TestLog::EndMessage; 1367e5c31af7Sopenharmony_ci 1368e5c31af7Sopenharmony_ci // draw stripes 1369e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1370e5c31af7Sopenharmony_ci for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y) 1371e5c31af7Sopenharmony_ci { 1372e5c31af7Sopenharmony_ci const deUint32 one = 0x3F800000; 1373e5c31af7Sopenharmony_ci const deUint32 special = s_specialFloats[y]; 1374e5c31af7Sopenharmony_ci const deUint32 uniformValue = (specialPass) ? (special) : (one); 1375e5c31af7Sopenharmony_ci const int indexIndex = y * 6; 1376e5c31af7Sopenharmony_ci 1377e5c31af7Sopenharmony_ci gl.uniform1fv(specialLoc, 1, (const float*)&uniformValue); 1378e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]); 1379e5c31af7Sopenharmony_ci } 1380e5c31af7Sopenharmony_ci 1381e5c31af7Sopenharmony_ci gl.finish(); 1382e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, ((specialPass) ? (specialImage) : (normalImage)).getAccess()); 1383e5c31af7Sopenharmony_ci } 1384e5c31af7Sopenharmony_ci 1385e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 1386e5c31af7Sopenharmony_ci gl.useProgram(0); 1387e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate"); 1388e5c31af7Sopenharmony_ci } 1389e5c31af7Sopenharmony_ci 1390e5c31af7Sopenharmony_ci // Check results 1391e5c31af7Sopenharmony_ci { 1392e5c31af7Sopenharmony_ci tcu::Surface errorMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1393e5c31af7Sopenharmony_ci const tcu::RGBA badPixelColor = tcu::RGBA::red(); 1394e5c31af7Sopenharmony_ci const tcu::RGBA okPixelColor = tcu::RGBA::green(); 1395e5c31af7Sopenharmony_ci int badPixels = 0; 1396e5c31af7Sopenharmony_ci 1397e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Checking passes have identical red and blue channels and the green channel is correct in the constant pass." << tcu::TestLog::EndMessage; 1398e5c31af7Sopenharmony_ci 1399e5c31af7Sopenharmony_ci for (int y = 0; y < specialImage.getHeight(); ++y) 1400e5c31af7Sopenharmony_ci for (int x = 0; x < specialImage.getWidth(); ++x) 1401e5c31af7Sopenharmony_ci { 1402e5c31af7Sopenharmony_ci const float greenThreshold = 0.1f; 1403e5c31af7Sopenharmony_ci const tcu::Vec4 cNormal = normalImage.getAccess().getPixel(x, y); 1404e5c31af7Sopenharmony_ci const tcu::Vec4 cSpecial = specialImage.getAccess().getPixel(x, y); 1405e5c31af7Sopenharmony_ci 1406e5c31af7Sopenharmony_ci if (cNormal.x() != cSpecial.x() || cNormal.z() != cSpecial.z() || cNormal.y() < 1.0f - greenThreshold) 1407e5c31af7Sopenharmony_ci { 1408e5c31af7Sopenharmony_ci ++badPixels; 1409e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, badPixelColor); 1410e5c31af7Sopenharmony_ci } 1411e5c31af7Sopenharmony_ci else 1412e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, okPixelColor); 1413e5c31af7Sopenharmony_ci } 1414e5c31af7Sopenharmony_ci 1415e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)." << tcu::TestLog::EndMessage; 1416e5c31af7Sopenharmony_ci 1417e5c31af7Sopenharmony_ci if (badPixels) 1418e5c31af7Sopenharmony_ci { 1419e5c31af7Sopenharmony_ci m_testCtx.getLog() 1420e5c31af7Sopenharmony_ci << tcu::TestLog::ImageSet("Results", "Result verification") 1421e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Image with special green channel", "Image with special green channel", specialImage) 1422e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Image with constant green channel", "Image with constant green channel", normalImage) 1423e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Error Mask", "Error Mask", errorMask) 1424e5c31af7Sopenharmony_ci << tcu::TestLog::EndImageSet; 1425e5c31af7Sopenharmony_ci 1426e5c31af7Sopenharmony_ci // all ok? 1427e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 1428e5c31af7Sopenharmony_ci } 1429e5c31af7Sopenharmony_ci else 1430e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1431e5c31af7Sopenharmony_ci } 1432e5c31af7Sopenharmony_ci} 1433e5c31af7Sopenharmony_ci 1434e5c31af7Sopenharmony_cistd::string OutputCase::genVertexSource (void) const 1435e5c31af7Sopenharmony_ci{ 1436e5c31af7Sopenharmony_ci return 1437e5c31af7Sopenharmony_ci "attribute highp vec4 a_pos;\n" 1438e5c31af7Sopenharmony_ci "varying mediump vec2 v_pos;\n" 1439e5c31af7Sopenharmony_ci "void main ()\n" 1440e5c31af7Sopenharmony_ci "{\n" 1441e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 1442e5c31af7Sopenharmony_ci " v_pos = a_pos.xy;\n" 1443e5c31af7Sopenharmony_ci "}\n"; 1444e5c31af7Sopenharmony_ci} 1445e5c31af7Sopenharmony_ci 1446e5c31af7Sopenharmony_cistd::string OutputCase::genFragmentSource (void) const 1447e5c31af7Sopenharmony_ci{ 1448e5c31af7Sopenharmony_ci return 1449e5c31af7Sopenharmony_ci "uniform mediump float u_special;\n" 1450e5c31af7Sopenharmony_ci "varying mediump vec2 v_pos;\n" 1451e5c31af7Sopenharmony_ci "void main ()\n" 1452e5c31af7Sopenharmony_ci "{\n" 1453e5c31af7Sopenharmony_ci " gl_FragColor = vec4((v_pos.x + 1.0) * 0.5, u_special, (v_pos.y + 1.0) * 0.5, 1.0);\n" 1454e5c31af7Sopenharmony_ci "}\n"; 1455e5c31af7Sopenharmony_ci} 1456e5c31af7Sopenharmony_ci 1457e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1458e5c31af7Sopenharmony_ci * \brief Tests special floats in blending 1459e5c31af7Sopenharmony_ci * 1460e5c31af7Sopenharmony_ci * Tests special floats as alpha and color components with various blending 1461e5c31af7Sopenharmony_ci * modes. Test draws a test pattern and then does various blend operations 1462e5c31af7Sopenharmony_ci * with special float values. After the blending test another test pattern 1463e5c31af7Sopenharmony_ci * is drawn to detect possible blending anomalies. Test patterns should be 1464e5c31af7Sopenharmony_ci * identical. 1465e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1466e5c31af7Sopenharmony_ciclass BlendingCase : public FramebufferRenderCase 1467e5c31af7Sopenharmony_ci{ 1468e5c31af7Sopenharmony_cipublic: 1469e5c31af7Sopenharmony_ci BlendingCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type); 1470e5c31af7Sopenharmony_ci ~BlendingCase (void); 1471e5c31af7Sopenharmony_ci 1472e5c31af7Sopenharmony_ci void testFBO (void); 1473e5c31af7Sopenharmony_ci 1474e5c31af7Sopenharmony_ciprivate: 1475e5c31af7Sopenharmony_ci void drawTestImage (tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex); 1476e5c31af7Sopenharmony_ci 1477e5c31af7Sopenharmony_ci std::string genVertexSource (void) const; 1478e5c31af7Sopenharmony_ci std::string genFragmentSource (void) const; 1479e5c31af7Sopenharmony_ci}; 1480e5c31af7Sopenharmony_ci 1481e5c31af7Sopenharmony_ciBlendingCase::BlendingCase (Context& context, const char* name, const char* desc, FramebufferRenderCase::FrameBufferType type) 1482e5c31af7Sopenharmony_ci : FramebufferRenderCase (context, name, desc, type) 1483e5c31af7Sopenharmony_ci{ 1484e5c31af7Sopenharmony_ci} 1485e5c31af7Sopenharmony_ci 1486e5c31af7Sopenharmony_ciBlendingCase::~BlendingCase (void) 1487e5c31af7Sopenharmony_ci{ 1488e5c31af7Sopenharmony_ci deinit(); 1489e5c31af7Sopenharmony_ci} 1490e5c31af7Sopenharmony_ci 1491e5c31af7Sopenharmony_civoid BlendingCase::testFBO (void) 1492e5c31af7Sopenharmony_ci{ 1493e5c31af7Sopenharmony_ci static const GLenum equations[] = 1494e5c31af7Sopenharmony_ci { 1495e5c31af7Sopenharmony_ci GL_FUNC_ADD, 1496e5c31af7Sopenharmony_ci GL_FUNC_SUBTRACT, 1497e5c31af7Sopenharmony_ci GL_FUNC_REVERSE_SUBTRACT, 1498e5c31af7Sopenharmony_ci }; 1499e5c31af7Sopenharmony_ci static const GLenum functions[] = 1500e5c31af7Sopenharmony_ci { 1501e5c31af7Sopenharmony_ci GL_ZERO, 1502e5c31af7Sopenharmony_ci GL_ONE, 1503e5c31af7Sopenharmony_ci GL_SRC_COLOR, 1504e5c31af7Sopenharmony_ci GL_ONE_MINUS_SRC_COLOR, 1505e5c31af7Sopenharmony_ci GL_SRC_ALPHA, 1506e5c31af7Sopenharmony_ci GL_ONE_MINUS_SRC_ALPHA, 1507e5c31af7Sopenharmony_ci }; 1508e5c31af7Sopenharmony_ci 1509e5c31af7Sopenharmony_ci // Create a [BlendFuncs] X [s_specialFloats] grid of tiles. ( BlendFuncs = equations x functions ) 1510e5c31af7Sopenharmony_ci 1511e5c31af7Sopenharmony_ci const int numBlendFuncs = DE_LENGTH_OF_ARRAY(equations) * DE_LENGTH_OF_ARRAY(functions); 1512e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> gridVertices ((numBlendFuncs + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1)); 1513e5c31af7Sopenharmony_ci std::vector<deUint16> indices (numBlendFuncs * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6); 1514e5c31af7Sopenharmony_ci tcu::TextureFormat textureFormat (tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16) ? (tcu::TextureFormat::FLOAT) : (tcu::TextureFormat::UNORM_INT8)); 1515e5c31af7Sopenharmony_ci tcu::TextureLevel beforeImage (textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1516e5c31af7Sopenharmony_ci tcu::TextureLevel afterImage (textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1517e5c31af7Sopenharmony_ci 1518e5c31af7Sopenharmony_ci // vertices 1519e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x) 1520e5c31af7Sopenharmony_ci for (int y = 0; y < numBlendFuncs + 1; ++y) 1521e5c31af7Sopenharmony_ci { 1522e5c31af7Sopenharmony_ci const float posX = (float)x / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f; // map from [0, len(s_specialFloats)] to [-1, 1] 1523e5c31af7Sopenharmony_ci const float posY = (float)y / (float)numBlendFuncs * 2.0f - 1.0f; 1524e5c31af7Sopenharmony_ci 1525e5c31af7Sopenharmony_ci gridVertices[x * (numBlendFuncs + 1) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f); 1526e5c31af7Sopenharmony_ci } 1527e5c31af7Sopenharmony_ci 1528e5c31af7Sopenharmony_ci // tiles 1529e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x) 1530e5c31af7Sopenharmony_ci for (int y = 0; y < numBlendFuncs; ++y) 1531e5c31af7Sopenharmony_ci { 1532e5c31af7Sopenharmony_ci const int baseNdx = (x * numBlendFuncs + y) * 6; 1533e5c31af7Sopenharmony_ci 1534e5c31af7Sopenharmony_ci indices[baseNdx + 0] = (deUint16)((x+0) * (numBlendFuncs + 1) + (y+0)); 1535e5c31af7Sopenharmony_ci indices[baseNdx + 1] = (deUint16)((x+1) * (numBlendFuncs + 1) + (y+1)); 1536e5c31af7Sopenharmony_ci indices[baseNdx + 2] = (deUint16)((x+1) * (numBlendFuncs + 1) + (y+0)); 1537e5c31af7Sopenharmony_ci 1538e5c31af7Sopenharmony_ci indices[baseNdx + 3] = (deUint16)((x+0) * (numBlendFuncs + 1) + (y+0)); 1539e5c31af7Sopenharmony_ci indices[baseNdx + 4] = (deUint16)((x+1) * (numBlendFuncs + 1) + (y+1)); 1540e5c31af7Sopenharmony_ci indices[baseNdx + 5] = (deUint16)((x+0) * (numBlendFuncs + 1) + (y+1)); 1541e5c31af7Sopenharmony_ci } 1542e5c31af7Sopenharmony_ci 1543e5c31af7Sopenharmony_ci // Draw tiles 1544e5c31af7Sopenharmony_ci { 1545e5c31af7Sopenharmony_ci const int numPasses = 5; 1546e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1547e5c31af7Sopenharmony_ci const GLint positionLoc = gl.getAttribLocation(m_program->getProgram(), "a_pos"); 1548e5c31af7Sopenharmony_ci const GLint specialLoc = gl.getUniformLocation(m_program->getProgram(), "u_special"); 1549e5c31af7Sopenharmony_ci 1550e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 1551e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1552e5c31af7Sopenharmony_ci gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1553e5c31af7Sopenharmony_ci gl.useProgram(m_program->getProgram()); 1554e5c31af7Sopenharmony_ci gl.enable(GL_BLEND); 1555e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw"); 1556e5c31af7Sopenharmony_ci 1557e5c31af7Sopenharmony_ci gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]); 1558e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(positionLoc); 1559e5c31af7Sopenharmony_ci 1560e5c31af7Sopenharmony_ci // draw "before" image 1561e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing pre-draw pattern." << tcu::TestLog::EndMessage; 1562e5c31af7Sopenharmony_ci drawTestImage(beforeImage.getAccess(), specialLoc, (int)gridVertices.size() - 1); 1563e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw pattern"); 1564e5c31af7Sopenharmony_ci 1565e5c31af7Sopenharmony_ci // draw multiple passes with special floats 1566e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1567e5c31af7Sopenharmony_ci for (int passNdx = 0; passNdx < numPasses; ++passNdx) 1568e5c31af7Sopenharmony_ci { 1569e5c31af7Sopenharmony_ci de::Random rnd(123 + 567 * passNdx); 1570e5c31af7Sopenharmony_ci 1571e5c31af7Sopenharmony_ci m_testCtx.getLog() 1572e5c31af7Sopenharmony_ci << tcu::TestLog::Message 1573e5c31af7Sopenharmony_ci << "Pass " << passNdx << ": Drawing tiles with the shader.\n" 1574e5c31af7Sopenharmony_ci << "\tVarying u_special for each tile.\n" 1575e5c31af7Sopenharmony_ci << "\tVarying blend function and blend equation for each tile.\n" 1576e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1577e5c31af7Sopenharmony_ci 1578e5c31af7Sopenharmony_ci // draw tiles 1579e5c31af7Sopenharmony_ci for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x) 1580e5c31af7Sopenharmony_ci for (int y = 0; y < numBlendFuncs; ++y) 1581e5c31af7Sopenharmony_ci { 1582e5c31af7Sopenharmony_ci const GLenum blendEquation = equations[y % DE_LENGTH_OF_ARRAY(equations)]; 1583e5c31af7Sopenharmony_ci const GLenum blendFunction = functions[y / DE_LENGTH_OF_ARRAY(equations)]; 1584e5c31af7Sopenharmony_ci const GLenum blendFunctionDst = rnd.choose<GLenum>(DE_ARRAY_BEGIN(functions), DE_ARRAY_END(functions)); 1585e5c31af7Sopenharmony_ci const int indexIndex = (x * numBlendFuncs + y) * 6; 1586e5c31af7Sopenharmony_ci 1587e5c31af7Sopenharmony_ci // "rnd.get"s are run in a deterministic order 1588e5c31af7Sopenharmony_ci const deUint32 componentR = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats)); 1589e5c31af7Sopenharmony_ci const deUint32 componentG = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats)); 1590e5c31af7Sopenharmony_ci const deUint32 componentB = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats)); 1591e5c31af7Sopenharmony_ci const deUint32 componentA = rnd.choose<deUint32>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats)); 1592e5c31af7Sopenharmony_ci const tcu::UVec4 uniformValue = tcu::UVec4(componentR, componentG, componentB, componentA); 1593e5c31af7Sopenharmony_ci 1594e5c31af7Sopenharmony_ci gl.uniform4fv(specialLoc, 1, (const float*)uniformValue.getPtr()); 1595e5c31af7Sopenharmony_ci gl.blendEquation(blendEquation); 1596e5c31af7Sopenharmony_ci gl.blendFunc(blendFunction, blendFunctionDst); 1597e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]); 1598e5c31af7Sopenharmony_ci } 1599e5c31af7Sopenharmony_ci } 1600e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "special passes"); 1601e5c31af7Sopenharmony_ci 1602e5c31af7Sopenharmony_ci // draw "after" image 1603e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Drawing post-draw pattern." << tcu::TestLog::EndMessage; 1604e5c31af7Sopenharmony_ci drawTestImage(afterImage.getAccess(), specialLoc, (int)gridVertices.size() - 1); 1605e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "post-draw pattern"); 1606e5c31af7Sopenharmony_ci 1607e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(positionLoc); 1608e5c31af7Sopenharmony_ci gl.useProgram(0); 1609e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate"); 1610e5c31af7Sopenharmony_ci } 1611e5c31af7Sopenharmony_ci 1612e5c31af7Sopenharmony_ci // Check results 1613e5c31af7Sopenharmony_ci { 1614e5c31af7Sopenharmony_ci tcu::Surface errorMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE); 1615e5c31af7Sopenharmony_ci const tcu::RGBA badPixelColor = tcu::RGBA::red(); 1616e5c31af7Sopenharmony_ci const tcu::RGBA okPixelColor = tcu::RGBA::green(); 1617e5c31af7Sopenharmony_ci int badPixels = 0; 1618e5c31af7Sopenharmony_ci 1619e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Checking patterns are identical." << tcu::TestLog::EndMessage; 1620e5c31af7Sopenharmony_ci 1621e5c31af7Sopenharmony_ci for (int y = 0; y < beforeImage.getHeight(); ++y) 1622e5c31af7Sopenharmony_ci for (int x = 0; x < beforeImage.getWidth(); ++x) 1623e5c31af7Sopenharmony_ci { 1624e5c31af7Sopenharmony_ci const tcu::Vec4 cBefore = beforeImage.getAccess().getPixel(x, y); 1625e5c31af7Sopenharmony_ci const tcu::Vec4 cAfter = afterImage.getAccess().getPixel(x, y); 1626e5c31af7Sopenharmony_ci 1627e5c31af7Sopenharmony_ci if (cBefore != cAfter) 1628e5c31af7Sopenharmony_ci { 1629e5c31af7Sopenharmony_ci ++badPixels; 1630e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, badPixelColor); 1631e5c31af7Sopenharmony_ci } 1632e5c31af7Sopenharmony_ci else 1633e5c31af7Sopenharmony_ci errorMask.setPixel(x, y, okPixelColor); 1634e5c31af7Sopenharmony_ci } 1635e5c31af7Sopenharmony_ci 1636e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)." << tcu::TestLog::EndMessage; 1637e5c31af7Sopenharmony_ci 1638e5c31af7Sopenharmony_ci if (badPixels) 1639e5c31af7Sopenharmony_ci { 1640e5c31af7Sopenharmony_ci m_testCtx.getLog() 1641e5c31af7Sopenharmony_ci << tcu::TestLog::ImageSet("Results", "Result verification") 1642e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Pattern drawn before special float blending", "Pattern drawn before special float blending", beforeImage) 1643e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Pattern drawn after special float blending", "Pattern drawn after special float blending", afterImage) 1644e5c31af7Sopenharmony_ci << tcu::TestLog::EndImageSet; 1645e5c31af7Sopenharmony_ci 1646e5c31af7Sopenharmony_ci // all ok? 1647e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 1648e5c31af7Sopenharmony_ci } 1649e5c31af7Sopenharmony_ci else 1650e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1651e5c31af7Sopenharmony_ci } 1652e5c31af7Sopenharmony_ci} 1653e5c31af7Sopenharmony_ci 1654e5c31af7Sopenharmony_civoid BlendingCase::drawTestImage (tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex) 1655e5c31af7Sopenharmony_ci{ 1656e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1657e5c31af7Sopenharmony_ci de::Random rnd (123); 1658e5c31af7Sopenharmony_ci 1659e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1660e5c31af7Sopenharmony_ci gl.blendEquation(GL_FUNC_ADD); 1661e5c31af7Sopenharmony_ci gl.blendFunc(GL_ONE, GL_ONE); 1662e5c31af7Sopenharmony_ci 1663e5c31af7Sopenharmony_ci for (int tri = 0; tri < 20; ++tri) 1664e5c31af7Sopenharmony_ci { 1665e5c31af7Sopenharmony_ci tcu::Vec4 color; 1666e5c31af7Sopenharmony_ci color.x() = rnd.getFloat(); 1667e5c31af7Sopenharmony_ci color.y() = rnd.getFloat(); 1668e5c31af7Sopenharmony_ci color.z() = rnd.getFloat(); 1669e5c31af7Sopenharmony_ci color.w() = rnd.getFloat(); 1670e5c31af7Sopenharmony_ci gl.uniform4fv(uColorLoc, 1, color.getPtr()); 1671e5c31af7Sopenharmony_ci 1672e5c31af7Sopenharmony_ci deUint16 indices[3]; 1673e5c31af7Sopenharmony_ci indices[0] = (deUint16)rnd.getInt(0, maxVertexIndex); 1674e5c31af7Sopenharmony_ci indices[1] = (deUint16)rnd.getInt(0, maxVertexIndex); 1675e5c31af7Sopenharmony_ci indices[2] = (deUint16)rnd.getInt(0, maxVertexIndex); 1676e5c31af7Sopenharmony_ci 1677e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, indices); 1678e5c31af7Sopenharmony_ci } 1679e5c31af7Sopenharmony_ci 1680e5c31af7Sopenharmony_ci gl.finish(); 1681e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, dst); 1682e5c31af7Sopenharmony_ci} 1683e5c31af7Sopenharmony_ci 1684e5c31af7Sopenharmony_cistd::string BlendingCase::genVertexSource (void) const 1685e5c31af7Sopenharmony_ci{ 1686e5c31af7Sopenharmony_ci return 1687e5c31af7Sopenharmony_ci "attribute highp vec4 a_pos;\n" 1688e5c31af7Sopenharmony_ci "void main ()\n" 1689e5c31af7Sopenharmony_ci "{\n" 1690e5c31af7Sopenharmony_ci " gl_Position = a_pos;\n" 1691e5c31af7Sopenharmony_ci "}\n"; 1692e5c31af7Sopenharmony_ci} 1693e5c31af7Sopenharmony_ci 1694e5c31af7Sopenharmony_cistd::string BlendingCase::genFragmentSource (void) const 1695e5c31af7Sopenharmony_ci{ 1696e5c31af7Sopenharmony_ci return 1697e5c31af7Sopenharmony_ci "uniform mediump vec4 u_special;\n" 1698e5c31af7Sopenharmony_ci "void main ()\n" 1699e5c31af7Sopenharmony_ci "{\n" 1700e5c31af7Sopenharmony_ci " gl_FragColor = u_special;\n" 1701e5c31af7Sopenharmony_ci "}\n"; 1702e5c31af7Sopenharmony_ci} 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci} //anonymous 1705e5c31af7Sopenharmony_ci 1706e5c31af7Sopenharmony_ciSpecialFloatTests::SpecialFloatTests (Context& context) 1707e5c31af7Sopenharmony_ci : TestCaseGroup(context, "special_float", "Special float tests") 1708e5c31af7Sopenharmony_ci{ 1709e5c31af7Sopenharmony_ci} 1710e5c31af7Sopenharmony_ci 1711e5c31af7Sopenharmony_ciSpecialFloatTests::~SpecialFloatTests (void) 1712e5c31af7Sopenharmony_ci{ 1713e5c31af7Sopenharmony_ci} 1714e5c31af7Sopenharmony_ci 1715e5c31af7Sopenharmony_civoid SpecialFloatTests::init (void) 1716e5c31af7Sopenharmony_ci{ 1717e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const vertexGroup = new tcu::TestCaseGroup(m_testCtx, "vertex", "Run vertex shader with special float values"); 1718e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const fragmentGroup = new tcu::TestCaseGroup(m_testCtx, "fragment", "Run fragment shader with special float values"); 1719e5c31af7Sopenharmony_ci tcu::TestCaseGroup* const framebufferGroup = new tcu::TestCaseGroup(m_testCtx, "framebuffer", "Test framebuffers containing special float values"); 1720e5c31af7Sopenharmony_ci 1721e5c31af7Sopenharmony_ci // .vertex 1722e5c31af7Sopenharmony_ci { 1723e5c31af7Sopenharmony_ci vertexGroup->addChild(new VertexAttributeCase (m_context, "attribute_buffer", "special attribute values in a buffer", VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_VERTEX)); 1724e5c31af7Sopenharmony_ci vertexGroup->addChild(new VertexAttributeCase (m_context, "attribute_client", "special attribute values in a client storage", VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_VERTEX)); 1725e5c31af7Sopenharmony_ci vertexGroup->addChild(new UniformCase (m_context, "uniform", "special uniform values", UniformCase::TYPE_VERTEX)); 1726e5c31af7Sopenharmony_ci vertexGroup->addChild(new TextureSamplerCase (m_context, "sampler_tex_coord", "special texture coords", TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_TEX_COORD)); 1727e5c31af7Sopenharmony_ci vertexGroup->addChild(new TextureSamplerCase (m_context, "sampler_tex_coord_cube", "special texture coords to cubemap", TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_TEX_COORD_CUBE)); 1728e5c31af7Sopenharmony_ci vertexGroup->addChild(new TextureSamplerCase (m_context, "sampler_lod", "special texture lod", TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_LOD)); 1729e5c31af7Sopenharmony_ci 1730e5c31af7Sopenharmony_ci addChild(vertexGroup); 1731e5c31af7Sopenharmony_ci } 1732e5c31af7Sopenharmony_ci 1733e5c31af7Sopenharmony_ci // .fragment 1734e5c31af7Sopenharmony_ci { 1735e5c31af7Sopenharmony_ci fragmentGroup->addChild(new VertexAttributeCase (m_context, "attribute_buffer", "special attribute values in a buffer", VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_FRAGMENT)); 1736e5c31af7Sopenharmony_ci fragmentGroup->addChild(new VertexAttributeCase (m_context, "attribute_client", "special attribute values in a client storage", VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_FRAGMENT)); 1737e5c31af7Sopenharmony_ci fragmentGroup->addChild(new UniformCase (m_context, "uniform", "special uniform values", UniformCase::TYPE_FRAGMENT)); 1738e5c31af7Sopenharmony_ci fragmentGroup->addChild(new TextureSamplerCase (m_context, "sampler_tex_coord", "special texture coords", TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_TEX_COORD)); 1739e5c31af7Sopenharmony_ci fragmentGroup->addChild(new TextureSamplerCase (m_context, "sampler_tex_coord_cube", "special texture coords to cubemap", TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_TEX_COORD_CUBE)); 1740e5c31af7Sopenharmony_ci fragmentGroup->addChild(new TextureSamplerCase (m_context, "sampler_lod", "special texture lod", TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_LOD)); 1741e5c31af7Sopenharmony_ci 1742e5c31af7Sopenharmony_ci addChild(fragmentGroup); 1743e5c31af7Sopenharmony_ci } 1744e5c31af7Sopenharmony_ci 1745e5c31af7Sopenharmony_ci // .framebuffer 1746e5c31af7Sopenharmony_ci { 1747e5c31af7Sopenharmony_ci framebufferGroup->addChild(new OutputCase (m_context, "write_default", "write special floating point values to default framebuffer", FramebufferRenderCase::FBO_DEFAULT)); 1748e5c31af7Sopenharmony_ci framebufferGroup->addChild(new OutputCase (m_context, "write_rgba", "write special floating point values to RGBA framebuffer", FramebufferRenderCase::FBO_RGBA)); 1749e5c31af7Sopenharmony_ci framebufferGroup->addChild(new OutputCase (m_context, "write_rgba4", "write special floating point values to RGBA4 framebuffer", FramebufferRenderCase::FBO_RGBA4)); 1750e5c31af7Sopenharmony_ci framebufferGroup->addChild(new OutputCase (m_context, "write_rgb5_a1", "write special floating point values to RGB5_A1 framebuffer", FramebufferRenderCase::FBO_RGB5_A1)); 1751e5c31af7Sopenharmony_ci framebufferGroup->addChild(new OutputCase (m_context, "write_rgb565", "write special floating point values to RGB565 framebuffer", FramebufferRenderCase::FBO_RGB565)); 1752e5c31af7Sopenharmony_ci framebufferGroup->addChild(new OutputCase (m_context, "write_float16", "write special floating point values to float16 framebuffer", FramebufferRenderCase::FBO_RGBA_FLOAT16)); 1753e5c31af7Sopenharmony_ci 1754e5c31af7Sopenharmony_ci framebufferGroup->addChild(new BlendingCase (m_context, "blend_default", "blend special floating point values in a default framebuffer", FramebufferRenderCase::FBO_DEFAULT)); 1755e5c31af7Sopenharmony_ci framebufferGroup->addChild(new BlendingCase (m_context, "blend_rgba", "blend special floating point values in a RGBA framebuffer", FramebufferRenderCase::FBO_RGBA)); 1756e5c31af7Sopenharmony_ci framebufferGroup->addChild(new BlendingCase (m_context, "blend_float16", "blend special floating point values in a float16 framebuffer", FramebufferRenderCase::FBO_RGBA_FLOAT16)); 1757e5c31af7Sopenharmony_ci 1758e5c31af7Sopenharmony_ci addChild(framebufferGroup); 1759e5c31af7Sopenharmony_ci } 1760e5c31af7Sopenharmony_ci} 1761e5c31af7Sopenharmony_ci 1762e5c31af7Sopenharmony_ci} // Stress 1763e5c31af7Sopenharmony_ci} // gles2 1764e5c31af7Sopenharmony_ci} // deqp 1765