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 gl_FragData[] tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es2fShaderFragDataTests.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "glsShaderLibrary.hpp" 27e5c31af7Sopenharmony_ci 28e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 29e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 30e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp" 31e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 32e5c31af7Sopenharmony_ci#include "gluObjectWrapper.hpp" 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 35e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 36e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 37e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 40e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_cinamespace deqp 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_cinamespace gles2 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_cinamespace Functional 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciusing std::string; 50e5c31af7Sopenharmony_ciusing tcu::TestLog; 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_cinamespace 53e5c31af7Sopenharmony_ci{ 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_cienum IndexExprType 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_ci INDEX_EXPR_STATIC = 0, 58e5c31af7Sopenharmony_ci INDEX_EXPR_UNIFORM, 59e5c31af7Sopenharmony_ci INDEX_EXPR_DYNAMIC, 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ci INDEX_EXPR_TYPE_LAST 62e5c31af7Sopenharmony_ci}; 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_cistatic bool compareSingleColor (tcu::TestLog& log, const tcu::Surface& surface, tcu::RGBA expectedColor, tcu::RGBA threshold) 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_ci const int maxPrints = 10; 67e5c31af7Sopenharmony_ci int numFailedPixels = 0; 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci log << TestLog::Message << "Expecting " << expectedColor << " with threshold " << threshold << TestLog::EndMessage; 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci for (int y = 0; y < surface.getHeight(); y++) 72e5c31af7Sopenharmony_ci { 73e5c31af7Sopenharmony_ci for (int x = 0; x < surface.getWidth(); x++) 74e5c31af7Sopenharmony_ci { 75e5c31af7Sopenharmony_ci const tcu::RGBA resultColor = surface.getPixel(x, y); 76e5c31af7Sopenharmony_ci const bool isOk = compareThreshold(resultColor, expectedColor, threshold); 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci if (!isOk) 79e5c31af7Sopenharmony_ci { 80e5c31af7Sopenharmony_ci if (numFailedPixels < maxPrints) 81e5c31af7Sopenharmony_ci log << TestLog::Message << "ERROR: Got " << resultColor << " at (" << x << ", " << y << ")!" << TestLog::EndMessage; 82e5c31af7Sopenharmony_ci else if (numFailedPixels == maxPrints) 83e5c31af7Sopenharmony_ci log << TestLog::Message << "..." << TestLog::EndMessage; 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ci numFailedPixels += 1; 86e5c31af7Sopenharmony_ci } 87e5c31af7Sopenharmony_ci } 88e5c31af7Sopenharmony_ci } 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ci if (numFailedPixels > 0) 91e5c31af7Sopenharmony_ci { 92e5c31af7Sopenharmony_ci log << TestLog::Message << "Found " << numFailedPixels << " invalid pixels, comparison FAILED!" << TestLog::EndMessage; 93e5c31af7Sopenharmony_ci log << TestLog::Image("ResultImage", "Result Image", surface); 94e5c31af7Sopenharmony_ci return false; 95e5c31af7Sopenharmony_ci } 96e5c31af7Sopenharmony_ci else 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci log << TestLog::Message << "Image comparison passed." << TestLog::EndMessage; 99e5c31af7Sopenharmony_ci return true; 100e5c31af7Sopenharmony_ci } 101e5c31af7Sopenharmony_ci} 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ciclass FragDataIndexingCase : public TestCase 104e5c31af7Sopenharmony_ci{ 105e5c31af7Sopenharmony_cipublic: 106e5c31af7Sopenharmony_ci FragDataIndexingCase (Context& context, const char* name, const char* description, IndexExprType indexExprType) 107e5c31af7Sopenharmony_ci : TestCase (context, name, description) 108e5c31af7Sopenharmony_ci , m_indexExprType (indexExprType) 109e5c31af7Sopenharmony_ci { 110e5c31af7Sopenharmony_ci } 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ci static glu::ProgramSources genSources (const IndexExprType indexExprType) 113e5c31af7Sopenharmony_ci { 114e5c31af7Sopenharmony_ci const char* const fragIndexExpr = indexExprType == INDEX_EXPR_STATIC ? "0" : 115e5c31af7Sopenharmony_ci indexExprType == INDEX_EXPR_UNIFORM ? "u_index" : 116e5c31af7Sopenharmony_ci indexExprType == INDEX_EXPR_DYNAMIC ? "int(v_index)" : DE_NULL; 117e5c31af7Sopenharmony_ci glu::ProgramSources sources; 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci DE_ASSERT(fragIndexExpr); 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci sources << glu::VertexSource( 122e5c31af7Sopenharmony_ci "attribute highp vec4 a_position;\n" 123e5c31af7Sopenharmony_ci "attribute highp float a_index;\n" 124e5c31af7Sopenharmony_ci "attribute highp vec4 a_color;\n" 125e5c31af7Sopenharmony_ci "varying mediump float v_index;\n" 126e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 127e5c31af7Sopenharmony_ci "void main (void)\n" 128e5c31af7Sopenharmony_ci "{\n" 129e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 130e5c31af7Sopenharmony_ci " v_color = a_color;\n" 131e5c31af7Sopenharmony_ci " v_index = a_index;\n" 132e5c31af7Sopenharmony_ci "}\n"); 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci sources << glu::FragmentSource(string( 135e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 136e5c31af7Sopenharmony_ci "varying mediump float v_index;\n" 137e5c31af7Sopenharmony_ci "uniform mediump int u_index;\n" 138e5c31af7Sopenharmony_ci "void main (void)\n" 139e5c31af7Sopenharmony_ci "{\n" 140e5c31af7Sopenharmony_ci " gl_FragData[") + fragIndexExpr + "] = v_color;\n" 141e5c31af7Sopenharmony_ci "}\n"); 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci return sources; 144e5c31af7Sopenharmony_ci } 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci IterateResult iterate (void) 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci const glu::RenderContext& renderCtx = m_context.getRenderContext(); 149e5c31af7Sopenharmony_ci const glw::Functions& gl = renderCtx.getFunctions(); 150e5c31af7Sopenharmony_ci const glu::ShaderProgram program (renderCtx, genSources(m_indexExprType)); 151e5c31af7Sopenharmony_ci const int viewportW = de::min(renderCtx.getRenderTarget().getWidth(), 128); 152e5c31af7Sopenharmony_ci const int viewportH = de::min(renderCtx.getRenderTarget().getHeight(), 128); 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci const float positions[] = 155e5c31af7Sopenharmony_ci { 156e5c31af7Sopenharmony_ci -1.0f, -1.0f, 157e5c31af7Sopenharmony_ci +1.0f, -1.0f, 158e5c31af7Sopenharmony_ci -1.0f, +1.0f, 159e5c31af7Sopenharmony_ci +1.0f, +1.0f 160e5c31af7Sopenharmony_ci }; 161e5c31af7Sopenharmony_ci const float colors[] = 162e5c31af7Sopenharmony_ci { 163e5c31af7Sopenharmony_ci 0.0f, 1.0f, 0.0f, 1.0f, 164e5c31af7Sopenharmony_ci 0.0f, 1.0f, 0.0f, 1.0f, 165e5c31af7Sopenharmony_ci 0.0f, 1.0f, 0.0f, 1.0f, 166e5c31af7Sopenharmony_ci 0.0f, 1.0f, 0.0f, 1.0f 167e5c31af7Sopenharmony_ci }; 168e5c31af7Sopenharmony_ci const float indexValues[] = { 0.0f, 0.0f, 0.0f, 0.0f }; 169e5c31af7Sopenharmony_ci const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 }; 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci const glu::VertexArrayBinding vertexArrays[] = 172e5c31af7Sopenharmony_ci { 173e5c31af7Sopenharmony_ci glu::va::Float("a_position", 2, 4, 0, &positions[0]), 174e5c31af7Sopenharmony_ci glu::va::Float("a_color", 4, 4, 0, &colors[0]), 175e5c31af7Sopenharmony_ci glu::va::Float("a_index", 1, 4, 0, &indexValues[0]) 176e5c31af7Sopenharmony_ci }; 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci m_testCtx.getLog() << program; 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci if (!program.isOk()) 181e5c31af7Sopenharmony_ci { 182e5c31af7Sopenharmony_ci if (m_indexExprType == INDEX_EXPR_STATIC) 183e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 184e5c31af7Sopenharmony_ci else 185e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Dynamic indexing of gl_FragData[] not supported"); 186e5c31af7Sopenharmony_ci } 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci gl.clearColor (1.0f, 0.0f, 0.0f, 1.0f); 189e5c31af7Sopenharmony_ci gl.clear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci gl.viewport (0, 0, viewportW, viewportH); 192e5c31af7Sopenharmony_ci gl.useProgram (program.getProgram()); 193e5c31af7Sopenharmony_ci gl.uniform1i (gl.getUniformLocation(program.getProgram(), "u_index"), 0); 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0], 196e5c31af7Sopenharmony_ci glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0])); 197e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed"); 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci { 200e5c31af7Sopenharmony_ci tcu::Surface result (viewportW, viewportH); 201e5c31af7Sopenharmony_ci const tcu::RGBA threshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1); 202e5c31af7Sopenharmony_ci bool isOk; 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci glu::readPixels(renderCtx, 0, 0, result.getAccess()); 205e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed"); 206e5c31af7Sopenharmony_ci 207e5c31af7Sopenharmony_ci isOk = compareSingleColor(m_testCtx.getLog(), result, tcu::RGBA::green(), threshold); 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 210e5c31af7Sopenharmony_ci isOk ? "Pass" : "Image comparison failed"); 211e5c31af7Sopenharmony_ci } 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci return STOP; 214e5c31af7Sopenharmony_ci } 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ciprivate: 217e5c31af7Sopenharmony_ci const IndexExprType m_indexExprType; 218e5c31af7Sopenharmony_ci}; 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_ci} // anonymous 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ciShaderFragDataTests::ShaderFragDataTests (Context& context) 223e5c31af7Sopenharmony_ci : TestCaseGroup(context, "fragdata", "gl_FragData[] Tests") 224e5c31af7Sopenharmony_ci{ 225e5c31af7Sopenharmony_ci} 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ciShaderFragDataTests::~ShaderFragDataTests (void) 228e5c31af7Sopenharmony_ci{ 229e5c31af7Sopenharmony_ci} 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_civoid ShaderFragDataTests::init (void) 232e5c31af7Sopenharmony_ci{ 233e5c31af7Sopenharmony_ci addChild(new FragDataIndexingCase(m_context, "valid_static_index", "Valid gl_FragData[] assignment using static index", INDEX_EXPR_STATIC)); 234e5c31af7Sopenharmony_ci addChild(new FragDataIndexingCase(m_context, "valid_uniform_index", "Valid gl_FragData[] assignment using uniform index", INDEX_EXPR_UNIFORM)); 235e5c31af7Sopenharmony_ci addChild(new FragDataIndexingCase(m_context, "valid_dynamic_index", "Valid gl_FragData[] assignment using dynamic index", INDEX_EXPR_DYNAMIC)); 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci // Negative cases. 238e5c31af7Sopenharmony_ci { 239e5c31af7Sopenharmony_ci gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo()); 240e5c31af7Sopenharmony_ci std::vector<tcu::TestNode*> negativeCases = library.loadShaderFile("shaders/fragdata.test"); 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci for (std::vector<tcu::TestNode*>::iterator i = negativeCases.begin(); i != negativeCases.end(); i++) 243e5c31af7Sopenharmony_ci addChild(*i); 244e5c31af7Sopenharmony_ci } 245e5c31af7Sopenharmony_ci} 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci} // Functional 248e5c31af7Sopenharmony_ci} // gles2 249e5c31af7Sopenharmony_ci} // deqp 250