148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/*------------------------------------------------------------------------- 248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * OpenGL Conformance Test Suite 348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * ----------------------------- 448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Copyright (c) 2016 Google Inc. 648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Copyright (c) 2016 The Khronos Group Inc. 748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License"); 948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * you may not use this file except in compliance with the License. 1048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * You may obtain a copy of the License at 1148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * http://www.apache.org/licenses/LICENSE-2.0 1348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Unless required by applicable law or agreed to in writing, software 1548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS, 1648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * See the License for the specific language governing permissions and 1848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * limitations under the License. 1948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 2084322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*! 2148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file 2248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief Compiler test case. 2384322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/ 2448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 2548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glcShaderLibraryCase.hpp" 2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 2748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuRenderTarget.hpp" 2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuTestLog.hpp" 2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluDrawUtil.hpp" 3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluPixelTransfer.hpp" 3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluShaderProgram.hpp" 3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuStringTemplate.hpp" 3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp" 3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp" 3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "deInt32.h" 3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "deMath.h" 4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "deRandom.hpp" 4148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "deString.h" 4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <map> 4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <sstream> 4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <string> 4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <vector> 4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 4848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing namespace std; 4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing namespace tcu; 5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing namespace glu; 5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace deqp 5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace sl 5548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosenum 5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos VIEWPORT_WIDTH = 128, 6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos VIEWPORT_HEIGHT = 128 6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic inline bool usesShaderInoutQualifiers(glu::GLSLVersion version) 6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (version) 6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case glu::GLSL_VERSION_100_ES: 6848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case glu::GLSL_VERSION_130: 6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case glu::GLSL_VERSION_140: 7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case glu::GLSL_VERSION_150: 7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos// ShaderCase. 7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 8048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosShaderCase::ShaderCase(tcu::TestContext& testCtx, RenderContext& renderCtx, const char* name, const char* description, 8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ExpectResult expectResult, const std::vector<ValueBlock>& valueBlocks, GLSLVersion targetVersion, 8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vertexSource, const char* fragmentSource) 8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : tcu::TestCase(testCtx, name, description) 8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_renderCtx(renderCtx) 8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_expectResult(expectResult) 8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_valueBlocks(valueBlocks) 8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_targetVersion(targetVersion) 8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // If no value blocks given, use an empty one. 9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_valueBlocks.size() == 0) 9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_valueBlocks.push_back(ValueBlock()); 9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Use first value block to specialize shaders. 9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ValueBlock& valueBlock = m_valueBlocks[0]; 9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // \todo [2010-04-01 petri] Check that all value blocks have matching values. 9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Generate specialized shader sources. 9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (vertexSource && fragmentSource) 10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_caseType = CASETYPE_COMPLETE; 10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos specializeShaders(vertexSource, fragmentSource, m_vertexSource, m_fragmentSource, valueBlock); 10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (vertexSource) 10548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_caseType = CASETYPE_VERTEX_ONLY; 10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertexSource = specializeVertexShader(vertexSource, valueBlock); 10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fragmentSource = genFragmentShader(valueBlock); 10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(fragmentSource); 11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_caseType = CASETYPE_FRAGMENT_ONLY; 11448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertexSource = genVertexShader(valueBlock); 11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fragmentSource = specializeFragmentShader(fragmentSource, valueBlock); 11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 11948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosShaderCase::~ShaderCase(void) 12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 12248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic void setUniformValue(const glw::Functions& gl, deUint32 programID, const std::string& name, 12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val, int arrayNdx) 12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int scalarSize = getDataTypeScalarSize(val.dataType); 12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int loc = gl.getUniformLocation(programID, name.c_str()); 12848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 12948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_CHECK_MSG(loc != -1, "uniform location not found"); 13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_STATIC_ASSERT(sizeof(ShaderCase::Value::Element) == sizeof(glw::GLfloat)); 13248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_STATIC_ASSERT(sizeof(ShaderCase::Value::Element) == sizeof(glw::GLint)); 13348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int elemNdx = (val.arrayLength == 1) ? 0 : (arrayNdx * scalarSize); 13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (val.dataType) 13748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 13848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT: 13948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform1fv(loc, 1, &val.elements[elemNdx].float32); 14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_VEC2: 14248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform2fv(loc, 1, &val.elements[elemNdx].float32); 14348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_VEC3: 14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform3fv(loc, 1, &val.elements[elemNdx].float32); 14648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 14748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_VEC4: 14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4fv(loc, 1, &val.elements[elemNdx].float32); 14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 15048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT2: 15148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT3: 15448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 15548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT4: 15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_INT: 16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform1iv(loc, 1, &val.elements[elemNdx].int32); 16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_INT_VEC2: 16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform2iv(loc, 1, &val.elements[elemNdx].int32); 16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_INT_VEC3: 16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform3iv(loc, 1, &val.elements[elemNdx].int32); 16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_INT_VEC4: 16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4iv(loc, 1, &val.elements[elemNdx].int32); 17048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 17148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_BOOL: 17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform1iv(loc, 1, &val.elements[elemNdx].int32); 17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_BOOL_VEC2: 17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform2iv(loc, 1, &val.elements[elemNdx].int32); 17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_BOOL_VEC3: 17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform3iv(loc, 1, &val.elements[elemNdx].int32); 17948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 18048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_BOOL_VEC4: 18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4iv(loc, 1, &val.elements[elemNdx].int32); 18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_UINT: 18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform1uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32); 18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_UINT_VEC2: 18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform2uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32); 18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_UINT_VEC3: 19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform3uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32); 19148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_UINT_VEC4: 19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32); 19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT2X3: 19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix2x3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT2X4: 19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix2x4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT3X2: 20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix3x2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT3X4: 20548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix3x4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 20648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 20748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT4X2: 20848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix4x2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 20948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 21048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_FLOAT_MAT4X3: 21148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformMatrix4x3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32); 21248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 21348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 21448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_SAMPLER_2D: 21548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TYPE_SAMPLER_CUBE: 21648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(DE_FALSE && "implement!"); 21748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 21848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 21948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 22048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(false); 22148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 22248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 22348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 22448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool ShaderCase::checkPixels(Surface& surface, int minX, int maxX, int minY, int maxY) 22548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 22648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TestLog& log = m_testCtx.getLog(); 22748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool allWhite = true; 22848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool allBlack = true; 22948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool anyUnexpected = false; 23048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 23148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT((maxX > minX) && (maxY > minY)); 23248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 23348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = minY; y <= maxY; y++) 23448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 23548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = minX; x <= maxX; x++) 23648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 23748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos RGBA pixel = surface.getPixel(x, y); 23848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Note: we really do not want to involve alpha in the check comparison 23948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // \todo [2010-09-22 kalle] Do we know that alpha would be one? If yes, could use color constants white and black. 24048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool isWhite = (pixel.getRed() == 255) && (pixel.getGreen() == 255) && (pixel.getBlue() == 255); 24148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool isBlack = (pixel.getRed() == 0) && (pixel.getGreen() == 0) && (pixel.getBlue() == 0); 24248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 24348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos allWhite = allWhite && isWhite; 24448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos allBlack = allBlack && isBlack; 24548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos anyUnexpected = anyUnexpected || (!isWhite && !isBlack); 24648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 24748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 24848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 24948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!allWhite) 25048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 25148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (anyUnexpected) 25248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << TestLog::Message 25348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "WARNING: expecting all rendered pixels to be white or black, but got other colors as well!" 25448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << TestLog::EndMessage; 25548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (!allBlack) 25648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << TestLog::Message 25748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "WARNING: got inconsistent results over the image, when all pixels should be the same color!" 25848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << TestLog::EndMessage; 25948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 26148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 26248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 26348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 26448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool ShaderCase::execute(void) 26648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 26748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TestLog& log = m_testCtx.getLog(); 26848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_renderCtx.getFunctions(); 26948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 27048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Compute viewport. 27148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const tcu::RenderTarget& renderTarget = m_renderCtx.getRenderTarget(); 27248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::Random rnd(deStringHash(getName())); 27348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int width = deMin32(renderTarget.getWidth(), VIEWPORT_WIDTH); 27448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int height = deMin32(renderTarget.getHeight(), VIEWPORT_HEIGHT); 27548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int viewportX = rnd.getInt(0, renderTarget.getWidth() - width); 27648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int viewportY = rnd.getInt(0, renderTarget.getHeight() - height); 27748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int numVerticesPerDraw = 4; 27848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 27948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderCase::execute(): start"); 28048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Setup viewport. 28248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.viewport(viewportX, viewportY, width, height); 28348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float quadSize = 1.0f; 28548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const float s_positions[4 * 4] = { -quadSize, -quadSize, 0.0f, 1.0f, -quadSize, +quadSize, 0.0f, 1.0f, 28648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos +quadSize, -quadSize, 0.0f, 1.0f, +quadSize, +quadSize, 0.0f, 1.0f }; 28748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const deUint16 s_indices[2 * 3] = { 0, 1, 2, 1, 3, 2 }; 28948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 29048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Setup program. 29148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glu::ShaderProgram program(m_renderCtx, glu::makeVtxFragSources(m_vertexSource.c_str(), m_fragmentSource.c_str())); 29248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 29348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Check that compile/link results are what we expect. 29448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool vertexOk = program.getShaderInfo(SHADERTYPE_VERTEX).compileOk; 29548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool fragmentOk = program.getShaderInfo(SHADERTYPE_FRAGMENT).compileOk; 29648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool linkOk = program.getProgramInfo().linkOk; 29748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* failReason = DE_NULL; 29848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 29948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << program; 30048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (m_expectResult) 30248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 30348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case EXPECT_PASS: 30448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!vertexOk || !fragmentOk) 30548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos failReason = "expected shaders to compile and link properly, but failed to compile."; 30648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (!linkOk) 30748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos failReason = "expected shaders to compile and link properly, but failed to link."; 30848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 30948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case EXPECT_COMPILE_FAIL: 31148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (vertexOk && fragmentOk && !linkOk) 31248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos failReason = "expected compilation to fail, but both shaders compiled and link failed."; 31348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (vertexOk && fragmentOk) 31448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos failReason = "expected compilation to fail, but both shaders compiled correctly."; 31548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 31648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case EXPECT_LINK_FAIL: 31848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!vertexOk || !fragmentOk) 31948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos failReason = "expected linking to fail, but unable to compile."; 32048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (linkOk) 32148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos failReason = "expected linking to fail, but passed."; 32248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 32348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 32548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(false); 32648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 32748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 32848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (failReason != DE_NULL) 33048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 33148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // \todo [2010-06-07 petri] These should be handled in the test case? 33248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << TestLog::Message << "ERROR: " << failReason << TestLog::EndMessage; 33348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 33448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // If implementation parses shader at link time, report it as quality warning. 33548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_expectResult == EXPECT_COMPILE_FAIL && vertexOk && fragmentOk && !linkOk) 33648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, failReason); 33748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 33848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failReason); 33948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 34048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 34148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Return if compile/link expected to fail. 34348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_expectResult != EXPECT_PASS) 34448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return (failReason == DE_NULL); 34548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Start using program. 34748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deUint32 programID = program.getProgram(); 34848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(programID); 34948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()"); 35048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Fetch location for positions positions. 35248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int positionLoc = gl.getAttribLocation(programID, "dEQP_Position"); 35348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (positionLoc == -1) 35448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 35548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string errStr = string("no location found for attribute 'dEQP_Position'"); 35648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL(errStr.c_str()); 35748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 35848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Iterate all value blocks. 36048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int blockNdx = 0; blockNdx < (int)m_valueBlocks.size(); blockNdx++) 36148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 36248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ValueBlock& valueBlock = m_valueBlocks[blockNdx]; 36348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Iterate all array sub-cases. 36548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int arrayNdx = 0; arrayNdx < valueBlock.arrayLength; arrayNdx++) 36648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 36748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int numValues = (int)valueBlock.values.size(); 36848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vector<VertexArrayBinding> vertexArrays; 36948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 37048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int attribValueNdx = 0; 37148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vector<vector<float> > attribValues(numValues); 37248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 37348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vertexArrays.push_back(va::Float(positionLoc, 4, numVerticesPerDraw, 0, &s_positions[0])); 37448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 37548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Collect VA pointer for inputs and set uniform values for outputs (refs). 37648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int valNdx = 0; valNdx < numValues; valNdx++) 37748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 37848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[valNdx]; 37948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* valueName = val.valueName.c_str(); 38048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DataType dataType = val.dataType; 38148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int scalarSize = getDataTypeScalarSize(val.dataType); 38248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "before set uniforms"); 38448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_INPUT) 38648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 38748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Replicate values four times. 38848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<float>& scalars = attribValues[attribValueNdx++]; 38948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos scalars.resize(numVerticesPerDraw * scalarSize); 39048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isDataTypeFloatOrVec(dataType) || isDataTypeMatrix(dataType)) 39148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 39248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int repNdx = 0; repNdx < numVerticesPerDraw; repNdx++) 39348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < scalarSize; ndx++) 39448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos scalars[repNdx * scalarSize + ndx] = val.elements[arrayNdx * scalarSize + ndx].float32; 39548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 39648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 39748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 39848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // convert to floats. 39948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int repNdx = 0; repNdx < numVerticesPerDraw; repNdx++) 40048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 40148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < scalarSize; ndx++) 40248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 40348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float v = (float)val.elements[arrayNdx * scalarSize + ndx].int32; 40448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(val.elements[arrayNdx * scalarSize + ndx].int32 == (int)v); 40548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos scalars[repNdx * scalarSize + ndx] = v; 40648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 40748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 40848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 40948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 41048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Attribute name prefix. 41148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string attribPrefix = ""; 41248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // \todo [2010-05-27 petri] Should latter condition only apply for vertex cases (or actually non-fragment cases)? 41348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ((m_caseType == CASETYPE_FRAGMENT_ONLY) || (getDataTypeScalarType(dataType) != TYPE_FLOAT)) 41448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos attribPrefix = "a_"; 41548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 41648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Input always given as attribute. 41748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string attribName = attribPrefix + valueName; 41848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int attribLoc = gl.getAttribLocation(programID, attribName.c_str()); 41948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (attribLoc == -1) 42048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 42148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << TestLog::Message << "Warning: no location found for attribute '" << attribName << "'" 42248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << TestLog::EndMessage; 42348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos continue; 42448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 42548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 42648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isDataTypeMatrix(dataType)) 42748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 42848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int numCols = getDataTypeMatrixNumColumns(dataType); 42948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int numRows = getDataTypeMatrixNumRows(dataType); 43048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(scalarSize == numCols * numRows); 43148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 43248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < numCols; i++) 43348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vertexArrays.push_back(va::Float(attribLoc + i, numRows, numVerticesPerDraw, 43448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static_cast<int>(scalarSize * sizeof(float)), 43548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &scalars[i * numRows])); 43648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 43748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 43848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 43948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(isDataTypeFloatOrVec(dataType) || isDataTypeIntOrIVec(dataType) || 44048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos isDataTypeUintOrUVec(dataType) || isDataTypeBoolOrBVec(dataType)); 44148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vertexArrays.push_back(va::Float(attribLoc, scalarSize, numVerticesPerDraw, 0, &scalars[0])); 44248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 44348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 44448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "set vertex attrib array"); 44548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 44648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT) 44748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 44848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Set reference value. 44948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string refName = string("ref_") + valueName; 45048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos setUniformValue(gl, programID, refName, val, arrayNdx); 45148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "set reference uniforms"); 45248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 45348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 45448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 45548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(val.storageType == ShaderCase::Value::STORAGE_UNIFORM); 45648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos setUniformValue(gl, programID, valueName, val, arrayNdx); 45748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "set uniforms"); 45848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 45948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 46048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Clear. 46248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 46348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.clear(GL_COLOR_BUFFER_BIT); 46448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "clear buffer"); 46548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Draw. 46748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos draw(m_renderCtx, program.getProgram(), (int)vertexArrays.size(), &vertexArrays[0], 46848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0])); 46948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "draw"); 47048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Read back results. 47248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Surface surface(width, height); 47348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glu::readPixels(m_renderCtx, viewportX, viewportY, surface.getAccess()); 47448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels"); 47548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float w = s_positions[3]; 47748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int minY = deCeilFloatToInt32(((-quadSize / w) * 0.5f + 0.5f) * (float)height + 1.0f); 47848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int maxY = deFloorFloatToInt32(((+quadSize / w) * 0.5f + 0.5f) * (float)height - 0.5f); 47948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int minX = deCeilFloatToInt32(((-quadSize / w) * 0.5f + 0.5f) * (float)width + 1.0f); 48048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int maxX = deFloorFloatToInt32(((+quadSize / w) * 0.5f + 0.5f) * (float)width - 0.5f); 48148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!checkPixels(surface, minX, maxX, minY, maxY)) 48348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 48448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << TestLog::Message << "INCORRECT RESULT for (value block " << (blockNdx + 1) << " of " 48548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << (int)m_valueBlocks.size() << ", sub-case " << arrayNdx + 1 << " of " << valueBlock.arrayLength 48648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "):" << TestLog::EndMessage; 48748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << TestLog::Message << "Failing shader input/output values:" << TestLog::EndMessage; 48948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos dumpValues(valueBlock, arrayNdx); 49048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 49148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Dump image on failure. 49248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos log << TestLog::Image("Result", "Rendered result image", surface); 49348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 49448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 49548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 49648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 49748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 49848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 49948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 50048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 50248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderCase::execute(): end"); 50348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 50448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 50548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosTestCase::IterateResult ShaderCase::iterate(void) 50748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 50848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Initialize state to pass. 50948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 51048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool executeOk = execute(); 51248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(executeOk ? m_testCtx.getTestResult() == QP_TEST_RESULT_PASS : 51448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getTestResult() != QP_TEST_RESULT_PASS); 51548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (void)executeOk; 51648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return TestCase::STOP; 51748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 51848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos// This functions builds a matching vertex shader for a 'both' case, when 52048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos// the fragment shader is being tested. 52148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos// We need to build attributes and varyings for each 'input'. 52248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstring ShaderCase::genVertexShader(const ValueBlock& valueBlock) 52348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 52448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream res; 52548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool usesInout = usesShaderInoutQualifiers(m_targetVersion); 52648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vtxIn = usesInout ? "in" : "attribute"; 52748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vtxOut = usesInout ? "out" : "varying"; 52848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << glu::getGLSLVersionDeclaration(m_targetVersion) << "\n"; 53048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 53148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Declarations (position + attribute/varying for each input). 53248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << "precision highp float;\n"; 53348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << "precision highp int;\n"; 53448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << "\n"; 53548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << vtxIn << " highp vec4 dEQP_Position;\n"; 53648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 53748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 53848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 53948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_INPUT) 54048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 54148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DataType floatType = getDataTypeFloatScalars(val.dataType); 54248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* typeStr = getDataTypeName(floatType); 54348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << vtxIn << " " << typeStr << " a_" << val.valueName << ";\n"; 54448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 54548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 54648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << vtxOut << " " << typeStr << " " << val.valueName << ";\n"; 54748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 54848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << vtxOut << " " << typeStr << " v_" << val.valueName << ";\n"; 54948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 55048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 55148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << "\n"; 55248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 55348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Main function. 55448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // - gl_Position = dEQP_Position; 55548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // - for each input: write attribute directly to varying 55648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << "void main()\n"; 55748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << "{\n"; 55848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << " gl_Position = dEQP_Position;\n"; 55948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 56048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 56148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 56248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_INPUT) 56348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 56448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const string& name = val.valueName; 56548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 56648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << " " << name << " = a_" << name << ";\n"; 56748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 56848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << " v_" << name << " = a_" << name << ";\n"; 56948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 57048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 57148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res << "}\n"; 57348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return res.str(); 57448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 57548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic void genCompareFunctions(ostringstream& stream, const ShaderCase::ValueBlock& valueBlock, bool useFloatTypes) 57748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 57848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool cmpTypeFound[TYPE_LAST]; 57948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < TYPE_LAST; i++) 58048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos cmpTypeFound[i] = false; 58148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int valueNdx = 0; valueNdx < (int)valueBlock.values.size(); valueNdx++) 58348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 58448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[valueNdx]; 58548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT) 58648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos cmpTypeFound[(int)val.dataType] = true; 58748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 58848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (useFloatTypes) 59048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 59148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL]) 59248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (float a, bool b) { return ((a > 0.5) == b); }\n"; 59348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL_VEC2]) 59448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec2 a, bvec2 b) { return (greaterThan(a, vec2(0.5)) == b); }\n"; 59548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL_VEC3]) 59648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec3 a, bvec3 b) { return (greaterThan(a, vec3(0.5)) == b); }\n"; 59748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL_VEC4]) 59848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec4 a, bvec4 b) { return (greaterThan(a, vec4(0.5)) == b); }\n"; 59948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT]) 60048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (float a, int b) { float atemp = a+0.5; return (float(b) <= atemp && atemp <= " 60148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "float(b+1)); }\n"; 60248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT_VEC2]) 60348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec2 a, ivec2 b) { return (ivec2(floor(a + 0.5)) == b); }\n"; 60448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT_VEC3]) 60548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec3 a, ivec3 b) { return (ivec3(floor(a + 0.5)) == b); }\n"; 60648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT_VEC4]) 60748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec4 a, ivec4 b) { return (ivec4(floor(a + 0.5)) == b); }\n"; 60848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT]) 60948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (float a, uint b) { float atemp = a+0.5; return (float(b) <= atemp && atemp <= " 61048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "float(b+1)); }\n"; 61148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT_VEC2]) 61248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec2 a, uvec2 b) { return (uvec2(floor(a + 0.5)) == b); }\n"; 61348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT_VEC3]) 61448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec3 a, uvec3 b) { return (uvec3(floor(a + 0.5)) == b); }\n"; 61548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT_VEC4]) 61648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (vec4 a, uvec4 b) { return (uvec4(floor(a + 0.5)) == b); }\n"; 61748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 61848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 61948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 62048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL]) 62148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (bool a, bool b) { return (a == b); }\n"; 62248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL_VEC2]) 62348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (bvec2 a, bvec2 b) { return (a == b); }\n"; 62448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL_VEC3]) 62548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (bvec3 a, bvec3 b) { return (a == b); }\n"; 62648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_BOOL_VEC4]) 62748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (bvec4 a, bvec4 b) { return (a == b); }\n"; 62848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT]) 62948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (int a, int b) { return (a == b); }\n"; 63048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT_VEC2]) 63148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (ivec2 a, ivec2 b) { return (a == b); }\n"; 63248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT_VEC3]) 63348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (ivec3 a, ivec3 b) { return (a == b); }\n"; 63448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_INT_VEC4]) 63548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (ivec4 a, ivec4 b) { return (a == b); }\n"; 63648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT]) 63748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (uint a, uint b) { return (a == b); }\n"; 63848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT_VEC2]) 63948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (uvec2 a, uvec2 b) { return (a == b); }\n"; 64048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT_VEC3]) 64148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (uvec3 a, uvec3 b) { return (a == b); }\n"; 64248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_UINT_VEC4]) 64348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (uvec4 a, uvec4 b) { return (a == b); }\n"; 64448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 64548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 64648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT]) 64748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (float a, float b, float eps) { return (abs(a-b) <= (eps*abs(b) + eps)); }\n"; 64848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_VEC2]) 64948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream 65048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "bool isOk (vec2 a, vec2 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n"; 65148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_VEC3]) 65248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream 65348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "bool isOk (vec3 a, vec3 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n"; 65448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_VEC4]) 65548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream 65648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "bool isOk (vec4 a, vec4 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n"; 65748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 65848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT2]) 65948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat2 a, mat2 b, float eps) { vec2 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return " 66048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "all(lessThanEqual(diff, vec2(eps))); }\n"; 66148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT2X3]) 66248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat2x3 a, mat2x3 b, float eps) { vec3 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return " 66348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "all(lessThanEqual(diff, vec3(eps))); }\n"; 66448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT2X4]) 66548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat2x4 a, mat2x4 b, float eps) { vec4 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return " 66648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "all(lessThanEqual(diff, vec4(eps))); }\n"; 66748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT3X2]) 66848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat3x2 a, mat3x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), " 66948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec2(eps))); }\n"; 67048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT3]) 67148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat3 a, mat3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), " 67248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec3(eps))); }\n"; 67348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT3X4]) 67448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat3x4 a, mat3x4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), " 67548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec4(eps))); }\n"; 67648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT4X2]) 67748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat4x2 a, mat4x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), " 67848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec2(eps))); }\n"; 67948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT4X3]) 68048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat4x3 a, mat4x3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), " 68148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec3(eps))); }\n"; 68248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (cmpTypeFound[TYPE_FLOAT_MAT4]) 68348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stream << "bool isOk (mat4 a, mat4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), " 68448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec4(eps))); }\n"; 68548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 68648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 68748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic void genCompareOp(ostringstream& output, const char* dstVec4Var, const ShaderCase::ValueBlock& valueBlock, 68848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* nonFloatNamePrefix, const char* checkVarName) 68948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 69048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool isFirstOutput = true; 69148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 69248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 69348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 69448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 69548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* valueName = val.valueName.c_str(); 69648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 69748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT) 69848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 69948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Check if we're only interested in one variable (then skip if not the right one). 70048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (checkVarName && !deStringEqual(valueName, checkVarName)) 70148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos continue; 70248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 70348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Prefix. 70448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isFirstOutput) 70548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 70648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << "bool RES = "; 70748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos isFirstOutput = false; 70848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 70948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 71048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << "RES = RES && "; 71148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 71248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Generate actual comparison. 71348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 71448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << "isOk(" << valueName << ", ref_" << valueName << ", 0.05);\n"; 71548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 71648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << "isOk(" << nonFloatNamePrefix << valueName << ", ref_" << valueName << ");\n"; 71748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 71848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // \note Uniforms are already declared in shader. 71948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 72048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 72148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isFirstOutput) 72248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << dstVec4Var << " = vec4(1.0);\n"; // \todo [petri] Should we give warning if not expect-failure case? 72348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 72448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << dstVec4Var << " = vec4(RES, RES, RES, 1.0);\n"; 72548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 72648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 72748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstring ShaderCase::genFragmentShader(const ValueBlock& valueBlock) 72848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 72948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream shader; 73048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool usesInout = usesShaderInoutQualifiers(m_targetVersion); 73148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool customColorOut = usesInout; 73248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* fragIn = usesInout ? "in" : "varying"; 73348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 73448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << glu::getGLSLVersionDeclaration(m_targetVersion) << "\n"; 73548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 73648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "precision mediump float;\n"; 73748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "precision mediump int;\n"; 73848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "\n"; 73948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 74048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (customColorOut) 74148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 74248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 74348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "\n"; 74448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 74548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 74648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos genCompareFunctions(shader, valueBlock, true); 74748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "\n"; 74848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 74948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Declarations (varying, reference for each output). 75048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 75148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 75248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 75348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DataType floatType = getDataTypeFloatScalars(val.dataType); 75448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* floatTypeStr = getDataTypeName(floatType); 75548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* refTypeStr = getDataTypeName(val.dataType); 75648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 75748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT) 75848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 75948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 76048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << fragIn << " " << floatTypeStr << " " << val.valueName << ";\n"; 76148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 76248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << fragIn << " " << floatTypeStr << " v_" << val.valueName << ";\n"; 76348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 76448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "uniform " << refTypeStr << " ref_" << val.valueName << ";\n"; 76548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 76648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 76748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 76848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "\n"; 76948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "void main()\n"; 77048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "{\n"; 77148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 77248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << " "; 77348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos genCompareOp(shader, customColorOut ? "dEQP_FragColor" : "gl_FragColor", valueBlock, "v_", DE_NULL); 77448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 77548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader << "}\n"; 77648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return shader.str(); 77748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 77848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 77948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos// Specialize a shader for the vertex shader test case. 78048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstring ShaderCase::specializeVertexShader(const char* src, const ValueBlock& valueBlock) 78148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 78248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream decl; 78348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream setup; 78448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream output; 78548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool usesInout = usesShaderInoutQualifiers(m_targetVersion); 78648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vtxIn = usesInout ? "in" : "attribute"; 78748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vtxOut = usesInout ? "out" : "varying"; 78848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 78948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Output (write out position). 79048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << "gl_Position = dEQP_Position;\n"; 79148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 79248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Declarations (position + attribute for each input, varying for each output). 79348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxIn << " highp vec4 dEQP_Position;\n"; 79448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 79548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 79648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 79748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* valueName = val.valueName.c_str(); 79848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DataType floatType = getDataTypeFloatScalars(val.dataType); 79948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* floatTypeStr = getDataTypeName(floatType); 80048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* refTypeStr = getDataTypeName(val.dataType); 80148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 80248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_INPUT) 80348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 80448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 80548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 80648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxIn << " " << floatTypeStr << " " << valueName << ";\n"; 80748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 80848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 80948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 81048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxIn << " " << floatTypeStr << " a_" << valueName << ";\n"; 81148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos setup << refTypeStr << " " << valueName << " = " << refTypeStr << "(a_" << valueName << ");\n"; 81248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 81348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 81448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT) 81548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 81648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 81748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxOut << " " << floatTypeStr << " " << valueName << ";\n"; 81848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 81948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 82048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxOut << " " << floatTypeStr << " v_" << valueName << ";\n"; 82148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << refTypeStr << " " << valueName << ";\n"; 82248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 82348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos output << "v_" << valueName << " = " << floatTypeStr << "(" << valueName << ");\n"; 82448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 82548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 82648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 82748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 82848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Shader specialization. 82948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos map<string, string> params; 83048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("DECLARATIONS", decl.str())); 83148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("SETUP", setup.str())); 83248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("OUTPUT", output.str())); 83348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("POSITION_FRAG_COLOR", "gl_Position")); 83448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos StringTemplate tmpl(src); 83648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tmpl.specialize(params); 83748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 83848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos// Specialize a shader for the fragment shader test case. 84048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstring ShaderCase::specializeFragmentShader(const char* src, const ValueBlock& valueBlock) 84148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 84248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream decl; 84348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream setup; 84448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream output; 84548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 84648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool usesInout = usesShaderInoutQualifiers(m_targetVersion); 84748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool customColorOut = usesInout; 84848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* fragIn = usesInout ? "in" : "varying"; 84948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* fragColor = customColorOut ? "dEQP_FragColor" : "gl_FragColor"; 85048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 85148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos genCompareFunctions(decl, valueBlock, false); 85248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos genCompareOp(output, fragColor, valueBlock, "", DE_NULL); 85348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 85448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (customColorOut) 85548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 85648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 85748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 85848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 85948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 86048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* valueName = val.valueName.c_str(); 86148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DataType floatType = getDataTypeFloatScalars(val.dataType); 86248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* floatTypeStr = getDataTypeName(floatType); 86348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* refTypeStr = getDataTypeName(val.dataType); 86448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 86548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_INPUT) 86648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 86748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 86848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << fragIn << " " << floatTypeStr << " " << valueName << ";\n"; 86948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 87048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 87148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << fragIn << " " << floatTypeStr << " v_" << valueName << ";\n"; 87248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string offset = 87348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos isDataTypeIntOrIVec(val.dataType) ? 87448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " * 1.0025" : 87548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ""; // \todo [petri] bit of a hack to avoid errors in chop() due to varying interpolation 87648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos setup << refTypeStr << " " << valueName << " = " << refTypeStr << "(v_" << valueName << offset 87748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");\n"; 87848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 87948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 88048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT) 88148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 88248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << "uniform " << refTypeStr << " ref_" << valueName << ";\n"; 88348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << refTypeStr << " " << valueName << ";\n"; 88448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 88548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 88648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 88748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* \todo [2010-04-01 petri] Check all outputs. */ 88848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 88948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Shader specialization. 89048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos map<string, string> params; 89148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("DECLARATIONS", decl.str())); 89248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("SETUP", setup.str())); 89348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("OUTPUT", output.str())); 89448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("POSITION_FRAG_COLOR", fragColor)); 89548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 89648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos StringTemplate tmpl(src); 89748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tmpl.specialize(params); 89848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 89948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 90048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid ShaderCase::specializeShaders(const char* vertexSource, const char* fragmentSource, string& outVertexSource, 90148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string& outFragmentSource, const ValueBlock& valueBlock) 90248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 90348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool usesInout = usesShaderInoutQualifiers(m_targetVersion); 90448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const bool customColorOut = usesInout; 90548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 90648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Vertex shader specialization. 90748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 90848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream decl; 90948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream setup; 91048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vtxIn = usesInout ? "in" : "attribute"; 91148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 91248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxIn << " highp vec4 dEQP_Position;\n"; 91348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 91448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 91548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 91648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 91748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* typeStr = getDataTypeName(val.dataType); 91848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 91948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_INPUT) 92048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 92148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT) 92248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 92348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxIn << " " << typeStr << " " << val.valueName << ";\n"; 92448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 92548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 92648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 92748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DataType floatType = getDataTypeFloatScalars(val.dataType); 92848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* floatTypeStr = getDataTypeName(floatType); 92948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 93048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << vtxIn << " " << floatTypeStr << " a_" << val.valueName << ";\n"; 93148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos setup << typeStr << " " << val.valueName << " = " << typeStr << "(a_" << val.valueName << ");\n"; 93248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 93348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 93448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (val.storageType == ShaderCase::Value::STORAGE_UNIFORM && val.valueName.find('.') == string::npos) 93548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 93648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << "uniform " << typeStr << " " << val.valueName << ";\n"; 93748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 93848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 93948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 94048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos map<string, string> params; 94148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("VERTEX_DECLARATIONS", decl.str())); 94248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("VERTEX_SETUP", setup.str())); 94348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("VERTEX_OUTPUT", string("gl_Position = dEQP_Position;\n"))); 94448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos StringTemplate tmpl(vertexSource); 94548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos outVertexSource = tmpl.specialize(params); 94648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 94748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 94848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // Fragment shader specialization. 94948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 95048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream decl; 95148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream output; 95248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* fragColor = customColorOut ? "dEQP_FragColor" : "gl_FragColor"; 95348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 95448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos genCompareFunctions(decl, valueBlock, false); 95548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos genCompareOp(output, fragColor, valueBlock, "", DE_NULL); 95648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 95748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (customColorOut) 95848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 95948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 96048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++) 96148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 96248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[ndx]; 96348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* valueName = val.valueName.c_str(); 96448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* refTypeStr = getDataTypeName(val.dataType); 96548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 96648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT) 96748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 96848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << "uniform " << refTypeStr << " ref_" << valueName << ";\n"; 96948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << refTypeStr << " " << valueName << ";\n"; 97048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 97148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (val.storageType == ShaderCase::Value::STORAGE_UNIFORM && val.valueName.find('.') == string::npos) 97248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 97348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos decl << "uniform " << refTypeStr << " " << valueName << ";\n"; 97448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 97548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 97648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 97748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos map<string, string> params; 97848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("FRAGMENT_DECLARATIONS", decl.str())); 97948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("FRAGMENT_OUTPUT", output.str())); 98048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos params.insert(pair<string, string>("FRAG_COLOR", fragColor)); 98148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos StringTemplate tmpl(fragmentSource); 98248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos outFragmentSource = tmpl.specialize(params); 98348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 98448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 98548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 98648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid ShaderCase::dumpValues(const ValueBlock& valueBlock, int arrayNdx) 98748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 98848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vector<vector<float> > attribValues; 98948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 99048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int numValues = (int)valueBlock.values.size(); 99148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int valNdx = 0; valNdx < numValues; valNdx++) 99248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 99348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ShaderCase::Value& val = valueBlock.values[valNdx]; 99448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* valueName = val.valueName.c_str(); 99548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DataType dataType = val.dataType; 99648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int scalarSize = getDataTypeScalarSize(val.dataType); 99748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ostringstream result; 99848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 99948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << " "; 100048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (val.storageType == Value::STORAGE_INPUT) 100148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "input "; 100248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (val.storageType == Value::STORAGE_UNIFORM) 100348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "uniform "; 100448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (val.storageType == Value::STORAGE_OUTPUT) 100548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "expected "; 100648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 100748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << getDataTypeName(dataType) << " " << valueName << ":"; 100848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 100948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isDataTypeScalar(dataType)) 101048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << " "; 101148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isDataTypeVector(dataType)) 101248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << " [ "; 101348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (isDataTypeMatrix(dataType)) 101448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "\n"; 101548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 101648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isDataTypeScalarOrVector(dataType)) 101748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 101848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 101948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 102048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int elemNdx = (val.arrayLength == 1) ? 0 : arrayNdx; 102148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Value::Element& e = val.elements[elemNdx * scalarSize + scalarNdx]; 102248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << ((scalarNdx != 0) ? ", " : ""); 102348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 102448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isDataTypeFloatOrVec(dataType)) 102548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << e.float32; 102648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (isDataTypeIntOrIVec(dataType)) 102748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << e.int32; 102848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (isDataTypeBoolOrBVec(dataType)) 102948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << (e.bool32 ? "true" : "false"); 103048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 103148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 103248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (isDataTypeMatrix(dataType)) 103348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 103448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int numRows = getDataTypeMatrixNumRows(dataType); 103548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int numCols = getDataTypeMatrixNumColumns(dataType); 103648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int rowNdx = 0; rowNdx < numRows; rowNdx++) 103748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 103848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << " [ "; 103948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int colNdx = 0; colNdx < numCols; colNdx++) 104048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 104148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int elemNdx = (val.arrayLength == 1) ? 0 : arrayNdx; 104248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float v = val.elements[elemNdx * scalarSize + rowNdx * numCols + colNdx].float32; 104348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << ((colNdx == 0) ? "" : ", ") << v; 104448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 104548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << " ]\n"; 104648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 104748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 104848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 104948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (isDataTypeScalar(dataType)) 105048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "\n"; 105148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (isDataTypeVector(dataType)) 105248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << " ]\n"; 105348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 105448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << TestLog::Message << result.str() << TestLog::EndMessage; 105548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 105648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 105748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 105848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // sl 105948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // deqp 1060