1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) 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 Fragment operation test utilities. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "glsFragmentOpUtil.hpp" 25e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 26e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 27e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp" 28e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 29e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_cinamespace deqp 32e5c31af7Sopenharmony_ci{ 33e5c31af7Sopenharmony_cinamespace gls 34e5c31af7Sopenharmony_ci{ 35e5c31af7Sopenharmony_cinamespace FragmentOpUtil 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_citemplate<typename T> 39e5c31af7Sopenharmony_ciinline T triQuadInterpolate (const T values[4], float xFactor, float yFactor) 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci if (xFactor + yFactor < 1.0f) 42e5c31af7Sopenharmony_ci return values[0] + (values[2]-values[0])*xFactor + (values[1]-values[0])*yFactor; 43e5c31af7Sopenharmony_ci else 44e5c31af7Sopenharmony_ci return values[3] + (values[1]-values[3])*(1.0f-xFactor) + (values[2]-values[3])*(1.0f-yFactor); 45e5c31af7Sopenharmony_ci} 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ci// GLSL ES 1.0 shaders 48e5c31af7Sopenharmony_cistatic const char* s_glsl1VertSrc = 49e5c31af7Sopenharmony_ci "attribute highp vec4 a_position;\n" 50e5c31af7Sopenharmony_ci "attribute mediump vec4 a_color;\n" 51e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 52e5c31af7Sopenharmony_ci "void main()\n" 53e5c31af7Sopenharmony_ci "{\n" 54e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 55e5c31af7Sopenharmony_ci " v_color = a_color;\n" 56e5c31af7Sopenharmony_ci "}\n"; 57e5c31af7Sopenharmony_cistatic const char* s_glsl1FragSrc = 58e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 59e5c31af7Sopenharmony_ci "void main()\n" 60e5c31af7Sopenharmony_ci "{\n" 61e5c31af7Sopenharmony_ci " gl_FragColor = v_color;\n" 62e5c31af7Sopenharmony_ci "}\n"; 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_ci// GLSL ES 3.0 shaders 65e5c31af7Sopenharmony_cistatic const char* s_glsl3VertSrc = 66e5c31af7Sopenharmony_ci "#version 300 es\n" 67e5c31af7Sopenharmony_ci "in highp vec4 a_position;\n" 68e5c31af7Sopenharmony_ci "in mediump vec4 a_color;\n" 69e5c31af7Sopenharmony_ci "out mediump vec4 v_color;\n" 70e5c31af7Sopenharmony_ci "void main()\n" 71e5c31af7Sopenharmony_ci "{\n" 72e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 73e5c31af7Sopenharmony_ci " v_color = a_color;\n" 74e5c31af7Sopenharmony_ci "}\n"; 75e5c31af7Sopenharmony_cistatic const char* s_glsl3FragSrc = 76e5c31af7Sopenharmony_ci "#version 300 es\n" 77e5c31af7Sopenharmony_ci "in mediump vec4 v_color;\n" 78e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 79e5c31af7Sopenharmony_ci "void main()\n" 80e5c31af7Sopenharmony_ci "{\n" 81e5c31af7Sopenharmony_ci " o_color = v_color;\n" 82e5c31af7Sopenharmony_ci "}\n"; 83e5c31af7Sopenharmony_ci 84e5c31af7Sopenharmony_ci// GLSL 3.3 shaders 85e5c31af7Sopenharmony_cistatic const char* s_glsl33VertSrc = 86e5c31af7Sopenharmony_ci "#version 330 core\n" 87e5c31af7Sopenharmony_ci "in vec4 a_position;\n" 88e5c31af7Sopenharmony_ci "in vec4 a_color;\n" 89e5c31af7Sopenharmony_ci "in vec4 a_color1;\n" 90e5c31af7Sopenharmony_ci "out vec4 v_color;\n" 91e5c31af7Sopenharmony_ci "out vec4 v_color1;\n" 92e5c31af7Sopenharmony_ci "void main()\n" 93e5c31af7Sopenharmony_ci "{\n" 94e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 95e5c31af7Sopenharmony_ci " v_color = a_color;\n" 96e5c31af7Sopenharmony_ci " v_color1 = a_color1;\n" 97e5c31af7Sopenharmony_ci "}\n"; 98e5c31af7Sopenharmony_cistatic const char* s_glsl33FragSrc = 99e5c31af7Sopenharmony_ci "#version 330 core\n" 100e5c31af7Sopenharmony_ci "in vec4 v_color;\n" 101e5c31af7Sopenharmony_ci "in vec4 v_color1;\n" 102e5c31af7Sopenharmony_ci "layout(location = 0, index = 0) out vec4 o_color;\n" 103e5c31af7Sopenharmony_ci "layout(location = 0, index = 1) out vec4 o_color1;\n" 104e5c31af7Sopenharmony_ci "void main()\n" 105e5c31af7Sopenharmony_ci "{\n" 106e5c31af7Sopenharmony_ci " o_color = v_color;\n" 107e5c31af7Sopenharmony_ci " o_color1 = v_color1;\n" 108e5c31af7Sopenharmony_ci "}\n"; 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_cistatic const char* getVertSrc (glu::GLSLVersion glslVersion) 111e5c31af7Sopenharmony_ci{ 112e5c31af7Sopenharmony_ci if (glslVersion == glu::GLSL_VERSION_100_ES) 113e5c31af7Sopenharmony_ci return s_glsl1VertSrc; 114e5c31af7Sopenharmony_ci else if (glslVersion == glu::GLSL_VERSION_300_ES) 115e5c31af7Sopenharmony_ci return s_glsl3VertSrc; 116e5c31af7Sopenharmony_ci else if (glslVersion == glu::GLSL_VERSION_330) 117e5c31af7Sopenharmony_ci return s_glsl33VertSrc; 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 120e5c31af7Sopenharmony_ci return 0; 121e5c31af7Sopenharmony_ci} 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_cistatic const char* getFragSrc (glu::GLSLVersion glslVersion) 124e5c31af7Sopenharmony_ci{ 125e5c31af7Sopenharmony_ci if (glslVersion == glu::GLSL_VERSION_100_ES) 126e5c31af7Sopenharmony_ci return s_glsl1FragSrc; 127e5c31af7Sopenharmony_ci else if (glslVersion == glu::GLSL_VERSION_300_ES) 128e5c31af7Sopenharmony_ci return s_glsl3FragSrc; 129e5c31af7Sopenharmony_ci else if (glslVersion == glu::GLSL_VERSION_330) 130e5c31af7Sopenharmony_ci return s_glsl33FragSrc; 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 133e5c31af7Sopenharmony_ci return 0; 134e5c31af7Sopenharmony_ci} 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ciQuadRenderer::QuadRenderer (const glu::RenderContext& context, glu::GLSLVersion glslVersion) 137e5c31af7Sopenharmony_ci : m_context (context) 138e5c31af7Sopenharmony_ci , m_program (DE_NULL) 139e5c31af7Sopenharmony_ci , m_positionLoc (0) 140e5c31af7Sopenharmony_ci , m_colorLoc (-1) 141e5c31af7Sopenharmony_ci , m_color1Loc (-1) 142e5c31af7Sopenharmony_ci , m_blendFuncExt (!glu::glslVersionIsES(glslVersion) && (glslVersion >= glu::GLSL_VERSION_330)) 143e5c31af7Sopenharmony_ci{ 144e5c31af7Sopenharmony_ci DE_ASSERT(glslVersion == glu::GLSL_VERSION_100_ES || 145e5c31af7Sopenharmony_ci glslVersion == glu::GLSL_VERSION_300_ES || 146e5c31af7Sopenharmony_ci glslVersion == glu::GLSL_VERSION_330); 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getFunctions(); 149e5c31af7Sopenharmony_ci const char* vertSrc = getVertSrc(glslVersion); 150e5c31af7Sopenharmony_ci const char* fragSrc = getFragSrc(glslVersion); 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context, glu::makeVtxFragSources(vertSrc, fragSrc)); 153e5c31af7Sopenharmony_ci if (!m_program->isOk()) 154e5c31af7Sopenharmony_ci { 155e5c31af7Sopenharmony_ci delete m_program; 156e5c31af7Sopenharmony_ci throw tcu::TestError("Failed to compile program", DE_NULL, __FILE__, __LINE__); 157e5c31af7Sopenharmony_ci } 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_ci m_positionLoc = gl.getAttribLocation(m_program->getProgram(), "a_position"); 160e5c31af7Sopenharmony_ci m_colorLoc = gl.getAttribLocation(m_program->getProgram(), "a_color"); 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci if (m_blendFuncExt) 163e5c31af7Sopenharmony_ci m_color1Loc = gl.getAttribLocation(m_program->getProgram(), "a_color1"); 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci if (m_positionLoc < 0 || m_colorLoc < 0 || (m_blendFuncExt && m_color1Loc < 0)) 166e5c31af7Sopenharmony_ci { 167e5c31af7Sopenharmony_ci delete m_program; 168e5c31af7Sopenharmony_ci throw tcu::TestError("Invalid attribute locations", DE_NULL, __FILE__, __LINE__); 169e5c31af7Sopenharmony_ci } 170e5c31af7Sopenharmony_ci} 171e5c31af7Sopenharmony_ci 172e5c31af7Sopenharmony_ciQuadRenderer::~QuadRenderer (void) 173e5c31af7Sopenharmony_ci{ 174e5c31af7Sopenharmony_ci delete m_program; 175e5c31af7Sopenharmony_ci} 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_civoid QuadRenderer::render (const Quad& quad) const 178e5c31af7Sopenharmony_ci{ 179e5c31af7Sopenharmony_ci const float position[] = 180e5c31af7Sopenharmony_ci { 181e5c31af7Sopenharmony_ci quad.posA.x(), quad.posA.y(), quad.depth[0], 1.0f, 182e5c31af7Sopenharmony_ci quad.posA.x(), quad.posB.y(), quad.depth[1], 1.0f, 183e5c31af7Sopenharmony_ci quad.posB.x(), quad.posA.y(), quad.depth[2], 1.0f, 184e5c31af7Sopenharmony_ci quad.posB.x(), quad.posB.y(), quad.depth[3], 1.0f 185e5c31af7Sopenharmony_ci }; 186e5c31af7Sopenharmony_ci const deUint8 indices[] = { 0, 2, 1, 1, 2, 3 }; 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(tcu::Vec4) == sizeof(float)*4); 189e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(quad.color) == sizeof(float)*4*4); 190e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(quad.color1) == sizeof(float)*4*4); 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci std::vector<glu::VertexArrayBinding> vertexArrays; 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci vertexArrays.push_back(glu::va::Float(m_positionLoc, 4, 4, 0, &position[0])); 195e5c31af7Sopenharmony_ci vertexArrays.push_back(glu::va::Float(m_colorLoc, 4, 4, 0, (const float*)&quad.color[0])); 196e5c31af7Sopenharmony_ci 197e5c31af7Sopenharmony_ci if (m_blendFuncExt) 198e5c31af7Sopenharmony_ci vertexArrays.push_back(glu::va::Float(m_color1Loc, 4, 4, 0, (const float*)&quad.color1[0])); 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci m_context.getFunctions().useProgram(m_program->getProgram()); 201e5c31af7Sopenharmony_ci glu::draw(m_context, m_program->getProgram(), 202e5c31af7Sopenharmony_ci (int)vertexArrays.size(), &vertexArrays[0], 203e5c31af7Sopenharmony_ci glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0])); 204e5c31af7Sopenharmony_ci} 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ciReferenceQuadRenderer::ReferenceQuadRenderer (void) 207e5c31af7Sopenharmony_ci : m_fragmentBufferSize(0) 208e5c31af7Sopenharmony_ci{ 209e5c31af7Sopenharmony_ci for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_fragmentDepths); i++) 210e5c31af7Sopenharmony_ci m_fragmentDepths[i] = 0.0f; 211e5c31af7Sopenharmony_ci} 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_civoid ReferenceQuadRenderer::flushFragmentBuffer (const rr::MultisamplePixelBufferAccess& colorBuffer, 214e5c31af7Sopenharmony_ci const rr::MultisamplePixelBufferAccess& depthBuffer, 215e5c31af7Sopenharmony_ci const rr::MultisamplePixelBufferAccess& stencilBuffer, 216e5c31af7Sopenharmony_ci rr::FaceType faceType, 217e5c31af7Sopenharmony_ci const rr::FragmentOperationState& state) 218e5c31af7Sopenharmony_ci{ 219e5c31af7Sopenharmony_ci m_fragmentProcessor.render(colorBuffer, depthBuffer, stencilBuffer, &m_fragmentBuffer[0], m_fragmentBufferSize, faceType, state); 220e5c31af7Sopenharmony_ci m_fragmentBufferSize = 0; 221e5c31af7Sopenharmony_ci} 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_civoid ReferenceQuadRenderer::render (const tcu::PixelBufferAccess& colorBuffer, 224e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess& depthBuffer, 225e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess& stencilBuffer, 226e5c31af7Sopenharmony_ci const IntegerQuad& quad, 227e5c31af7Sopenharmony_ci const rr::FragmentOperationState& state) 228e5c31af7Sopenharmony_ci{ 229e5c31af7Sopenharmony_ci bool flipX = quad.posA.x() > quad.posB.x(); 230e5c31af7Sopenharmony_ci bool flipY = quad.posA.y() > quad.posB.y(); 231e5c31af7Sopenharmony_ci rr::FaceType faceType = flipX == flipY ? rr::FACETYPE_FRONT : rr::FACETYPE_BACK; 232e5c31af7Sopenharmony_ci int xFirst = flipX ? quad.posB.x() : quad.posA.x(); 233e5c31af7Sopenharmony_ci int xLast = flipX ? quad.posA.x() : quad.posB.x(); 234e5c31af7Sopenharmony_ci int yFirst = flipY ? quad.posB.y() : quad.posA.y(); 235e5c31af7Sopenharmony_ci int yLast = flipY ? quad.posA.y() : quad.posB.y(); 236e5c31af7Sopenharmony_ci float width = (float)(xLast - xFirst + 1); 237e5c31af7Sopenharmony_ci float height = (float)(yLast - yFirst + 1); 238e5c31af7Sopenharmony_ci 239e5c31af7Sopenharmony_ci for (int y = yFirst; y <= yLast; y++) 240e5c31af7Sopenharmony_ci { 241e5c31af7Sopenharmony_ci // Interpolation factor for y. 242e5c31af7Sopenharmony_ci float yRatio = (0.5f + (float)(y - yFirst)) / height; 243e5c31af7Sopenharmony_ci if (flipY) 244e5c31af7Sopenharmony_ci yRatio = 1.0f - yRatio; 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ci for (int x = xFirst; x <= xLast; x++) 247e5c31af7Sopenharmony_ci { 248e5c31af7Sopenharmony_ci // Interpolation factor for x. 249e5c31af7Sopenharmony_ci float xRatio = (0.5f + (float)(x - xFirst)) / width; 250e5c31af7Sopenharmony_ci if (flipX) 251e5c31af7Sopenharmony_ci xRatio = 1.0f - xRatio; 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci tcu::Vec4 color = triQuadInterpolate(quad.color, xRatio, yRatio); 254e5c31af7Sopenharmony_ci tcu::Vec4 color1 = triQuadInterpolate(quad.color1, xRatio, yRatio); 255e5c31af7Sopenharmony_ci float depth = triQuadInterpolate(quad.depth, xRatio, yRatio); 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci // Interpolated color and depth. 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(MAX_FRAGMENT_BUFFER_SIZE == DE_LENGTH_OF_ARRAY(m_fragmentBuffer)); 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci if (m_fragmentBufferSize >= MAX_FRAGMENT_BUFFER_SIZE) 262e5c31af7Sopenharmony_ci flushFragmentBuffer(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer), 263e5c31af7Sopenharmony_ci rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthBuffer), 264e5c31af7Sopenharmony_ci rr::MultisamplePixelBufferAccess::fromMultisampleAccess(stencilBuffer), faceType, state); 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ci m_fragmentDepths[m_fragmentBufferSize] = depth; 267e5c31af7Sopenharmony_ci m_fragmentBuffer[m_fragmentBufferSize] = rr::Fragment(tcu::IVec2(x, y), rr::GenericVec4(color), rr::GenericVec4(color1), 1u /* coverage mask */, &m_fragmentDepths[m_fragmentBufferSize]); 268e5c31af7Sopenharmony_ci m_fragmentBufferSize++; 269e5c31af7Sopenharmony_ci } 270e5c31af7Sopenharmony_ci } 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_ci flushFragmentBuffer(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer), 273e5c31af7Sopenharmony_ci rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthBuffer), 274e5c31af7Sopenharmony_ci rr::MultisamplePixelBufferAccess::fromMultisampleAccess(stencilBuffer), faceType, state); 275e5c31af7Sopenharmony_ci} 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_citcu::PixelBufferAccess getMultisampleAccess(const tcu::PixelBufferAccess& original) 278e5c31af7Sopenharmony_ci{ 279e5c31af7Sopenharmony_ci return tcu::PixelBufferAccess(original.getFormat(), 280e5c31af7Sopenharmony_ci 1, 281e5c31af7Sopenharmony_ci original.getWidth(), 282e5c31af7Sopenharmony_ci original.getHeight(), 283e5c31af7Sopenharmony_ci original.getFormat().getPixelSize(), 284e5c31af7Sopenharmony_ci original.getRowPitch(), 285e5c31af7Sopenharmony_ci original.getDataPtr()); 286e5c31af7Sopenharmony_ci} 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_citcu::ConstPixelBufferAccess getMultisampleAccess(const tcu::ConstPixelBufferAccess& original) 289e5c31af7Sopenharmony_ci{ 290e5c31af7Sopenharmony_ci return tcu::ConstPixelBufferAccess(original.getFormat(), 291e5c31af7Sopenharmony_ci 1, 292e5c31af7Sopenharmony_ci original.getWidth(), 293e5c31af7Sopenharmony_ci original.getHeight(), 294e5c31af7Sopenharmony_ci original.getFormat().getPixelSize(), 295e5c31af7Sopenharmony_ci original.getRowPitch(), 296e5c31af7Sopenharmony_ci original.getDataPtr()); 297e5c31af7Sopenharmony_ci} 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_ci} // FragmentOpUtil 300e5c31af7Sopenharmony_ci} // gls 301e5c31af7Sopenharmony_ci} // deqp 302