1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) Module 3e5c31af7Sopenharmony_ci * ----------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Draw tests 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "glsDrawTest.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "deRandom.h" 27e5c31af7Sopenharmony_ci#include "deRandom.hpp" 28e5c31af7Sopenharmony_ci#include "deMath.h" 29e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 30e5c31af7Sopenharmony_ci#include "deFloat16.h" 31e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp" 32e5c31af7Sopenharmony_ci#include "deArrayUtil.hpp" 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 35e5c31af7Sopenharmony_ci#include "tcuPixelFormat.hpp" 36e5c31af7Sopenharmony_ci#include "tcuRGBA.hpp" 37e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 38e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 39e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 40e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 41e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 42e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 43e5c31af7Sopenharmony_ci#include "tcuFloat.hpp" 44e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 47e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 48e5c31af7Sopenharmony_ci#include "gluCallLogWrapper.hpp" 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ci#include "sglrContext.hpp" 51e5c31af7Sopenharmony_ci#include "sglrReferenceContext.hpp" 52e5c31af7Sopenharmony_ci#include "sglrGLContext.hpp" 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_ci#include "rrGenericVector.hpp" 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ci#include <cstring> 57e5c31af7Sopenharmony_ci#include <cmath> 58e5c31af7Sopenharmony_ci#include <vector> 59e5c31af7Sopenharmony_ci#include <sstream> 60e5c31af7Sopenharmony_ci#include <limits> 61e5c31af7Sopenharmony_ci#include <cstdint> 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci#include "glwDefs.hpp" 64e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_cinamespace deqp 67e5c31af7Sopenharmony_ci{ 68e5c31af7Sopenharmony_cinamespace gls 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_cinamespace 71e5c31af7Sopenharmony_ci{ 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ciusing tcu::TestLog; 74e5c31af7Sopenharmony_ciusing namespace glw; // GL types 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ciconst int MAX_RENDER_TARGET_SIZE = 512; 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci// Utils 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_cistatic GLenum targetToGL (DrawTestSpec::Target target) 81e5c31af7Sopenharmony_ci{ 82e5c31af7Sopenharmony_ci static const GLenum targets[] = 83e5c31af7Sopenharmony_ci { 84e5c31af7Sopenharmony_ci GL_ELEMENT_ARRAY_BUFFER, // TARGET_ELEMENT_ARRAY = 0, 85e5c31af7Sopenharmony_ci GL_ARRAY_BUFFER // TARGET_ARRAY, 86e5c31af7Sopenharmony_ci }; 87e5c31af7Sopenharmony_ci 88e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target); 89e5c31af7Sopenharmony_ci} 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_cistatic GLenum usageToGL (DrawTestSpec::Usage usage) 92e5c31af7Sopenharmony_ci{ 93e5c31af7Sopenharmony_ci static const GLenum usages[] = 94e5c31af7Sopenharmony_ci { 95e5c31af7Sopenharmony_ci GL_DYNAMIC_DRAW, // USAGE_DYNAMIC_DRAW = 0, 96e5c31af7Sopenharmony_ci GL_STATIC_DRAW, // USAGE_STATIC_DRAW, 97e5c31af7Sopenharmony_ci GL_STREAM_DRAW, // USAGE_STREAM_DRAW, 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci GL_STREAM_READ, // USAGE_STREAM_READ, 100e5c31af7Sopenharmony_ci GL_STREAM_COPY, // USAGE_STREAM_COPY, 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci GL_STATIC_READ, // USAGE_STATIC_READ, 103e5c31af7Sopenharmony_ci GL_STATIC_COPY, // USAGE_STATIC_COPY, 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ci GL_DYNAMIC_READ, // USAGE_DYNAMIC_READ, 106e5c31af7Sopenharmony_ci GL_DYNAMIC_COPY // USAGE_DYNAMIC_COPY, 107e5c31af7Sopenharmony_ci }; 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage); 110e5c31af7Sopenharmony_ci} 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_cistatic GLenum inputTypeToGL (DrawTestSpec::InputType type) 113e5c31af7Sopenharmony_ci{ 114e5c31af7Sopenharmony_ci static const GLenum types[] = 115e5c31af7Sopenharmony_ci { 116e5c31af7Sopenharmony_ci GL_FLOAT, // INPUTTYPE_FLOAT = 0, 117e5c31af7Sopenharmony_ci GL_FIXED, // INPUTTYPE_FIXED, 118e5c31af7Sopenharmony_ci GL_DOUBLE, // INPUTTYPE_DOUBLE 119e5c31af7Sopenharmony_ci GL_BYTE, // INPUTTYPE_BYTE, 120e5c31af7Sopenharmony_ci GL_SHORT, // INPUTTYPE_SHORT, 121e5c31af7Sopenharmony_ci GL_UNSIGNED_BYTE, // INPUTTYPE_UNSIGNED_BYTE, 122e5c31af7Sopenharmony_ci GL_UNSIGNED_SHORT, // INPUTTYPE_UNSIGNED_SHORT, 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci GL_INT, // INPUTTYPE_INT, 125e5c31af7Sopenharmony_ci GL_UNSIGNED_INT, // INPUTTYPE_UNSIGNED_INT, 126e5c31af7Sopenharmony_ci GL_HALF_FLOAT, // INPUTTYPE_HALF, 127e5c31af7Sopenharmony_ci GL_UNSIGNED_INT_2_10_10_10_REV, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, 128e5c31af7Sopenharmony_ci GL_INT_2_10_10_10_REV // INPUTTYPE_INT_2_10_10_10, 129e5c31af7Sopenharmony_ci }; 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type); 132e5c31af7Sopenharmony_ci} 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_cistatic std::string outputTypeToGLType (DrawTestSpec::OutputType type) 135e5c31af7Sopenharmony_ci{ 136e5c31af7Sopenharmony_ci static const char* types[] = 137e5c31af7Sopenharmony_ci { 138e5c31af7Sopenharmony_ci "float", // OUTPUTTYPE_FLOAT = 0, 139e5c31af7Sopenharmony_ci "vec2", // OUTPUTTYPE_VEC2, 140e5c31af7Sopenharmony_ci "vec3", // OUTPUTTYPE_VEC3, 141e5c31af7Sopenharmony_ci "vec4", // OUTPUTTYPE_VEC4, 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci "int", // OUTPUTTYPE_INT, 144e5c31af7Sopenharmony_ci "uint", // OUTPUTTYPE_UINT, 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci "ivec2", // OUTPUTTYPE_IVEC2, 147e5c31af7Sopenharmony_ci "ivec3", // OUTPUTTYPE_IVEC3, 148e5c31af7Sopenharmony_ci "ivec4", // OUTPUTTYPE_IVEC4, 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci "uvec2", // OUTPUTTYPE_UVEC2, 151e5c31af7Sopenharmony_ci "uvec3", // OUTPUTTYPE_UVEC3, 152e5c31af7Sopenharmony_ci "uvec4", // OUTPUTTYPE_UVEC4, 153e5c31af7Sopenharmony_ci }; 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type); 156e5c31af7Sopenharmony_ci} 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_cistatic GLenum primitiveToGL (DrawTestSpec::Primitive primitive) 159e5c31af7Sopenharmony_ci{ 160e5c31af7Sopenharmony_ci static const GLenum primitives[] = 161e5c31af7Sopenharmony_ci { 162e5c31af7Sopenharmony_ci GL_POINTS, // PRIMITIVE_POINTS = 0, 163e5c31af7Sopenharmony_ci GL_TRIANGLES, // PRIMITIVE_TRIANGLES, 164e5c31af7Sopenharmony_ci GL_TRIANGLE_FAN, // PRIMITIVE_TRIANGLE_FAN, 165e5c31af7Sopenharmony_ci GL_TRIANGLE_STRIP, // PRIMITIVE_TRIANGLE_STRIP, 166e5c31af7Sopenharmony_ci GL_LINES, // PRIMITIVE_LINES 167e5c31af7Sopenharmony_ci GL_LINE_STRIP, // PRIMITIVE_LINE_STRIP 168e5c31af7Sopenharmony_ci GL_LINE_LOOP, // PRIMITIVE_LINE_LOOP 169e5c31af7Sopenharmony_ci GL_LINES_ADJACENCY, // PRIMITIVE_LINES_ADJACENCY 170e5c31af7Sopenharmony_ci GL_LINE_STRIP_ADJACENCY, // PRIMITIVE_LINE_STRIP_ADJACENCY 171e5c31af7Sopenharmony_ci GL_TRIANGLES_ADJACENCY, // PRIMITIVE_TRIANGLES_ADJACENCY 172e5c31af7Sopenharmony_ci GL_TRIANGLE_STRIP_ADJACENCY, // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY 173e5c31af7Sopenharmony_ci }; 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive); 176e5c31af7Sopenharmony_ci} 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_cistatic deUint32 indexTypeToGL (DrawTestSpec::IndexType indexType) 179e5c31af7Sopenharmony_ci{ 180e5c31af7Sopenharmony_ci static const GLenum indexTypes[] = 181e5c31af7Sopenharmony_ci { 182e5c31af7Sopenharmony_ci GL_UNSIGNED_BYTE, // INDEXTYPE_BYTE = 0, 183e5c31af7Sopenharmony_ci GL_UNSIGNED_SHORT, // INDEXTYPE_SHORT, 184e5c31af7Sopenharmony_ci GL_UNSIGNED_INT, // INDEXTYPE_INT, 185e5c31af7Sopenharmony_ci }; 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)indexType); 188e5c31af7Sopenharmony_ci} 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_cistatic bool inputTypeIsFloatType (DrawTestSpec::InputType type) 191e5c31af7Sopenharmony_ci{ 192e5c31af7Sopenharmony_ci if (type == DrawTestSpec::INPUTTYPE_FLOAT) 193e5c31af7Sopenharmony_ci return true; 194e5c31af7Sopenharmony_ci if (type == DrawTestSpec::INPUTTYPE_FIXED) 195e5c31af7Sopenharmony_ci return true; 196e5c31af7Sopenharmony_ci if (type == DrawTestSpec::INPUTTYPE_HALF) 197e5c31af7Sopenharmony_ci return true; 198e5c31af7Sopenharmony_ci if (type == DrawTestSpec::INPUTTYPE_DOUBLE) 199e5c31af7Sopenharmony_ci return true; 200e5c31af7Sopenharmony_ci return false; 201e5c31af7Sopenharmony_ci} 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_cistatic bool outputTypeIsFloatType (DrawTestSpec::OutputType type) 204e5c31af7Sopenharmony_ci{ 205e5c31af7Sopenharmony_ci if (type == DrawTestSpec::OUTPUTTYPE_FLOAT 206e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_VEC2 207e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_VEC3 208e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_VEC4) 209e5c31af7Sopenharmony_ci return true; 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci return false; 212e5c31af7Sopenharmony_ci} 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_cistatic bool outputTypeIsIntType (DrawTestSpec::OutputType type) 215e5c31af7Sopenharmony_ci{ 216e5c31af7Sopenharmony_ci if (type == DrawTestSpec::OUTPUTTYPE_INT 217e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_IVEC2 218e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_IVEC3 219e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_IVEC4) 220e5c31af7Sopenharmony_ci return true; 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ci return false; 223e5c31af7Sopenharmony_ci} 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_cistatic bool outputTypeIsUintType (DrawTestSpec::OutputType type) 226e5c31af7Sopenharmony_ci{ 227e5c31af7Sopenharmony_ci if (type == DrawTestSpec::OUTPUTTYPE_UINT 228e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_UVEC2 229e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_UVEC3 230e5c31af7Sopenharmony_ci || type == DrawTestSpec::OUTPUTTYPE_UVEC4) 231e5c31af7Sopenharmony_ci return true; 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci return false; 234e5c31af7Sopenharmony_ci} 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_cistatic size_t getElementCount (DrawTestSpec::Primitive primitive, size_t primitiveCount) 237e5c31af7Sopenharmony_ci{ 238e5c31af7Sopenharmony_ci switch (primitive) 239e5c31af7Sopenharmony_ci { 240e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_POINTS: return primitiveCount; 241e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES: return primitiveCount * 3; 242e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN: return primitiveCount + 2; 243e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP: return primitiveCount + 2; 244e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES: return primitiveCount * 2; 245e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP: return primitiveCount + 1; 246e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_LOOP: return (primitiveCount==1) ? (2) : (primitiveCount); 247e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY: return primitiveCount * 4; 248e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY: return primitiveCount + 3; 249e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY: return primitiveCount * 6; 250e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY: return primitiveCount * 2 + 4; 251e5c31af7Sopenharmony_ci default: 252e5c31af7Sopenharmony_ci DE_ASSERT(false); 253e5c31af7Sopenharmony_ci return 0; 254e5c31af7Sopenharmony_ci } 255e5c31af7Sopenharmony_ci} 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_cistruct MethodInfo 258e5c31af7Sopenharmony_ci{ 259e5c31af7Sopenharmony_ci bool indexed; 260e5c31af7Sopenharmony_ci bool instanced; 261e5c31af7Sopenharmony_ci bool ranged; 262e5c31af7Sopenharmony_ci bool first; 263e5c31af7Sopenharmony_ci bool baseVertex; 264e5c31af7Sopenharmony_ci bool indirect; 265e5c31af7Sopenharmony_ci}; 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_cistatic MethodInfo getMethodInfo (gls::DrawTestSpec::DrawMethod method) 268e5c31af7Sopenharmony_ci{ 269e5c31af7Sopenharmony_ci static const MethodInfo infos[] = 270e5c31af7Sopenharmony_ci { 271e5c31af7Sopenharmony_ci // indexed instanced ranged first baseVertex indirect 272e5c31af7Sopenharmony_ci { false, false, false, true, false, false }, //!< DRAWMETHOD_DRAWARRAYS, 273e5c31af7Sopenharmony_ci { false, true, false, true, false, false }, //!< DRAWMETHOD_DRAWARRAYS_INSTANCED, 274e5c31af7Sopenharmony_ci { false, true, false, true, false, true }, //!< DRAWMETHOD_DRAWARRAYS_INDIRECT, 275e5c31af7Sopenharmony_ci { true, false, false, false, false, false }, //!< DRAWMETHOD_DRAWELEMENTS, 276e5c31af7Sopenharmony_ci { true, false, true, false, false, false }, //!< DRAWMETHOD_DRAWELEMENTS_RANGED, 277e5c31af7Sopenharmony_ci { true, true, false, false, false, false }, //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED, 278e5c31af7Sopenharmony_ci { true, true, false, false, true, true }, //!< DRAWMETHOD_DRAWELEMENTS_INDIRECT, 279e5c31af7Sopenharmony_ci { true, false, false, false, true, false }, //!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX, 280e5c31af7Sopenharmony_ci { true, true, false, false, true, false }, //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX, 281e5c31af7Sopenharmony_ci { true, false, true, false, true, false }, //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX, 282e5c31af7Sopenharmony_ci }; 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(infos, (int)method); 285e5c31af7Sopenharmony_ci} 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_citemplate<class T> 288e5c31af7Sopenharmony_ciinline static void alignmentSafeAssignment (char* dst, T val) 289e5c31af7Sopenharmony_ci{ 290e5c31af7Sopenharmony_ci std::memcpy(dst, &val, sizeof(T)); 291e5c31af7Sopenharmony_ci} 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_cistatic bool checkSpecsShaderCompatible (const DrawTestSpec& a, const DrawTestSpec& b) 294e5c31af7Sopenharmony_ci{ 295e5c31af7Sopenharmony_ci // Only the attributes matter 296e5c31af7Sopenharmony_ci if (a.attribs.size() != b.attribs.size()) 297e5c31af7Sopenharmony_ci return false; 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < a.attribs.size(); ++ndx) 300e5c31af7Sopenharmony_ci { 301e5c31af7Sopenharmony_ci // Only the output type (== shader input type) matters and the usage in the shader. 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci if (a.attribs[ndx].additionalPositionAttribute != b.attribs[ndx].additionalPositionAttribute) 304e5c31af7Sopenharmony_ci return false; 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_ci // component counts need not to match 307e5c31af7Sopenharmony_ci if (outputTypeIsFloatType(a.attribs[ndx].outputType) && outputTypeIsFloatType(b.attribs[ndx].outputType)) 308e5c31af7Sopenharmony_ci continue; 309e5c31af7Sopenharmony_ci if (outputTypeIsIntType(a.attribs[ndx].outputType) && outputTypeIsIntType(b.attribs[ndx].outputType)) 310e5c31af7Sopenharmony_ci continue; 311e5c31af7Sopenharmony_ci if (outputTypeIsUintType(a.attribs[ndx].outputType) && outputTypeIsUintType(b.attribs[ndx].outputType)) 312e5c31af7Sopenharmony_ci continue; 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci return false; 315e5c31af7Sopenharmony_ci } 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ci return true; 318e5c31af7Sopenharmony_ci} 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ci// generate random vectors in a way that does not depend on argument evaluation order 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_citcu::Vec4 generateRandomVec4 (de::Random& random) 323e5c31af7Sopenharmony_ci{ 324e5c31af7Sopenharmony_ci tcu::Vec4 retVal; 325e5c31af7Sopenharmony_ci 326e5c31af7Sopenharmony_ci for (int i = 0; i < 4; ++i) 327e5c31af7Sopenharmony_ci retVal[i] = random.getFloat(); 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci return retVal; 330e5c31af7Sopenharmony_ci} 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_citcu::IVec4 generateRandomIVec4 (de::Random& random) 333e5c31af7Sopenharmony_ci{ 334e5c31af7Sopenharmony_ci tcu::IVec4 retVal; 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci for (int i = 0; i < 4; ++i) 337e5c31af7Sopenharmony_ci retVal[i] = random.getUint32(); 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_ci return retVal; 340e5c31af7Sopenharmony_ci} 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_citcu::UVec4 generateRandomUVec4 (de::Random& random) 343e5c31af7Sopenharmony_ci{ 344e5c31af7Sopenharmony_ci tcu::UVec4 retVal; 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci for (int i = 0; i < 4; ++i) 347e5c31af7Sopenharmony_ci retVal[i] = random.getUint32(); 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci return retVal; 350e5c31af7Sopenharmony_ci} 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci// IterationLogSectionEmitter 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_ciclass IterationLogSectionEmitter 355e5c31af7Sopenharmony_ci{ 356e5c31af7Sopenharmony_cipublic: 357e5c31af7Sopenharmony_ci IterationLogSectionEmitter (tcu::TestLog& log, size_t testIteration, size_t testIterations, const std::string& description, bool enabled); 358e5c31af7Sopenharmony_ci ~IterationLogSectionEmitter (void); 359e5c31af7Sopenharmony_ciprivate: 360e5c31af7Sopenharmony_ci IterationLogSectionEmitter (const IterationLogSectionEmitter&); // delete 361e5c31af7Sopenharmony_ci IterationLogSectionEmitter& operator= (const IterationLogSectionEmitter&); // delete 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci tcu::TestLog& m_log; 364e5c31af7Sopenharmony_ci bool m_enabled; 365e5c31af7Sopenharmony_ci}; 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ciIterationLogSectionEmitter::IterationLogSectionEmitter (tcu::TestLog& log, size_t testIteration, size_t testIterations, const std::string& description, bool enabled) 368e5c31af7Sopenharmony_ci : m_log (log) 369e5c31af7Sopenharmony_ci , m_enabled (enabled) 370e5c31af7Sopenharmony_ci{ 371e5c31af7Sopenharmony_ci if (m_enabled) 372e5c31af7Sopenharmony_ci { 373e5c31af7Sopenharmony_ci std::ostringstream buf; 374e5c31af7Sopenharmony_ci buf << "Iteration " << (testIteration+1) << "/" << testIterations; 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_ci if (!description.empty()) 377e5c31af7Sopenharmony_ci buf << " - " << description; 378e5c31af7Sopenharmony_ci 379e5c31af7Sopenharmony_ci m_log << tcu::TestLog::Section(buf.str(), buf.str()); 380e5c31af7Sopenharmony_ci } 381e5c31af7Sopenharmony_ci} 382e5c31af7Sopenharmony_ci 383e5c31af7Sopenharmony_ciIterationLogSectionEmitter::~IterationLogSectionEmitter (void) 384e5c31af7Sopenharmony_ci{ 385e5c31af7Sopenharmony_ci if (m_enabled) 386e5c31af7Sopenharmony_ci m_log << tcu::TestLog::EndSection; 387e5c31af7Sopenharmony_ci} 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci// GLValue 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_ciclass GLValue 392e5c31af7Sopenharmony_ci{ 393e5c31af7Sopenharmony_cipublic: 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci template<class Type> 396e5c31af7Sopenharmony_ci class WrappedType 397e5c31af7Sopenharmony_ci { 398e5c31af7Sopenharmony_ci public: 399e5c31af7Sopenharmony_ci static WrappedType<Type> create (Type value) { WrappedType<Type> v; v.m_value = value; return v; } 400e5c31af7Sopenharmony_ci inline Type getValue (void) const { return m_value; } 401e5c31af7Sopenharmony_ci 402e5c31af7Sopenharmony_ci inline WrappedType<Type> operator+ (const WrappedType<Type>& other) const { return WrappedType<Type>::create((Type)(m_value + other.getValue())); } 403e5c31af7Sopenharmony_ci inline WrappedType<Type> operator* (const WrappedType<Type>& other) const { return WrappedType<Type>::create((Type)(m_value * other.getValue())); } 404e5c31af7Sopenharmony_ci inline WrappedType<Type> operator/ (const WrappedType<Type>& other) const { return WrappedType<Type>::create((Type)(m_value / other.getValue())); } 405e5c31af7Sopenharmony_ci inline WrappedType<Type> operator- (const WrappedType<Type>& other) const { return WrappedType<Type>::create((Type)(m_value - other.getValue())); } 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci inline WrappedType<Type>& operator+= (const WrappedType<Type>& other) { m_value += other.getValue(); return *this; } 408e5c31af7Sopenharmony_ci inline WrappedType<Type>& operator*= (const WrappedType<Type>& other) { m_value *= other.getValue(); return *this; } 409e5c31af7Sopenharmony_ci inline WrappedType<Type>& operator/= (const WrappedType<Type>& other) { m_value /= other.getValue(); return *this; } 410e5c31af7Sopenharmony_ci inline WrappedType<Type>& operator-= (const WrappedType<Type>& other) { m_value -= other.getValue(); return *this; } 411e5c31af7Sopenharmony_ci 412e5c31af7Sopenharmony_ci inline bool operator== (const WrappedType<Type>& other) const { return m_value == other.m_value; } 413e5c31af7Sopenharmony_ci inline bool operator!= (const WrappedType<Type>& other) const { return m_value != other.m_value; } 414e5c31af7Sopenharmony_ci inline bool operator< (const WrappedType<Type>& other) const { return m_value < other.m_value; } 415e5c31af7Sopenharmony_ci inline bool operator> (const WrappedType<Type>& other) const { return m_value > other.m_value; } 416e5c31af7Sopenharmony_ci inline bool operator<= (const WrappedType<Type>& other) const { return m_value <= other.m_value; } 417e5c31af7Sopenharmony_ci inline bool operator>= (const WrappedType<Type>& other) const { return m_value >= other.m_value; } 418e5c31af7Sopenharmony_ci 419e5c31af7Sopenharmony_ci inline operator Type (void) const { return m_value; } 420e5c31af7Sopenharmony_ci template<class T> 421e5c31af7Sopenharmony_ci inline T to (void) const { return (T)m_value; } 422e5c31af7Sopenharmony_ci private: 423e5c31af7Sopenharmony_ci Type m_value; 424e5c31af7Sopenharmony_ci }; 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci typedef WrappedType<deInt16> Short; 427e5c31af7Sopenharmony_ci typedef WrappedType<deUint16> Ushort; 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci typedef WrappedType<deInt8> Byte; 430e5c31af7Sopenharmony_ci typedef WrappedType<deUint8> Ubyte; 431e5c31af7Sopenharmony_ci 432e5c31af7Sopenharmony_ci typedef WrappedType<float> Float; 433e5c31af7Sopenharmony_ci typedef WrappedType<double> Double; 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci typedef WrappedType<deUint32> Uint; 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_ci // All operations are calculated using 64bit values to avoid signed integer overflow which is undefined. 438e5c31af7Sopenharmony_ci class Int 439e5c31af7Sopenharmony_ci { 440e5c31af7Sopenharmony_ci public: 441e5c31af7Sopenharmony_ci static Int create (deInt32 value) { Int v; v.m_value = value; return v; } 442e5c31af7Sopenharmony_ci inline deInt32 getValue (void) const { return m_value; } 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci inline Int operator+ (const Int& other) const { return Int::create((deInt32)((deInt64)m_value + (deInt64)other.getValue())); } 445e5c31af7Sopenharmony_ci inline Int operator* (const Int& other) const { return Int::create((deInt32)((deInt64)m_value * (deInt64)other.getValue())); } 446e5c31af7Sopenharmony_ci inline Int operator/ (const Int& other) const { return Int::create((deInt32)((deInt64)m_value / (deInt64)other.getValue())); } 447e5c31af7Sopenharmony_ci inline Int operator- (const Int& other) const { return Int::create((deInt32)((deInt64)m_value - (deInt64)other.getValue())); } 448e5c31af7Sopenharmony_ci 449e5c31af7Sopenharmony_ci inline Int& operator+= (const Int& other) { m_value = (deInt32)((deInt64)m_value + (deInt64)other.getValue()); return *this; } 450e5c31af7Sopenharmony_ci inline Int& operator*= (const Int& other) { m_value = (deInt32)((deInt64)m_value * (deInt64)other.getValue()); return *this; } 451e5c31af7Sopenharmony_ci inline Int& operator/= (const Int& other) { m_value = (deInt32)((deInt64)m_value / (deInt64)other.getValue()); return *this; } 452e5c31af7Sopenharmony_ci inline Int& operator-= (const Int& other) { m_value = (deInt32)((deInt64)m_value - (deInt64)other.getValue()); return *this; } 453e5c31af7Sopenharmony_ci 454e5c31af7Sopenharmony_ci inline bool operator== (const Int& other) const { return m_value == other.m_value; } 455e5c31af7Sopenharmony_ci inline bool operator!= (const Int& other) const { return m_value != other.m_value; } 456e5c31af7Sopenharmony_ci inline bool operator< (const Int& other) const { return m_value < other.m_value; } 457e5c31af7Sopenharmony_ci inline bool operator> (const Int& other) const { return m_value > other.m_value; } 458e5c31af7Sopenharmony_ci inline bool operator<= (const Int& other) const { return m_value <= other.m_value; } 459e5c31af7Sopenharmony_ci inline bool operator>= (const Int& other) const { return m_value >= other.m_value; } 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci inline operator deInt32 (void) const { return m_value; } 462e5c31af7Sopenharmony_ci template<class T> 463e5c31af7Sopenharmony_ci inline T to (void) const { return (T)m_value; } 464e5c31af7Sopenharmony_ci private: 465e5c31af7Sopenharmony_ci deInt32 m_value; 466e5c31af7Sopenharmony_ci }; 467e5c31af7Sopenharmony_ci 468e5c31af7Sopenharmony_ci class Half 469e5c31af7Sopenharmony_ci { 470e5c31af7Sopenharmony_ci public: 471e5c31af7Sopenharmony_ci static Half create (float value) { Half h; h.m_value = floatToHalf(value); return h; } 472e5c31af7Sopenharmony_ci inline deFloat16 getValue (void) const { return m_value; } 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci inline Half operator+ (const Half& other) const { return create(halfToFloat(m_value) + halfToFloat(other.getValue())); } 475e5c31af7Sopenharmony_ci inline Half operator* (const Half& other) const { return create(halfToFloat(m_value) * halfToFloat(other.getValue())); } 476e5c31af7Sopenharmony_ci inline Half operator/ (const Half& other) const { return create(halfToFloat(m_value) / halfToFloat(other.getValue())); } 477e5c31af7Sopenharmony_ci inline Half operator- (const Half& other) const { return create(halfToFloat(m_value) - halfToFloat(other.getValue())); } 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci inline Half& operator+= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; } 480e5c31af7Sopenharmony_ci inline Half& operator*= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value)); return *this; } 481e5c31af7Sopenharmony_ci inline Half& operator/= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value)); return *this; } 482e5c31af7Sopenharmony_ci inline Half& operator-= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value)); return *this; } 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ci inline bool operator== (const Half& other) const { return m_value == other.m_value; } 485e5c31af7Sopenharmony_ci inline bool operator!= (const Half& other) const { return m_value != other.m_value; } 486e5c31af7Sopenharmony_ci inline bool operator< (const Half& other) const { return halfToFloat(m_value) < halfToFloat(other.m_value); } 487e5c31af7Sopenharmony_ci inline bool operator> (const Half& other) const { return halfToFloat(m_value) > halfToFloat(other.m_value); } 488e5c31af7Sopenharmony_ci inline bool operator<= (const Half& other) const { return halfToFloat(m_value) <= halfToFloat(other.m_value); } 489e5c31af7Sopenharmony_ci inline bool operator>= (const Half& other) const { return halfToFloat(m_value) >= halfToFloat(other.m_value); } 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci template<class T> 492e5c31af7Sopenharmony_ci inline T to (void) const { return (T)halfToFloat(m_value); } 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ci inline static deFloat16 floatToHalf (float f); 495e5c31af7Sopenharmony_ci inline static float halfToFloat (deFloat16 h); 496e5c31af7Sopenharmony_ci private: 497e5c31af7Sopenharmony_ci deFloat16 m_value; 498e5c31af7Sopenharmony_ci }; 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_ci class Fixed 501e5c31af7Sopenharmony_ci { 502e5c31af7Sopenharmony_ci public: 503e5c31af7Sopenharmony_ci static Fixed create (deInt32 value) { Fixed v; v.m_value = value; return v; } 504e5c31af7Sopenharmony_ci inline deInt32 getValue (void) const { return m_value; } 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci inline Fixed operator+ (const Fixed& other) const { return create(m_value + other.getValue()); } 507e5c31af7Sopenharmony_ci inline Fixed operator* (const Fixed& other) const { return create(m_value * other.getValue()); } 508e5c31af7Sopenharmony_ci inline Fixed operator/ (const Fixed& other) const { return create(m_value / other.getValue()); } 509e5c31af7Sopenharmony_ci inline Fixed operator- (const Fixed& other) const { return create(m_value - other.getValue()); } 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci inline Fixed& operator+= (const Fixed& other) { m_value += other.getValue(); return *this; } 512e5c31af7Sopenharmony_ci inline Fixed& operator*= (const Fixed& other) { m_value *= other.getValue(); return *this; } 513e5c31af7Sopenharmony_ci inline Fixed& operator/= (const Fixed& other) { m_value /= other.getValue(); return *this; } 514e5c31af7Sopenharmony_ci inline Fixed& operator-= (const Fixed& other) { m_value -= other.getValue(); return *this; } 515e5c31af7Sopenharmony_ci 516e5c31af7Sopenharmony_ci inline bool operator== (const Fixed& other) const { return m_value == other.m_value; } 517e5c31af7Sopenharmony_ci inline bool operator!= (const Fixed& other) const { return m_value != other.m_value; } 518e5c31af7Sopenharmony_ci inline bool operator< (const Fixed& other) const { return m_value < other.m_value; } 519e5c31af7Sopenharmony_ci inline bool operator> (const Fixed& other) const { return m_value > other.m_value; } 520e5c31af7Sopenharmony_ci inline bool operator<= (const Fixed& other) const { return m_value <= other.m_value; } 521e5c31af7Sopenharmony_ci inline bool operator>= (const Fixed& other) const { return m_value >= other.m_value; } 522e5c31af7Sopenharmony_ci 523e5c31af7Sopenharmony_ci inline operator deInt32 (void) const { return m_value; } 524e5c31af7Sopenharmony_ci template<class T> 525e5c31af7Sopenharmony_ci inline T to (void) const { return (T)m_value; } 526e5c31af7Sopenharmony_ci private: 527e5c31af7Sopenharmony_ci deInt32 m_value; 528e5c31af7Sopenharmony_ci }; 529e5c31af7Sopenharmony_ci 530e5c31af7Sopenharmony_ci // \todo [mika] This is pretty messy 531e5c31af7Sopenharmony_ci GLValue (void) : type(DrawTestSpec::INPUTTYPE_LAST) {} 532e5c31af7Sopenharmony_ci explicit GLValue (Float value) : type(DrawTestSpec::INPUTTYPE_FLOAT), fl(value) {} 533e5c31af7Sopenharmony_ci explicit GLValue (Fixed value) : type(DrawTestSpec::INPUTTYPE_FIXED), fi(value) {} 534e5c31af7Sopenharmony_ci explicit GLValue (Byte value) : type(DrawTestSpec::INPUTTYPE_BYTE), b(value) {} 535e5c31af7Sopenharmony_ci explicit GLValue (Ubyte value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE), ub(value) {} 536e5c31af7Sopenharmony_ci explicit GLValue (Short value) : type(DrawTestSpec::INPUTTYPE_SHORT), s(value) {} 537e5c31af7Sopenharmony_ci explicit GLValue (Ushort value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT), us(value) {} 538e5c31af7Sopenharmony_ci explicit GLValue (Int value) : type(DrawTestSpec::INPUTTYPE_INT), i(value) {} 539e5c31af7Sopenharmony_ci explicit GLValue (Uint value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_INT), ui(value) {} 540e5c31af7Sopenharmony_ci explicit GLValue (Half value) : type(DrawTestSpec::INPUTTYPE_HALF), h(value) {} 541e5c31af7Sopenharmony_ci explicit GLValue (Double value) : type(DrawTestSpec::INPUTTYPE_DOUBLE), d(value) {} 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_ci float toFloat (void) const; 544e5c31af7Sopenharmony_ci 545e5c31af7Sopenharmony_ci static GLValue getMaxValue (DrawTestSpec::InputType type); 546e5c31af7Sopenharmony_ci static GLValue getMinValue (DrawTestSpec::InputType type); 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci DrawTestSpec::InputType type; 549e5c31af7Sopenharmony_ci 550e5c31af7Sopenharmony_ci union 551e5c31af7Sopenharmony_ci { 552e5c31af7Sopenharmony_ci Float fl; 553e5c31af7Sopenharmony_ci Fixed fi; 554e5c31af7Sopenharmony_ci Double d; 555e5c31af7Sopenharmony_ci Byte b; 556e5c31af7Sopenharmony_ci Ubyte ub; 557e5c31af7Sopenharmony_ci Short s; 558e5c31af7Sopenharmony_ci Ushort us; 559e5c31af7Sopenharmony_ci Int i; 560e5c31af7Sopenharmony_ci Uint ui; 561e5c31af7Sopenharmony_ci Half h; 562e5c31af7Sopenharmony_ci }; 563e5c31af7Sopenharmony_ci}; 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ciinline deFloat16 GLValue::Half::floatToHalf (float f) 566e5c31af7Sopenharmony_ci{ 567e5c31af7Sopenharmony_ci // No denorm support. 568e5c31af7Sopenharmony_ci tcu::Float<deUint16, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f); 569e5c31af7Sopenharmony_ci DE_ASSERT(!v.isNaN() && !v.isInf()); 570e5c31af7Sopenharmony_ci return v.bits(); 571e5c31af7Sopenharmony_ci} 572e5c31af7Sopenharmony_ci 573e5c31af7Sopenharmony_ciinline float GLValue::Half::halfToFloat (deFloat16 h) 574e5c31af7Sopenharmony_ci{ 575e5c31af7Sopenharmony_ci return tcu::Float16((deUint16)h).asFloat(); 576e5c31af7Sopenharmony_ci} 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_cifloat GLValue::toFloat (void) const 579e5c31af7Sopenharmony_ci{ 580e5c31af7Sopenharmony_ci switch (type) 581e5c31af7Sopenharmony_ci { 582e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_FLOAT: 583e5c31af7Sopenharmony_ci return fl.getValue(); 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_BYTE: 586e5c31af7Sopenharmony_ci return b.getValue(); 587e5c31af7Sopenharmony_ci 588e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE: 589e5c31af7Sopenharmony_ci return ub.getValue(); 590e5c31af7Sopenharmony_ci 591e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_SHORT: 592e5c31af7Sopenharmony_ci return s.getValue(); 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT: 595e5c31af7Sopenharmony_ci return us.getValue(); 596e5c31af7Sopenharmony_ci 597e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_FIXED: 598e5c31af7Sopenharmony_ci { 599e5c31af7Sopenharmony_ci int maxValue = 65536; 600e5c31af7Sopenharmony_ci return (float)(double(2 * fi.getValue() + 1) / (maxValue - 1)); 601e5c31af7Sopenharmony_ci } 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_INT: 604e5c31af7Sopenharmony_ci return (float)ui.getValue(); 605e5c31af7Sopenharmony_ci 606e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_INT: 607e5c31af7Sopenharmony_ci return (float)i.getValue(); 608e5c31af7Sopenharmony_ci 609e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_HALF: 610e5c31af7Sopenharmony_ci return h.to<float>(); 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_DOUBLE: 613e5c31af7Sopenharmony_ci return d.to<float>(); 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ci default: 616e5c31af7Sopenharmony_ci DE_ASSERT(false); 617e5c31af7Sopenharmony_ci return 0.0f; 618e5c31af7Sopenharmony_ci } 619e5c31af7Sopenharmony_ci} 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ciGLValue GLValue::getMaxValue (DrawTestSpec::InputType type) 622e5c31af7Sopenharmony_ci{ 623e5c31af7Sopenharmony_ci GLValue rangesHi[(int)DrawTestSpec::INPUTTYPE_LAST]; 624e5c31af7Sopenharmony_ci 625e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_FLOAT] = GLValue(Float::create(127.0f)); 626e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_DOUBLE] = GLValue(Double::create(127.0f)); 627e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_BYTE] = GLValue(Byte::create(127)); 628e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE] = GLValue(Ubyte::create(255)); 629e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(65530)); 630e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_SHORT] = GLValue(Short::create(32760)); 631e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_FIXED] = GLValue(Fixed::create(32760)); 632e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_INT] = GLValue(Int::create(2147483647)); 633e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT] = GLValue(Uint::create(4294967295u)); 634e5c31af7Sopenharmony_ci rangesHi[(int)DrawTestSpec::INPUTTYPE_HALF] = GLValue(Half::create(256.0f)); 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci return rangesHi[(int)type]; 637e5c31af7Sopenharmony_ci} 638e5c31af7Sopenharmony_ci 639e5c31af7Sopenharmony_ciGLValue GLValue::getMinValue (DrawTestSpec::InputType type) 640e5c31af7Sopenharmony_ci{ 641e5c31af7Sopenharmony_ci GLValue rangesLo[(int)DrawTestSpec::INPUTTYPE_LAST]; 642e5c31af7Sopenharmony_ci 643e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_FLOAT] = GLValue(Float::create(-127.0f)); 644e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_DOUBLE] = GLValue(Double::create(-127.0f)); 645e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_BYTE] = GLValue(Byte::create(-127)); 646e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE] = GLValue(Ubyte::create(0)); 647e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(0)); 648e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_SHORT] = GLValue(Short::create(-32760)); 649e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_FIXED] = GLValue(Fixed::create(-32760)); 650e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_INT] = GLValue(Int::create(-2147483647)); 651e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT] = GLValue(Uint::create(0)); 652e5c31af7Sopenharmony_ci rangesLo[(int)DrawTestSpec::INPUTTYPE_HALF] = GLValue(Half::create(-256.0f)); 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci return rangesLo[(int)type]; 655e5c31af7Sopenharmony_ci} 656e5c31af7Sopenharmony_ci 657e5c31af7Sopenharmony_citemplate<typename T> 658e5c31af7Sopenharmony_cistruct GLValueTypeTraits; 659e5c31af7Sopenharmony_ci 660e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Float> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FLOAT; }; 661e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Double> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_DOUBLE; }; 662e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Byte> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_BYTE; }; 663e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Ubyte> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE; }; 664e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Ushort> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT; }; 665e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Short> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_SHORT; }; 666e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Fixed> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FIXED; }; 667e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Int> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_INT; }; 668e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Uint> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_INT; }; 669e5c31af7Sopenharmony_citemplate<> struct GLValueTypeTraits<GLValue::Half> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_HALF; }; 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_citemplate<typename T> 672e5c31af7Sopenharmony_ciinline T extractGLValue (const GLValue& v); 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_citemplate<> GLValue::Float inline extractGLValue<GLValue::Float> (const GLValue& v) { return v.fl; } 675e5c31af7Sopenharmony_citemplate<> GLValue::Double inline extractGLValue<GLValue::Double> (const GLValue& v) { return v.d; } 676e5c31af7Sopenharmony_citemplate<> GLValue::Byte inline extractGLValue<GLValue::Byte> (const GLValue& v) { return v.b; } 677e5c31af7Sopenharmony_citemplate<> GLValue::Ubyte inline extractGLValue<GLValue::Ubyte> (const GLValue& v) { return v.ub; } 678e5c31af7Sopenharmony_citemplate<> GLValue::Ushort inline extractGLValue<GLValue::Ushort> (const GLValue& v) { return v.us; } 679e5c31af7Sopenharmony_citemplate<> GLValue::Short inline extractGLValue<GLValue::Short> (const GLValue& v) { return v.s; } 680e5c31af7Sopenharmony_citemplate<> GLValue::Fixed inline extractGLValue<GLValue::Fixed> (const GLValue& v) { return v.fi; } 681e5c31af7Sopenharmony_citemplate<> GLValue::Int inline extractGLValue<GLValue::Int> (const GLValue& v) { return v.i; } 682e5c31af7Sopenharmony_citemplate<> GLValue::Uint inline extractGLValue<GLValue::Uint> (const GLValue& v) { return v.ui; } 683e5c31af7Sopenharmony_citemplate<> GLValue::Half inline extractGLValue<GLValue::Half> (const GLValue& v) { return v.h; } 684e5c31af7Sopenharmony_ci 685e5c31af7Sopenharmony_citemplate<class T> 686e5c31af7Sopenharmony_ciinline T getRandom (deRandom& rnd, T min, T max); 687e5c31af7Sopenharmony_ci 688e5c31af7Sopenharmony_citemplate<> 689e5c31af7Sopenharmony_ciinline GLValue::Float getRandom (deRandom& rnd, GLValue::Float min, GLValue::Float max) 690e5c31af7Sopenharmony_ci{ 691e5c31af7Sopenharmony_ci if (max < min) 692e5c31af7Sopenharmony_ci return min; 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_ci return GLValue::Float::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>())); 695e5c31af7Sopenharmony_ci} 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_citemplate<> 698e5c31af7Sopenharmony_ciinline GLValue::Double getRandom (deRandom& rnd, GLValue::Double min, GLValue::Double max) 699e5c31af7Sopenharmony_ci{ 700e5c31af7Sopenharmony_ci if (max < min) 701e5c31af7Sopenharmony_ci return min; 702e5c31af7Sopenharmony_ci 703e5c31af7Sopenharmony_ci return GLValue::Double::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>())); 704e5c31af7Sopenharmony_ci} 705e5c31af7Sopenharmony_ci 706e5c31af7Sopenharmony_citemplate<> 707e5c31af7Sopenharmony_ciinline GLValue::Short getRandom (deRandom& rnd, GLValue::Short min, GLValue::Short max) 708e5c31af7Sopenharmony_ci{ 709e5c31af7Sopenharmony_ci if (max < min) 710e5c31af7Sopenharmony_ci return min; 711e5c31af7Sopenharmony_ci 712e5c31af7Sopenharmony_ci return GLValue::Short::create((min == max ? min : (deInt16)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 713e5c31af7Sopenharmony_ci} 714e5c31af7Sopenharmony_ci 715e5c31af7Sopenharmony_citemplate<> 716e5c31af7Sopenharmony_ciinline GLValue::Ushort getRandom (deRandom& rnd, GLValue::Ushort min, GLValue::Ushort max) 717e5c31af7Sopenharmony_ci{ 718e5c31af7Sopenharmony_ci if (max < min) 719e5c31af7Sopenharmony_ci return min; 720e5c31af7Sopenharmony_ci 721e5c31af7Sopenharmony_ci return GLValue::Ushort::create((min == max ? min : (deUint16)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 722e5c31af7Sopenharmony_ci} 723e5c31af7Sopenharmony_ci 724e5c31af7Sopenharmony_citemplate<> 725e5c31af7Sopenharmony_ciinline GLValue::Byte getRandom (deRandom& rnd, GLValue::Byte min, GLValue::Byte max) 726e5c31af7Sopenharmony_ci{ 727e5c31af7Sopenharmony_ci if (max < min) 728e5c31af7Sopenharmony_ci return min; 729e5c31af7Sopenharmony_ci 730e5c31af7Sopenharmony_ci return GLValue::Byte::create((min == max ? min : (deInt8)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 731e5c31af7Sopenharmony_ci} 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_citemplate<> 734e5c31af7Sopenharmony_ciinline GLValue::Ubyte getRandom (deRandom& rnd, GLValue::Ubyte min, GLValue::Ubyte max) 735e5c31af7Sopenharmony_ci{ 736e5c31af7Sopenharmony_ci if (max < min) 737e5c31af7Sopenharmony_ci return min; 738e5c31af7Sopenharmony_ci 739e5c31af7Sopenharmony_ci return GLValue::Ubyte::create((min == max ? min : (deUint8)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 740e5c31af7Sopenharmony_ci} 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_citemplate<> 743e5c31af7Sopenharmony_ciinline GLValue::Fixed getRandom (deRandom& rnd, GLValue::Fixed min, GLValue::Fixed max) 744e5c31af7Sopenharmony_ci{ 745e5c31af7Sopenharmony_ci if (max < min) 746e5c31af7Sopenharmony_ci return min; 747e5c31af7Sopenharmony_ci 748e5c31af7Sopenharmony_ci return GLValue::Fixed::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>())))); 749e5c31af7Sopenharmony_ci} 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_citemplate<> 752e5c31af7Sopenharmony_ciinline GLValue::Half getRandom (deRandom& rnd, GLValue::Half min, GLValue::Half max) 753e5c31af7Sopenharmony_ci{ 754e5c31af7Sopenharmony_ci if (max < min) 755e5c31af7Sopenharmony_ci return min; 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_ci float fMax = max.to<float>(); 758e5c31af7Sopenharmony_ci float fMin = min.to<float>(); 759e5c31af7Sopenharmony_ci GLValue::Half h = GLValue::Half::create(fMin + deRandom_getFloat(&rnd) * (fMax - fMin)); 760e5c31af7Sopenharmony_ci return h; 761e5c31af7Sopenharmony_ci} 762e5c31af7Sopenharmony_ci 763e5c31af7Sopenharmony_citemplate<> 764e5c31af7Sopenharmony_ciinline GLValue::Int getRandom (deRandom& rnd, GLValue::Int min, GLValue::Int max) 765e5c31af7Sopenharmony_ci{ 766e5c31af7Sopenharmony_ci if (max < min) 767e5c31af7Sopenharmony_ci return min; 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci return GLValue::Int::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>())))); 770e5c31af7Sopenharmony_ci} 771e5c31af7Sopenharmony_ci 772e5c31af7Sopenharmony_citemplate<> 773e5c31af7Sopenharmony_ciinline GLValue::Uint getRandom (deRandom& rnd, GLValue::Uint min, GLValue::Uint max) 774e5c31af7Sopenharmony_ci{ 775e5c31af7Sopenharmony_ci if (max < min) 776e5c31af7Sopenharmony_ci return min; 777e5c31af7Sopenharmony_ci 778e5c31af7Sopenharmony_ci return GLValue::Uint::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>())))); 779e5c31af7Sopenharmony_ci} 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci// Minimum difference required between coordinates 782e5c31af7Sopenharmony_citemplate<class T> 783e5c31af7Sopenharmony_ciinline T minValue (void); 784e5c31af7Sopenharmony_ci 785e5c31af7Sopenharmony_citemplate<> 786e5c31af7Sopenharmony_ciinline GLValue::Float minValue (void) 787e5c31af7Sopenharmony_ci{ 788e5c31af7Sopenharmony_ci return GLValue::Float::create(4 * 1.0f); 789e5c31af7Sopenharmony_ci} 790e5c31af7Sopenharmony_ci 791e5c31af7Sopenharmony_citemplate<> 792e5c31af7Sopenharmony_ciinline GLValue::Double minValue (void) 793e5c31af7Sopenharmony_ci{ 794e5c31af7Sopenharmony_ci return GLValue::Double::create(4 * 1.0f); 795e5c31af7Sopenharmony_ci} 796e5c31af7Sopenharmony_ci 797e5c31af7Sopenharmony_citemplate<> 798e5c31af7Sopenharmony_ciinline GLValue::Short minValue (void) 799e5c31af7Sopenharmony_ci{ 800e5c31af7Sopenharmony_ci return GLValue::Short::create(4 * 256); 801e5c31af7Sopenharmony_ci} 802e5c31af7Sopenharmony_ci 803e5c31af7Sopenharmony_citemplate<> 804e5c31af7Sopenharmony_ciinline GLValue::Ushort minValue (void) 805e5c31af7Sopenharmony_ci{ 806e5c31af7Sopenharmony_ci return GLValue::Ushort::create(4 * 256); 807e5c31af7Sopenharmony_ci} 808e5c31af7Sopenharmony_ci 809e5c31af7Sopenharmony_citemplate<> 810e5c31af7Sopenharmony_ciinline GLValue::Byte minValue (void) 811e5c31af7Sopenharmony_ci{ 812e5c31af7Sopenharmony_ci return GLValue::Byte::create(4 * 1); 813e5c31af7Sopenharmony_ci} 814e5c31af7Sopenharmony_ci 815e5c31af7Sopenharmony_citemplate<> 816e5c31af7Sopenharmony_ciinline GLValue::Ubyte minValue (void) 817e5c31af7Sopenharmony_ci{ 818e5c31af7Sopenharmony_ci return GLValue::Ubyte::create(4 * 2); 819e5c31af7Sopenharmony_ci} 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_citemplate<> 822e5c31af7Sopenharmony_ciinline GLValue::Fixed minValue (void) 823e5c31af7Sopenharmony_ci{ 824e5c31af7Sopenharmony_ci return GLValue::Fixed::create(4 * 1); 825e5c31af7Sopenharmony_ci} 826e5c31af7Sopenharmony_ci 827e5c31af7Sopenharmony_citemplate<> 828e5c31af7Sopenharmony_ciinline GLValue::Int minValue (void) 829e5c31af7Sopenharmony_ci{ 830e5c31af7Sopenharmony_ci return GLValue::Int::create(4 * 16777216); 831e5c31af7Sopenharmony_ci} 832e5c31af7Sopenharmony_ci 833e5c31af7Sopenharmony_citemplate<> 834e5c31af7Sopenharmony_ciinline GLValue::Uint minValue (void) 835e5c31af7Sopenharmony_ci{ 836e5c31af7Sopenharmony_ci return GLValue::Uint::create(4 * 16777216); 837e5c31af7Sopenharmony_ci} 838e5c31af7Sopenharmony_ci 839e5c31af7Sopenharmony_citemplate<> 840e5c31af7Sopenharmony_ciinline GLValue::Half minValue (void) 841e5c31af7Sopenharmony_ci{ 842e5c31af7Sopenharmony_ci return GLValue::Half::create(4 * 1.0f); 843e5c31af7Sopenharmony_ci} 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_citemplate<class T> 846e5c31af7Sopenharmony_ciinline T abs (T val); 847e5c31af7Sopenharmony_ci 848e5c31af7Sopenharmony_citemplate<> 849e5c31af7Sopenharmony_ciinline GLValue::Fixed abs (GLValue::Fixed val) 850e5c31af7Sopenharmony_ci{ 851e5c31af7Sopenharmony_ci return GLValue::Fixed::create(0x7FFFu & val.getValue()); 852e5c31af7Sopenharmony_ci} 853e5c31af7Sopenharmony_ci 854e5c31af7Sopenharmony_citemplate<> 855e5c31af7Sopenharmony_ciinline GLValue::Ubyte abs (GLValue::Ubyte val) 856e5c31af7Sopenharmony_ci{ 857e5c31af7Sopenharmony_ci return val; 858e5c31af7Sopenharmony_ci} 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_citemplate<> 861e5c31af7Sopenharmony_ciinline GLValue::Byte abs (GLValue::Byte val) 862e5c31af7Sopenharmony_ci{ 863e5c31af7Sopenharmony_ci return GLValue::Byte::create(0x7Fu & val.getValue()); 864e5c31af7Sopenharmony_ci} 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_citemplate<> 867e5c31af7Sopenharmony_ciinline GLValue::Ushort abs (GLValue::Ushort val) 868e5c31af7Sopenharmony_ci{ 869e5c31af7Sopenharmony_ci return val; 870e5c31af7Sopenharmony_ci} 871e5c31af7Sopenharmony_ci 872e5c31af7Sopenharmony_citemplate<> 873e5c31af7Sopenharmony_ciinline GLValue::Short abs (GLValue::Short val) 874e5c31af7Sopenharmony_ci{ 875e5c31af7Sopenharmony_ci return GLValue::Short::create(0x7FFFu & val.getValue()); 876e5c31af7Sopenharmony_ci} 877e5c31af7Sopenharmony_ci 878e5c31af7Sopenharmony_citemplate<> 879e5c31af7Sopenharmony_ciinline GLValue::Float abs (GLValue::Float val) 880e5c31af7Sopenharmony_ci{ 881e5c31af7Sopenharmony_ci return GLValue::Float::create(std::fabs(val.to<float>())); 882e5c31af7Sopenharmony_ci} 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_citemplate<> 885e5c31af7Sopenharmony_ciinline GLValue::Double abs (GLValue::Double val) 886e5c31af7Sopenharmony_ci{ 887e5c31af7Sopenharmony_ci return GLValue::Double::create(std::fabs(val.to<float>())); 888e5c31af7Sopenharmony_ci} 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_citemplate<> 891e5c31af7Sopenharmony_ciinline GLValue::Uint abs (GLValue::Uint val) 892e5c31af7Sopenharmony_ci{ 893e5c31af7Sopenharmony_ci return val; 894e5c31af7Sopenharmony_ci} 895e5c31af7Sopenharmony_ci 896e5c31af7Sopenharmony_citemplate<> 897e5c31af7Sopenharmony_ciinline GLValue::Int abs (GLValue::Int val) 898e5c31af7Sopenharmony_ci{ 899e5c31af7Sopenharmony_ci return GLValue::Int::create(0x7FFFFFFFu & val.getValue()); 900e5c31af7Sopenharmony_ci} 901e5c31af7Sopenharmony_ci 902e5c31af7Sopenharmony_citemplate<> 903e5c31af7Sopenharmony_ciinline GLValue::Half abs (GLValue::Half val) 904e5c31af7Sopenharmony_ci{ 905e5c31af7Sopenharmony_ci return GLValue::Half::create(std::fabs(val.to<float>())); 906e5c31af7Sopenharmony_ci} 907e5c31af7Sopenharmony_ci 908e5c31af7Sopenharmony_ci// AttributeArray 909e5c31af7Sopenharmony_ci 910e5c31af7Sopenharmony_ciclass AttributeArray 911e5c31af7Sopenharmony_ci{ 912e5c31af7Sopenharmony_cipublic: 913e5c31af7Sopenharmony_ci AttributeArray (DrawTestSpec::Storage storage, sglr::Context& context); 914e5c31af7Sopenharmony_ci ~AttributeArray (void); 915e5c31af7Sopenharmony_ci 916e5c31af7Sopenharmony_ci void data (DrawTestSpec::Target target, size_t size, const char* data, DrawTestSpec::Usage usage); 917e5c31af7Sopenharmony_ci void setupArray (bool bound, int offset, int size, DrawTestSpec::InputType inType, DrawTestSpec::OutputType outType, bool normalized, int stride, int instanceDivisor, const rr::GenericVec4& defaultAttrib, bool isPositionAttr, bool bgraComponentOrder); 918e5c31af7Sopenharmony_ci void bindAttribute (deUint32 loc); 919e5c31af7Sopenharmony_ci void bindIndexArray (DrawTestSpec::Target storage); 920e5c31af7Sopenharmony_ci 921e5c31af7Sopenharmony_ci int getComponentCount (void) const { return m_componentCount; } 922e5c31af7Sopenharmony_ci DrawTestSpec::Target getTarget (void) const { return m_target; } 923e5c31af7Sopenharmony_ci DrawTestSpec::InputType getInputType (void) const { return m_inputType; } 924e5c31af7Sopenharmony_ci DrawTestSpec::OutputType getOutputType (void) const { return m_outputType; } 925e5c31af7Sopenharmony_ci DrawTestSpec::Storage getStorageType (void) const { return m_storage; } 926e5c31af7Sopenharmony_ci bool getNormalized (void) const { return m_normalize; } 927e5c31af7Sopenharmony_ci int getStride (void) const { return m_stride; } 928e5c31af7Sopenharmony_ci bool isBound (void) const { return m_bound; } 929e5c31af7Sopenharmony_ci bool isPositionAttribute (void) const { return m_isPositionAttr; } 930e5c31af7Sopenharmony_ci 931e5c31af7Sopenharmony_ciprivate: 932e5c31af7Sopenharmony_ci DrawTestSpec::Storage m_storage; 933e5c31af7Sopenharmony_ci sglr::Context& m_ctx; 934e5c31af7Sopenharmony_ci deUint32 m_glBuffer; 935e5c31af7Sopenharmony_ci 936e5c31af7Sopenharmony_ci int m_size; 937e5c31af7Sopenharmony_ci char* m_data; 938e5c31af7Sopenharmony_ci int m_componentCount; 939e5c31af7Sopenharmony_ci bool m_bound; 940e5c31af7Sopenharmony_ci DrawTestSpec::Target m_target; 941e5c31af7Sopenharmony_ci DrawTestSpec::InputType m_inputType; 942e5c31af7Sopenharmony_ci DrawTestSpec::OutputType m_outputType; 943e5c31af7Sopenharmony_ci bool m_normalize; 944e5c31af7Sopenharmony_ci int m_stride; 945e5c31af7Sopenharmony_ci int m_offset; 946e5c31af7Sopenharmony_ci rr::GenericVec4 m_defaultAttrib; 947e5c31af7Sopenharmony_ci int m_instanceDivisor; 948e5c31af7Sopenharmony_ci bool m_isPositionAttr; 949e5c31af7Sopenharmony_ci bool m_bgraOrder; 950e5c31af7Sopenharmony_ci}; 951e5c31af7Sopenharmony_ci 952e5c31af7Sopenharmony_ciAttributeArray::AttributeArray (DrawTestSpec::Storage storage, sglr::Context& context) 953e5c31af7Sopenharmony_ci : m_storage (storage) 954e5c31af7Sopenharmony_ci , m_ctx (context) 955e5c31af7Sopenharmony_ci , m_glBuffer (0) 956e5c31af7Sopenharmony_ci , m_size (0) 957e5c31af7Sopenharmony_ci , m_data (DE_NULL) 958e5c31af7Sopenharmony_ci , m_componentCount (1) 959e5c31af7Sopenharmony_ci , m_bound (false) 960e5c31af7Sopenharmony_ci , m_target (DrawTestSpec::TARGET_ARRAY) 961e5c31af7Sopenharmony_ci , m_inputType (DrawTestSpec::INPUTTYPE_FLOAT) 962e5c31af7Sopenharmony_ci , m_outputType (DrawTestSpec::OUTPUTTYPE_VEC4) 963e5c31af7Sopenharmony_ci , m_normalize (false) 964e5c31af7Sopenharmony_ci , m_stride (0) 965e5c31af7Sopenharmony_ci , m_offset (0) 966e5c31af7Sopenharmony_ci , m_instanceDivisor (0) 967e5c31af7Sopenharmony_ci , m_isPositionAttr (false) 968e5c31af7Sopenharmony_ci , m_bgraOrder (false) 969e5c31af7Sopenharmony_ci{ 970e5c31af7Sopenharmony_ci if (m_storage == DrawTestSpec::STORAGE_BUFFER) 971e5c31af7Sopenharmony_ci { 972e5c31af7Sopenharmony_ci m_ctx.genBuffers(1, &m_glBuffer); 973e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glGenBuffers()"); 974e5c31af7Sopenharmony_ci } 975e5c31af7Sopenharmony_ci} 976e5c31af7Sopenharmony_ci 977e5c31af7Sopenharmony_ciAttributeArray::~AttributeArray (void) 978e5c31af7Sopenharmony_ci{ 979e5c31af7Sopenharmony_ci if (m_storage == DrawTestSpec::STORAGE_BUFFER) 980e5c31af7Sopenharmony_ci { 981e5c31af7Sopenharmony_ci m_ctx.deleteBuffers(1, &m_glBuffer); 982e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDeleteBuffers()"); 983e5c31af7Sopenharmony_ci } 984e5c31af7Sopenharmony_ci else if (m_storage == DrawTestSpec::STORAGE_USER) 985e5c31af7Sopenharmony_ci delete[] m_data; 986e5c31af7Sopenharmony_ci else 987e5c31af7Sopenharmony_ci DE_ASSERT(false); 988e5c31af7Sopenharmony_ci} 989e5c31af7Sopenharmony_ci 990e5c31af7Sopenharmony_civoid AttributeArray::data (DrawTestSpec::Target target, size_t size, const char* ptr, DrawTestSpec::Usage usage) 991e5c31af7Sopenharmony_ci{ 992e5c31af7Sopenharmony_ci m_size = (int)size; 993e5c31af7Sopenharmony_ci m_target = target; 994e5c31af7Sopenharmony_ci 995e5c31af7Sopenharmony_ci if (m_storage == DrawTestSpec::STORAGE_BUFFER) 996e5c31af7Sopenharmony_ci { 997e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(target), m_glBuffer); 998e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()"); 999e5c31af7Sopenharmony_ci 1000e5c31af7Sopenharmony_ci m_ctx.bufferData(targetToGL(target), size, ptr, usageToGL(usage)); 1001e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBufferData()"); 1002e5c31af7Sopenharmony_ci } 1003e5c31af7Sopenharmony_ci else if (m_storage == DrawTestSpec::STORAGE_USER) 1004e5c31af7Sopenharmony_ci { 1005e5c31af7Sopenharmony_ci if (m_data) 1006e5c31af7Sopenharmony_ci delete[] m_data; 1007e5c31af7Sopenharmony_ci 1008e5c31af7Sopenharmony_ci m_data = new char[size]; 1009e5c31af7Sopenharmony_ci std::memcpy(m_data, ptr, size); 1010e5c31af7Sopenharmony_ci } 1011e5c31af7Sopenharmony_ci else 1012e5c31af7Sopenharmony_ci DE_ASSERT(false); 1013e5c31af7Sopenharmony_ci} 1014e5c31af7Sopenharmony_ci 1015e5c31af7Sopenharmony_civoid AttributeArray::setupArray (bool bound, int offset, int size, DrawTestSpec::InputType inputType, DrawTestSpec::OutputType outType, bool normalized, int stride, int instanceDivisor, const rr::GenericVec4& defaultAttrib, bool isPositionAttr, bool bgraComponentOrder) 1016e5c31af7Sopenharmony_ci{ 1017e5c31af7Sopenharmony_ci m_componentCount = size; 1018e5c31af7Sopenharmony_ci m_bound = bound; 1019e5c31af7Sopenharmony_ci m_inputType = inputType; 1020e5c31af7Sopenharmony_ci m_outputType = outType; 1021e5c31af7Sopenharmony_ci m_normalize = normalized; 1022e5c31af7Sopenharmony_ci m_stride = stride; 1023e5c31af7Sopenharmony_ci m_offset = offset; 1024e5c31af7Sopenharmony_ci m_defaultAttrib = defaultAttrib; 1025e5c31af7Sopenharmony_ci m_instanceDivisor = instanceDivisor; 1026e5c31af7Sopenharmony_ci m_isPositionAttr = isPositionAttr; 1027e5c31af7Sopenharmony_ci m_bgraOrder = bgraComponentOrder; 1028e5c31af7Sopenharmony_ci} 1029e5c31af7Sopenharmony_ci 1030e5c31af7Sopenharmony_civoid AttributeArray::bindAttribute (deUint32 loc) 1031e5c31af7Sopenharmony_ci{ 1032e5c31af7Sopenharmony_ci if (!isBound()) 1033e5c31af7Sopenharmony_ci { 1034e5c31af7Sopenharmony_ci switch (m_inputType) 1035e5c31af7Sopenharmony_ci { 1036e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_FLOAT: 1037e5c31af7Sopenharmony_ci { 1038e5c31af7Sopenharmony_ci tcu::Vec4 attr = m_defaultAttrib.get<float>(); 1039e5c31af7Sopenharmony_ci 1040e5c31af7Sopenharmony_ci switch (m_componentCount) 1041e5c31af7Sopenharmony_ci { 1042e5c31af7Sopenharmony_ci case 1: m_ctx.vertexAttrib1f(loc, attr.x()); break; 1043e5c31af7Sopenharmony_ci case 2: m_ctx.vertexAttrib2f(loc, attr.x(), attr.y()); break; 1044e5c31af7Sopenharmony_ci case 3: m_ctx.vertexAttrib3f(loc, attr.x(), attr.y(), attr.z()); break; 1045e5c31af7Sopenharmony_ci case 4: m_ctx.vertexAttrib4f(loc, attr.x(), attr.y(), attr.z(), attr.w()); break; 1046e5c31af7Sopenharmony_ci default: DE_ASSERT(DE_FALSE); break; 1047e5c31af7Sopenharmony_ci } 1048e5c31af7Sopenharmony_ci break; 1049e5c31af7Sopenharmony_ci } 1050e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_INT: 1051e5c31af7Sopenharmony_ci { 1052e5c31af7Sopenharmony_ci tcu::IVec4 attr = m_defaultAttrib.get<deInt32>(); 1053e5c31af7Sopenharmony_ci m_ctx.vertexAttribI4i(loc, attr.x(), attr.y(), attr.z(), attr.w()); 1054e5c31af7Sopenharmony_ci break; 1055e5c31af7Sopenharmony_ci } 1056e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_INT: 1057e5c31af7Sopenharmony_ci { 1058e5c31af7Sopenharmony_ci tcu::UVec4 attr = m_defaultAttrib.get<deUint32>(); 1059e5c31af7Sopenharmony_ci m_ctx.vertexAttribI4ui(loc, attr.x(), attr.y(), attr.z(), attr.w()); 1060e5c31af7Sopenharmony_ci break; 1061e5c31af7Sopenharmony_ci } 1062e5c31af7Sopenharmony_ci default: 1063e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1064e5c31af7Sopenharmony_ci break; 1065e5c31af7Sopenharmony_ci } 1066e5c31af7Sopenharmony_ci } 1067e5c31af7Sopenharmony_ci else 1068e5c31af7Sopenharmony_ci { 1069e5c31af7Sopenharmony_ci const deUint8* basePtr = DE_NULL; 1070e5c31af7Sopenharmony_ci 1071e5c31af7Sopenharmony_ci if (m_storage == DrawTestSpec::STORAGE_BUFFER) 1072e5c31af7Sopenharmony_ci { 1073e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(m_target), m_glBuffer); 1074e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()"); 1075e5c31af7Sopenharmony_ci 1076e5c31af7Sopenharmony_ci basePtr = DE_NULL; 1077e5c31af7Sopenharmony_ci } 1078e5c31af7Sopenharmony_ci else if (m_storage == DrawTestSpec::STORAGE_USER) 1079e5c31af7Sopenharmony_ci { 1080e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(m_target), 0); 1081e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()"); 1082e5c31af7Sopenharmony_ci 1083e5c31af7Sopenharmony_ci basePtr = (const deUint8*)m_data; 1084e5c31af7Sopenharmony_ci } 1085e5c31af7Sopenharmony_ci else 1086e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1087e5c31af7Sopenharmony_ci 1088e5c31af7Sopenharmony_ci if (!inputTypeIsFloatType(m_inputType)) 1089e5c31af7Sopenharmony_ci { 1090e5c31af7Sopenharmony_ci // Input is not float type 1091e5c31af7Sopenharmony_ci 1092e5c31af7Sopenharmony_ci if (outputTypeIsFloatType(m_outputType)) 1093e5c31af7Sopenharmony_ci { 1094e5c31af7Sopenharmony_ci const int size = (m_bgraOrder) ? (GL_BGRA) : (m_componentCount); 1095e5c31af7Sopenharmony_ci 1096e5c31af7Sopenharmony_ci DE_ASSERT(!(m_bgraOrder && m_componentCount != 4)); 1097e5c31af7Sopenharmony_ci 1098e5c31af7Sopenharmony_ci // Output type is float type 1099e5c31af7Sopenharmony_ci m_ctx.vertexAttribPointer(loc, size, inputTypeToGL(m_inputType), m_normalize, m_stride, basePtr + m_offset); 1100e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()"); 1101e5c31af7Sopenharmony_ci } 1102e5c31af7Sopenharmony_ci else 1103e5c31af7Sopenharmony_ci { 1104e5c31af7Sopenharmony_ci // Output type is int type 1105e5c31af7Sopenharmony_ci m_ctx.vertexAttribIPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_stride, basePtr + m_offset); 1106e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()"); 1107e5c31af7Sopenharmony_ci } 1108e5c31af7Sopenharmony_ci } 1109e5c31af7Sopenharmony_ci else 1110e5c31af7Sopenharmony_ci { 1111e5c31af7Sopenharmony_ci // Input type is float type 1112e5c31af7Sopenharmony_ci 1113e5c31af7Sopenharmony_ci // Output type must be float type 1114e5c31af7Sopenharmony_ci DE_ASSERT(outputTypeIsFloatType(m_outputType)); 1115e5c31af7Sopenharmony_ci 1116e5c31af7Sopenharmony_ci m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, basePtr + m_offset); 1117e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()"); 1118e5c31af7Sopenharmony_ci } 1119e5c31af7Sopenharmony_ci 1120e5c31af7Sopenharmony_ci if (m_instanceDivisor) 1121e5c31af7Sopenharmony_ci m_ctx.vertexAttribDivisor(loc, m_instanceDivisor); 1122e5c31af7Sopenharmony_ci } 1123e5c31af7Sopenharmony_ci} 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_civoid AttributeArray::bindIndexArray (DrawTestSpec::Target target) 1126e5c31af7Sopenharmony_ci{ 1127e5c31af7Sopenharmony_ci if (m_storage == DrawTestSpec::STORAGE_USER) 1128e5c31af7Sopenharmony_ci { 1129e5c31af7Sopenharmony_ci } 1130e5c31af7Sopenharmony_ci else if (m_storage == DrawTestSpec::STORAGE_BUFFER) 1131e5c31af7Sopenharmony_ci { 1132e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(target), m_glBuffer); 1133e5c31af7Sopenharmony_ci } 1134e5c31af7Sopenharmony_ci} 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_ci// DrawTestShaderProgram 1137e5c31af7Sopenharmony_ci 1138e5c31af7Sopenharmony_ciclass DrawTestShaderProgram : public sglr::ShaderProgram 1139e5c31af7Sopenharmony_ci{ 1140e5c31af7Sopenharmony_cipublic: 1141e5c31af7Sopenharmony_ci DrawTestShaderProgram (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays); 1142e5c31af7Sopenharmony_ci 1143e5c31af7Sopenharmony_ci void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const; 1144e5c31af7Sopenharmony_ci void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const; 1145e5c31af7Sopenharmony_ci 1146e5c31af7Sopenharmony_ciprivate: 1147e5c31af7Sopenharmony_ci static std::string genVertexSource (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays); 1148e5c31af7Sopenharmony_ci static std::string genFragmentSource (const glu::RenderContext& ctx); 1149e5c31af7Sopenharmony_ci static void generateShaderParams (std::map<std::string, std::string>& params, glu::ContextType type); 1150e5c31af7Sopenharmony_ci static rr::GenericVecType mapOutputType (const DrawTestSpec::OutputType& type); 1151e5c31af7Sopenharmony_ci static int getComponentCount (const DrawTestSpec::OutputType& type); 1152e5c31af7Sopenharmony_ci 1153e5c31af7Sopenharmony_ci static sglr::pdec::ShaderProgramDeclaration createProgramDeclaration (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays); 1154e5c31af7Sopenharmony_ci 1155e5c31af7Sopenharmony_ci std::vector<int> m_componentCount; 1156e5c31af7Sopenharmony_ci std::vector<bool> m_isCoord; 1157e5c31af7Sopenharmony_ci std::vector<rr::GenericVecType> m_attrType; 1158e5c31af7Sopenharmony_ci}; 1159e5c31af7Sopenharmony_ci 1160e5c31af7Sopenharmony_ciDrawTestShaderProgram::DrawTestShaderProgram (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays) 1161e5c31af7Sopenharmony_ci : sglr::ShaderProgram (createProgramDeclaration(ctx, arrays)) 1162e5c31af7Sopenharmony_ci , m_componentCount (arrays.size()) 1163e5c31af7Sopenharmony_ci , m_isCoord (arrays.size()) 1164e5c31af7Sopenharmony_ci , m_attrType (arrays.size()) 1165e5c31af7Sopenharmony_ci{ 1166e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 1167e5c31af7Sopenharmony_ci { 1168e5c31af7Sopenharmony_ci m_componentCount[arrayNdx] = getComponentCount(arrays[arrayNdx]->getOutputType()); 1169e5c31af7Sopenharmony_ci m_isCoord[arrayNdx] = arrays[arrayNdx]->isPositionAttribute(); 1170e5c31af7Sopenharmony_ci m_attrType[arrayNdx] = mapOutputType(arrays[arrayNdx]->getOutputType()); 1171e5c31af7Sopenharmony_ci } 1172e5c31af7Sopenharmony_ci} 1173e5c31af7Sopenharmony_ci 1174e5c31af7Sopenharmony_citemplate <typename T> 1175e5c31af7Sopenharmony_civoid calcShaderColorCoord (tcu::Vec2& coord, tcu::Vec3& color, const tcu::Vector<T, 4>& attribValue, bool isCoordinate, int numComponents) 1176e5c31af7Sopenharmony_ci{ 1177e5c31af7Sopenharmony_ci if (isCoordinate) 1178e5c31af7Sopenharmony_ci switch (numComponents) 1179e5c31af7Sopenharmony_ci { 1180e5c31af7Sopenharmony_ci case 1: coord += tcu::Vec2((float)attribValue.x(), (float)attribValue.x()); break; 1181e5c31af7Sopenharmony_ci case 2: coord += tcu::Vec2((float)attribValue.x(), (float)attribValue.y()); break; 1182e5c31af7Sopenharmony_ci case 3: coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(), (float)attribValue.y()); break; 1183e5c31af7Sopenharmony_ci case 4: coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(), (float)attribValue.y() + (float)attribValue.w()); break; 1184e5c31af7Sopenharmony_ci 1185e5c31af7Sopenharmony_ci default: 1186e5c31af7Sopenharmony_ci DE_ASSERT(false); 1187e5c31af7Sopenharmony_ci } 1188e5c31af7Sopenharmony_ci else 1189e5c31af7Sopenharmony_ci { 1190e5c31af7Sopenharmony_ci switch (numComponents) 1191e5c31af7Sopenharmony_ci { 1192e5c31af7Sopenharmony_ci case 1: 1193e5c31af7Sopenharmony_ci color = color * (float)attribValue.x(); 1194e5c31af7Sopenharmony_ci break; 1195e5c31af7Sopenharmony_ci 1196e5c31af7Sopenharmony_ci case 2: 1197e5c31af7Sopenharmony_ci color.x() = color.x() * (float)attribValue.x(); 1198e5c31af7Sopenharmony_ci color.y() = color.y() * (float)attribValue.y(); 1199e5c31af7Sopenharmony_ci break; 1200e5c31af7Sopenharmony_ci 1201e5c31af7Sopenharmony_ci case 3: 1202e5c31af7Sopenharmony_ci color.x() = color.x() * (float)attribValue.x(); 1203e5c31af7Sopenharmony_ci color.y() = color.y() * (float)attribValue.y(); 1204e5c31af7Sopenharmony_ci color.z() = color.z() * (float)attribValue.z(); 1205e5c31af7Sopenharmony_ci break; 1206e5c31af7Sopenharmony_ci 1207e5c31af7Sopenharmony_ci case 4: 1208e5c31af7Sopenharmony_ci color.x() = color.x() * (float)attribValue.x() * (float)attribValue.w(); 1209e5c31af7Sopenharmony_ci color.y() = color.y() * (float)attribValue.y() * (float)attribValue.w(); 1210e5c31af7Sopenharmony_ci color.z() = color.z() * (float)attribValue.z() * (float)attribValue.w(); 1211e5c31af7Sopenharmony_ci break; 1212e5c31af7Sopenharmony_ci 1213e5c31af7Sopenharmony_ci default: 1214e5c31af7Sopenharmony_ci DE_ASSERT(false); 1215e5c31af7Sopenharmony_ci } 1216e5c31af7Sopenharmony_ci } 1217e5c31af7Sopenharmony_ci} 1218e5c31af7Sopenharmony_ci 1219e5c31af7Sopenharmony_civoid DrawTestShaderProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 1220e5c31af7Sopenharmony_ci{ 1221e5c31af7Sopenharmony_ci const float u_coordScale = getUniformByName("u_coordScale").value.f; 1222e5c31af7Sopenharmony_ci const float u_colorScale = getUniformByName("u_colorScale").value.f; 1223e5c31af7Sopenharmony_ci 1224e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 1225e5c31af7Sopenharmony_ci { 1226e5c31af7Sopenharmony_ci const size_t varyingLocColor = 0; 1227e5c31af7Sopenharmony_ci 1228e5c31af7Sopenharmony_ci rr::VertexPacket& packet = *packets[packetNdx]; 1229e5c31af7Sopenharmony_ci 1230e5c31af7Sopenharmony_ci // Calc output color 1231e5c31af7Sopenharmony_ci tcu::Vec2 coord = tcu::Vec2(0.0, 0.0); 1232e5c31af7Sopenharmony_ci tcu::Vec3 color = tcu::Vec3(1.0, 1.0, 1.0); 1233e5c31af7Sopenharmony_ci 1234e5c31af7Sopenharmony_ci for (int attribNdx = 0; attribNdx < (int)m_attrType.size(); attribNdx++) 1235e5c31af7Sopenharmony_ci { 1236e5c31af7Sopenharmony_ci const int numComponents = m_componentCount[attribNdx]; 1237e5c31af7Sopenharmony_ci const bool isCoord = m_isCoord[attribNdx]; 1238e5c31af7Sopenharmony_ci 1239e5c31af7Sopenharmony_ci switch (m_attrType[attribNdx]) 1240e5c31af7Sopenharmony_ci { 1241e5c31af7Sopenharmony_ci case rr::GENERICVECTYPE_FLOAT: calcShaderColorCoord(coord, color, rr::readVertexAttribFloat(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), isCoord, numComponents); break; 1242e5c31af7Sopenharmony_ci case rr::GENERICVECTYPE_INT32: calcShaderColorCoord(coord, color, rr::readVertexAttribInt (inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), isCoord, numComponents); break; 1243e5c31af7Sopenharmony_ci case rr::GENERICVECTYPE_UINT32: calcShaderColorCoord(coord, color, rr::readVertexAttribUint (inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), isCoord, numComponents); break; 1244e5c31af7Sopenharmony_ci default: 1245e5c31af7Sopenharmony_ci DE_ASSERT(false); 1246e5c31af7Sopenharmony_ci } 1247e5c31af7Sopenharmony_ci } 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci // Transform position 1250e5c31af7Sopenharmony_ci { 1251e5c31af7Sopenharmony_ci packet.position = tcu::Vec4(u_coordScale * coord.x(), u_coordScale * coord.y(), 1.0f, 1.0f); 1252e5c31af7Sopenharmony_ci packet.pointSize = 1.0f; 1253e5c31af7Sopenharmony_ci } 1254e5c31af7Sopenharmony_ci 1255e5c31af7Sopenharmony_ci // Pass color to FS 1256e5c31af7Sopenharmony_ci { 1257e5c31af7Sopenharmony_ci packet.outputs[varyingLocColor] = tcu::Vec4(u_colorScale * color.x(), u_colorScale * color.y(), u_colorScale * color.z(), 1.0f) * 0.5f + tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f); 1258e5c31af7Sopenharmony_ci } 1259e5c31af7Sopenharmony_ci } 1260e5c31af7Sopenharmony_ci} 1261e5c31af7Sopenharmony_ci 1262e5c31af7Sopenharmony_civoid DrawTestShaderProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 1263e5c31af7Sopenharmony_ci{ 1264e5c31af7Sopenharmony_ci const size_t varyingLocColor = 0; 1265e5c31af7Sopenharmony_ci 1266e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 1267e5c31af7Sopenharmony_ci { 1268e5c31af7Sopenharmony_ci rr::FragmentPacket& packet = packets[packetNdx]; 1269e5c31af7Sopenharmony_ci 1270e5c31af7Sopenharmony_ci for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 1271e5c31af7Sopenharmony_ci rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readVarying<float>(packet, context, varyingLocColor, fragNdx)); 1272e5c31af7Sopenharmony_ci } 1273e5c31af7Sopenharmony_ci} 1274e5c31af7Sopenharmony_ci 1275e5c31af7Sopenharmony_cistd::string DrawTestShaderProgram::genVertexSource (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays) 1276e5c31af7Sopenharmony_ci{ 1277e5c31af7Sopenharmony_ci std::map<std::string, std::string> params; 1278e5c31af7Sopenharmony_ci std::stringstream vertexShaderTmpl; 1279e5c31af7Sopenharmony_ci 1280e5c31af7Sopenharmony_ci generateShaderParams(params, ctx.getType()); 1281e5c31af7Sopenharmony_ci 1282e5c31af7Sopenharmony_ci vertexShaderTmpl << "${VTX_HDR}"; 1283e5c31af7Sopenharmony_ci 1284e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 1285e5c31af7Sopenharmony_ci { 1286e5c31af7Sopenharmony_ci vertexShaderTmpl 1287e5c31af7Sopenharmony_ci << "${VTX_IN} highp " << outputTypeToGLType(arrays[arrayNdx]->getOutputType()) << " a_" << arrayNdx << ";\n"; 1288e5c31af7Sopenharmony_ci } 1289e5c31af7Sopenharmony_ci 1290e5c31af7Sopenharmony_ci vertexShaderTmpl << 1291e5c31af7Sopenharmony_ci "uniform highp float u_coordScale;\n" 1292e5c31af7Sopenharmony_ci "uniform highp float u_colorScale;\n" 1293e5c31af7Sopenharmony_ci "${VTX_OUT} ${COL_PRECISION} vec4 v_color;\n" 1294e5c31af7Sopenharmony_ci "void main(void)\n" 1295e5c31af7Sopenharmony_ci "{\n" 1296e5c31af7Sopenharmony_ci "\tgl_PointSize = 1.0;\n" 1297e5c31af7Sopenharmony_ci "\thighp vec2 coord = vec2(0.0, 0.0);\n" 1298e5c31af7Sopenharmony_ci "\thighp vec3 color = vec3(1.0, 1.0, 1.0);\n"; 1299e5c31af7Sopenharmony_ci 1300e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 1301e5c31af7Sopenharmony_ci { 1302e5c31af7Sopenharmony_ci const bool isPositionAttr = arrays[arrayNdx]->isPositionAttribute(); 1303e5c31af7Sopenharmony_ci 1304e5c31af7Sopenharmony_ci if (isPositionAttr) 1305e5c31af7Sopenharmony_ci { 1306e5c31af7Sopenharmony_ci switch (arrays[arrayNdx]->getOutputType()) 1307e5c31af7Sopenharmony_ci { 1308e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_FLOAT): 1309e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_INT): 1310e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UINT): 1311e5c31af7Sopenharmony_ci vertexShaderTmpl << 1312e5c31af7Sopenharmony_ci "\tcoord += vec2(float(a_" << arrayNdx << "), float(a_" << arrayNdx << "));\n"; 1313e5c31af7Sopenharmony_ci break; 1314e5c31af7Sopenharmony_ci 1315e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC2): 1316e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC2): 1317e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC2): 1318e5c31af7Sopenharmony_ci vertexShaderTmpl << 1319e5c31af7Sopenharmony_ci "\tcoord += vec2(a_" << arrayNdx << ".xy);\n"; 1320e5c31af7Sopenharmony_ci break; 1321e5c31af7Sopenharmony_ci 1322e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC3): 1323e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC3): 1324e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC3): 1325e5c31af7Sopenharmony_ci vertexShaderTmpl << 1326e5c31af7Sopenharmony_ci "\tcoord += vec2(a_" << arrayNdx << ".xy);\n" 1327e5c31af7Sopenharmony_ci "\tcoord.x += float(a_" << arrayNdx << ".z);\n"; 1328e5c31af7Sopenharmony_ci break; 1329e5c31af7Sopenharmony_ci 1330e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC4): 1331e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC4): 1332e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC4): 1333e5c31af7Sopenharmony_ci vertexShaderTmpl << 1334e5c31af7Sopenharmony_ci "\tcoord += vec2(a_" << arrayNdx << ".xy);\n" 1335e5c31af7Sopenharmony_ci "\tcoord += vec2(a_" << arrayNdx << ".zw);\n"; 1336e5c31af7Sopenharmony_ci break; 1337e5c31af7Sopenharmony_ci 1338e5c31af7Sopenharmony_ci default: 1339e5c31af7Sopenharmony_ci DE_ASSERT(false); 1340e5c31af7Sopenharmony_ci break; 1341e5c31af7Sopenharmony_ci } 1342e5c31af7Sopenharmony_ci } 1343e5c31af7Sopenharmony_ci else 1344e5c31af7Sopenharmony_ci { 1345e5c31af7Sopenharmony_ci switch (arrays[arrayNdx]->getOutputType()) 1346e5c31af7Sopenharmony_ci { 1347e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_FLOAT): 1348e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_INT): 1349e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UINT): 1350e5c31af7Sopenharmony_ci vertexShaderTmpl << 1351e5c31af7Sopenharmony_ci "\tcolor = color * float(a_" << arrayNdx << ");\n"; 1352e5c31af7Sopenharmony_ci break; 1353e5c31af7Sopenharmony_ci 1354e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC2): 1355e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC2): 1356e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC2): 1357e5c31af7Sopenharmony_ci vertexShaderTmpl << 1358e5c31af7Sopenharmony_ci "\tcolor.rg = color.rg * vec2(a_" << arrayNdx << ".xy);\n"; 1359e5c31af7Sopenharmony_ci break; 1360e5c31af7Sopenharmony_ci 1361e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC3): 1362e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC3): 1363e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC3): 1364e5c31af7Sopenharmony_ci vertexShaderTmpl << 1365e5c31af7Sopenharmony_ci "\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz);\n"; 1366e5c31af7Sopenharmony_ci break; 1367e5c31af7Sopenharmony_ci 1368e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC4): 1369e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC4): 1370e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC4): 1371e5c31af7Sopenharmony_ci vertexShaderTmpl << 1372e5c31af7Sopenharmony_ci "\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz) * float(a_" << arrayNdx << ".w);\n"; 1373e5c31af7Sopenharmony_ci break; 1374e5c31af7Sopenharmony_ci 1375e5c31af7Sopenharmony_ci default: 1376e5c31af7Sopenharmony_ci DE_ASSERT(false); 1377e5c31af7Sopenharmony_ci break; 1378e5c31af7Sopenharmony_ci } 1379e5c31af7Sopenharmony_ci } 1380e5c31af7Sopenharmony_ci } 1381e5c31af7Sopenharmony_ci 1382e5c31af7Sopenharmony_ci vertexShaderTmpl << 1383e5c31af7Sopenharmony_ci "\tv_color = vec4(u_colorScale * color, 1.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);\n" 1384e5c31af7Sopenharmony_ci "\tgl_Position = vec4(u_coordScale * coord, 1.0, 1.0);\n" 1385e5c31af7Sopenharmony_ci "}\n"; 1386e5c31af7Sopenharmony_ci 1387e5c31af7Sopenharmony_ci return tcu::StringTemplate(vertexShaderTmpl.str().c_str()).specialize(params); 1388e5c31af7Sopenharmony_ci} 1389e5c31af7Sopenharmony_ci 1390e5c31af7Sopenharmony_cistd::string DrawTestShaderProgram::genFragmentSource (const glu::RenderContext& ctx) 1391e5c31af7Sopenharmony_ci{ 1392e5c31af7Sopenharmony_ci std::map<std::string, std::string> params; 1393e5c31af7Sopenharmony_ci 1394e5c31af7Sopenharmony_ci generateShaderParams(params, ctx.getType()); 1395e5c31af7Sopenharmony_ci 1396e5c31af7Sopenharmony_ci static const char* fragmentShaderTmpl = 1397e5c31af7Sopenharmony_ci "${FRAG_HDR}" 1398e5c31af7Sopenharmony_ci "${FRAG_IN} ${COL_PRECISION} vec4 v_color;\n" 1399e5c31af7Sopenharmony_ci "void main(void)\n" 1400e5c31af7Sopenharmony_ci "{\n" 1401e5c31af7Sopenharmony_ci "\t${FRAG_COLOR} = v_color;\n" 1402e5c31af7Sopenharmony_ci "}\n"; 1403e5c31af7Sopenharmony_ci 1404e5c31af7Sopenharmony_ci return tcu::StringTemplate(fragmentShaderTmpl).specialize(params); 1405e5c31af7Sopenharmony_ci} 1406e5c31af7Sopenharmony_ci 1407e5c31af7Sopenharmony_civoid DrawTestShaderProgram::generateShaderParams (std::map<std::string, std::string>& params, glu::ContextType type) 1408e5c31af7Sopenharmony_ci{ 1409e5c31af7Sopenharmony_ci if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_300_ES)) 1410e5c31af7Sopenharmony_ci { 1411e5c31af7Sopenharmony_ci params["VTX_IN"] = "in"; 1412e5c31af7Sopenharmony_ci params["VTX_OUT"] = "out"; 1413e5c31af7Sopenharmony_ci params["FRAG_IN"] = "in"; 1414e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "dEQP_FragColor"; 1415e5c31af7Sopenharmony_ci params["VTX_HDR"] = "#version 300 es\n"; 1416e5c31af7Sopenharmony_ci params["FRAG_HDR"] = "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 1417e5c31af7Sopenharmony_ci params["COL_PRECISION"] = "mediump"; 1418e5c31af7Sopenharmony_ci } 1419e5c31af7Sopenharmony_ci else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_100_ES)) 1420e5c31af7Sopenharmony_ci { 1421e5c31af7Sopenharmony_ci params["VTX_IN"] = "attribute"; 1422e5c31af7Sopenharmony_ci params["VTX_OUT"] = "varying"; 1423e5c31af7Sopenharmony_ci params["FRAG_IN"] = "varying"; 1424e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "gl_FragColor"; 1425e5c31af7Sopenharmony_ci params["VTX_HDR"] = ""; 1426e5c31af7Sopenharmony_ci params["FRAG_HDR"] = ""; 1427e5c31af7Sopenharmony_ci params["COL_PRECISION"] = "mediump"; 1428e5c31af7Sopenharmony_ci } 1429e5c31af7Sopenharmony_ci else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_430)) 1430e5c31af7Sopenharmony_ci { 1431e5c31af7Sopenharmony_ci params["VTX_IN"] = "in"; 1432e5c31af7Sopenharmony_ci params["VTX_OUT"] = "out"; 1433e5c31af7Sopenharmony_ci params["FRAG_IN"] = "in"; 1434e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "dEQP_FragColor"; 1435e5c31af7Sopenharmony_ci params["VTX_HDR"] = "#version 430\n"; 1436e5c31af7Sopenharmony_ci params["FRAG_HDR"] = "#version 430\nlayout(location = 0) out highp vec4 dEQP_FragColor;\n"; 1437e5c31af7Sopenharmony_ci params["COL_PRECISION"] = "highp"; 1438e5c31af7Sopenharmony_ci } 1439e5c31af7Sopenharmony_ci else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_330)) 1440e5c31af7Sopenharmony_ci { 1441e5c31af7Sopenharmony_ci params["VTX_IN"] = "in"; 1442e5c31af7Sopenharmony_ci params["VTX_OUT"] = "out"; 1443e5c31af7Sopenharmony_ci params["FRAG_IN"] = "in"; 1444e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "dEQP_FragColor"; 1445e5c31af7Sopenharmony_ci params["VTX_HDR"] = "#version 330\n"; 1446e5c31af7Sopenharmony_ci params["FRAG_HDR"] = "#version 330\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 1447e5c31af7Sopenharmony_ci params["COL_PRECISION"] = "mediump"; 1448e5c31af7Sopenharmony_ci } 1449e5c31af7Sopenharmony_ci else 1450e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1451e5c31af7Sopenharmony_ci} 1452e5c31af7Sopenharmony_ci 1453e5c31af7Sopenharmony_cirr::GenericVecType DrawTestShaderProgram::mapOutputType (const DrawTestSpec::OutputType& type) 1454e5c31af7Sopenharmony_ci{ 1455e5c31af7Sopenharmony_ci switch (type) 1456e5c31af7Sopenharmony_ci { 1457e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_FLOAT): 1458e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC2): 1459e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC3): 1460e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC4): 1461e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_FLOAT; 1462e5c31af7Sopenharmony_ci 1463e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_INT): 1464e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC2): 1465e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC3): 1466e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC4): 1467e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_INT32; 1468e5c31af7Sopenharmony_ci 1469e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UINT): 1470e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC2): 1471e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC3): 1472e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC4): 1473e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_UINT32; 1474e5c31af7Sopenharmony_ci 1475e5c31af7Sopenharmony_ci default: 1476e5c31af7Sopenharmony_ci DE_ASSERT(false); 1477e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_LAST; 1478e5c31af7Sopenharmony_ci } 1479e5c31af7Sopenharmony_ci} 1480e5c31af7Sopenharmony_ci 1481e5c31af7Sopenharmony_ciint DrawTestShaderProgram::getComponentCount (const DrawTestSpec::OutputType& type) 1482e5c31af7Sopenharmony_ci{ 1483e5c31af7Sopenharmony_ci switch (type) 1484e5c31af7Sopenharmony_ci { 1485e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_FLOAT): 1486e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_INT): 1487e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UINT): 1488e5c31af7Sopenharmony_ci return 1; 1489e5c31af7Sopenharmony_ci 1490e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC2): 1491e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC2): 1492e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC2): 1493e5c31af7Sopenharmony_ci return 2; 1494e5c31af7Sopenharmony_ci 1495e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC3): 1496e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC3): 1497e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC3): 1498e5c31af7Sopenharmony_ci return 3; 1499e5c31af7Sopenharmony_ci 1500e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_VEC4): 1501e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_IVEC4): 1502e5c31af7Sopenharmony_ci case (DrawTestSpec::OUTPUTTYPE_UVEC4): 1503e5c31af7Sopenharmony_ci return 4; 1504e5c31af7Sopenharmony_ci 1505e5c31af7Sopenharmony_ci default: 1506e5c31af7Sopenharmony_ci DE_ASSERT(false); 1507e5c31af7Sopenharmony_ci return 0; 1508e5c31af7Sopenharmony_ci } 1509e5c31af7Sopenharmony_ci} 1510e5c31af7Sopenharmony_ci 1511e5c31af7Sopenharmony_cisglr::pdec::ShaderProgramDeclaration DrawTestShaderProgram::createProgramDeclaration (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays) 1512e5c31af7Sopenharmony_ci{ 1513e5c31af7Sopenharmony_ci sglr::pdec::ShaderProgramDeclaration decl; 1514e5c31af7Sopenharmony_ci 1515e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 1516e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexAttribute(std::string("a_") + de::toString(arrayNdx), mapOutputType(arrays[arrayNdx]->getOutputType())); 1517e5c31af7Sopenharmony_ci 1518e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT); 1519e5c31af7Sopenharmony_ci decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT); 1520e5c31af7Sopenharmony_ci 1521e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexSource(genVertexSource(ctx, arrays)); 1522e5c31af7Sopenharmony_ci decl << sglr::pdec::FragmentSource(genFragmentSource(ctx)); 1523e5c31af7Sopenharmony_ci 1524e5c31af7Sopenharmony_ci decl << sglr::pdec::Uniform("u_coordScale", glu::TYPE_FLOAT); 1525e5c31af7Sopenharmony_ci decl << sglr::pdec::Uniform("u_colorScale", glu::TYPE_FLOAT); 1526e5c31af7Sopenharmony_ci 1527e5c31af7Sopenharmony_ci return decl; 1528e5c31af7Sopenharmony_ci} 1529e5c31af7Sopenharmony_ci 1530e5c31af7Sopenharmony_ciclass RandomArrayGenerator 1531e5c31af7Sopenharmony_ci{ 1532e5c31af7Sopenharmony_cipublic: 1533e5c31af7Sopenharmony_ci static char* generateArray (int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type); 1534e5c31af7Sopenharmony_ci static char* generateIndices (int seed, int elementCount, DrawTestSpec::IndexType type, int offset, int min, int max, int indexBase); 1535e5c31af7Sopenharmony_ci static rr::GenericVec4 generateAttributeValue (int seed, DrawTestSpec::InputType type); 1536e5c31af7Sopenharmony_ci 1537e5c31af7Sopenharmony_ciprivate: 1538e5c31af7Sopenharmony_ci template<typename T> 1539e5c31af7Sopenharmony_ci static char* createIndices (int seed, int elementCount, int offset, int min, int max, int indexBase); 1540e5c31af7Sopenharmony_ci 1541e5c31af7Sopenharmony_ci static char* generateBasicArray (int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type); 1542e5c31af7Sopenharmony_ci template<typename T, typename GLType> 1543e5c31af7Sopenharmony_ci static char* createBasicArray (int seed, int elementCount, int componentCount, int offset, int stride); 1544e5c31af7Sopenharmony_ci static char* generatePackedArray (int seed, int elementCount, int componentCount, int offset, int stride); 1545e5c31af7Sopenharmony_ci}; 1546e5c31af7Sopenharmony_ci 1547e5c31af7Sopenharmony_cichar* RandomArrayGenerator::generateArray (int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type) 1548e5c31af7Sopenharmony_ci{ 1549e5c31af7Sopenharmony_ci if (type == DrawTestSpec::INPUTTYPE_INT_2_10_10_10 || type == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10) 1550e5c31af7Sopenharmony_ci return generatePackedArray(seed, elementCount, componentCount, offset, stride); 1551e5c31af7Sopenharmony_ci else 1552e5c31af7Sopenharmony_ci return generateBasicArray(seed, elementCount, componentCount, offset, stride, type); 1553e5c31af7Sopenharmony_ci} 1554e5c31af7Sopenharmony_ci 1555e5c31af7Sopenharmony_cichar* RandomArrayGenerator::generateBasicArray (int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type) 1556e5c31af7Sopenharmony_ci{ 1557e5c31af7Sopenharmony_ci switch (type) 1558e5c31af7Sopenharmony_ci { 1559e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_FLOAT: return createBasicArray<float, GLValue::Float> (seed, elementCount, componentCount, offset, stride); 1560e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_DOUBLE: return createBasicArray<double, GLValue::Double>(seed, elementCount, componentCount, offset, stride); 1561e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_SHORT: return createBasicArray<deInt16, GLValue::Short> (seed, elementCount, componentCount, offset, stride); 1562e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT: return createBasicArray<deUint16, GLValue::Ushort>(seed, elementCount, componentCount, offset, stride); 1563e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_BYTE: return createBasicArray<deInt8, GLValue::Byte> (seed, elementCount, componentCount, offset, stride); 1564e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE: return createBasicArray<deUint8, GLValue::Ubyte> (seed, elementCount, componentCount, offset, stride); 1565e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_FIXED: return createBasicArray<deInt32, GLValue::Fixed> (seed, elementCount, componentCount, offset, stride); 1566e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_INT: return createBasicArray<deInt32, GLValue::Int> (seed, elementCount, componentCount, offset, stride); 1567e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_INT: return createBasicArray<deUint32, GLValue::Uint> (seed, elementCount, componentCount, offset, stride); 1568e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_HALF: return createBasicArray<deFloat16, GLValue::Half> (seed, elementCount, componentCount, offset, stride); 1569e5c31af7Sopenharmony_ci default: 1570e5c31af7Sopenharmony_ci DE_ASSERT(false); 1571e5c31af7Sopenharmony_ci break; 1572e5c31af7Sopenharmony_ci } 1573e5c31af7Sopenharmony_ci return DE_NULL; 1574e5c31af7Sopenharmony_ci} 1575e5c31af7Sopenharmony_ci 1576e5c31af7Sopenharmony_ci#if (DE_COMPILER == DE_COMPILER_GCC) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) 1577e5c31af7Sopenharmony_ci // GCC 4.8/4.9 incorrectly emits array-bounds warning from createBasicArray() 1578e5c31af7Sopenharmony_ci# define GCC_ARRAY_BOUNDS_FALSE_NEGATIVE 1 1579e5c31af7Sopenharmony_ci#endif 1580e5c31af7Sopenharmony_ci 1581e5c31af7Sopenharmony_ci#if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE) 1582e5c31af7Sopenharmony_ci# pragma GCC diagnostic push 1583e5c31af7Sopenharmony_ci# pragma GCC diagnostic ignored "-Warray-bounds" 1584e5c31af7Sopenharmony_ci#endif 1585e5c31af7Sopenharmony_ci 1586e5c31af7Sopenharmony_citemplate<typename T, typename GLType> 1587e5c31af7Sopenharmony_cichar* RandomArrayGenerator::createBasicArray (int seed, int elementCount, int componentCount, int offset, int stride) 1588e5c31af7Sopenharmony_ci{ 1589e5c31af7Sopenharmony_ci DE_ASSERT(componentCount >= 1 && componentCount <= 4); 1590e5c31af7Sopenharmony_ci 1591e5c31af7Sopenharmony_ci const GLType min = extractGLValue<GLType>(GLValue::getMinValue(GLValueTypeTraits<GLType>::Type)); 1592e5c31af7Sopenharmony_ci const GLType max = extractGLValue<GLType>(GLValue::getMaxValue(GLValueTypeTraits<GLType>::Type)); 1593e5c31af7Sopenharmony_ci 1594e5c31af7Sopenharmony_ci const size_t componentSize = sizeof(T); 1595e5c31af7Sopenharmony_ci const size_t elementSize = componentSize * componentCount; 1596e5c31af7Sopenharmony_ci const size_t bufferSize = offset + (elementCount - 1) * stride + elementSize; 1597e5c31af7Sopenharmony_ci 1598e5c31af7Sopenharmony_ci char* data = new char[bufferSize]; 1599e5c31af7Sopenharmony_ci char* writePtr = data + offset; 1600e5c31af7Sopenharmony_ci 1601e5c31af7Sopenharmony_ci GLType previousComponents[4]; 1602e5c31af7Sopenharmony_ci 1603e5c31af7Sopenharmony_ci deRandom rnd; 1604e5c31af7Sopenharmony_ci deRandom_init(&rnd, seed); 1605e5c31af7Sopenharmony_ci 1606e5c31af7Sopenharmony_ci for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++) 1607e5c31af7Sopenharmony_ci { 1608e5c31af7Sopenharmony_ci GLType components[4]; 1609e5c31af7Sopenharmony_ci 1610e5c31af7Sopenharmony_ci for (int componentNdx = 0; componentNdx < componentCount; componentNdx++) 1611e5c31af7Sopenharmony_ci { 1612e5c31af7Sopenharmony_ci components[componentNdx] = getRandom<GLType>(rnd, min, max); 1613e5c31af7Sopenharmony_ci 1614e5c31af7Sopenharmony_ci // Try to not create vertex near previous 1615e5c31af7Sopenharmony_ci if (vertexNdx != 0 && abs(components[componentNdx] - previousComponents[componentNdx]) < minValue<GLType>()) 1616e5c31af7Sopenharmony_ci { 1617e5c31af7Sopenharmony_ci // Too close, try again (but only once) 1618e5c31af7Sopenharmony_ci components[componentNdx] = getRandom<GLType>(rnd, min, max); 1619e5c31af7Sopenharmony_ci } 1620e5c31af7Sopenharmony_ci } 1621e5c31af7Sopenharmony_ci 1622e5c31af7Sopenharmony_ci for (int componentNdx = 0; componentNdx < componentCount; componentNdx++) 1623e5c31af7Sopenharmony_ci previousComponents[componentNdx] = components[componentNdx]; 1624e5c31af7Sopenharmony_ci 1625e5c31af7Sopenharmony_ci for (int componentNdx = 0; componentNdx < componentCount; componentNdx++) 1626e5c31af7Sopenharmony_ci alignmentSafeAssignment(writePtr + componentNdx*componentSize, components[componentNdx].getValue()); 1627e5c31af7Sopenharmony_ci 1628e5c31af7Sopenharmony_ci writePtr += stride; 1629e5c31af7Sopenharmony_ci } 1630e5c31af7Sopenharmony_ci 1631e5c31af7Sopenharmony_ci return data; 1632e5c31af7Sopenharmony_ci} 1633e5c31af7Sopenharmony_ci 1634e5c31af7Sopenharmony_ci#if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE) 1635e5c31af7Sopenharmony_ci# pragma GCC diagnostic pop 1636e5c31af7Sopenharmony_ci#endif 1637e5c31af7Sopenharmony_ci 1638e5c31af7Sopenharmony_cichar* RandomArrayGenerator::generatePackedArray (int seed, int elementCount, int componentCount, int offset, int stride) 1639e5c31af7Sopenharmony_ci{ 1640e5c31af7Sopenharmony_ci DE_ASSERT(componentCount == 4); 1641e5c31af7Sopenharmony_ci DE_UNREF(componentCount); 1642e5c31af7Sopenharmony_ci 1643e5c31af7Sopenharmony_ci const deUint32 limit10 = (1 << 10); 1644e5c31af7Sopenharmony_ci const deUint32 limit2 = (1 << 2); 1645e5c31af7Sopenharmony_ci const size_t elementSize = 4; 1646e5c31af7Sopenharmony_ci const size_t bufferSize = offset + (elementCount - 1) * stride + elementSize; 1647e5c31af7Sopenharmony_ci 1648e5c31af7Sopenharmony_ci char* data = new char[bufferSize]; 1649e5c31af7Sopenharmony_ci char* writePtr = data + offset; 1650e5c31af7Sopenharmony_ci 1651e5c31af7Sopenharmony_ci deRandom rnd; 1652e5c31af7Sopenharmony_ci deRandom_init(&rnd, seed); 1653e5c31af7Sopenharmony_ci 1654e5c31af7Sopenharmony_ci for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++) 1655e5c31af7Sopenharmony_ci { 1656e5c31af7Sopenharmony_ci const deUint32 x = deRandom_getUint32(&rnd) % limit10; 1657e5c31af7Sopenharmony_ci const deUint32 y = deRandom_getUint32(&rnd) % limit10; 1658e5c31af7Sopenharmony_ci const deUint32 z = deRandom_getUint32(&rnd) % limit10; 1659e5c31af7Sopenharmony_ci const deUint32 w = deRandom_getUint32(&rnd) % limit2; 1660e5c31af7Sopenharmony_ci const deUint32 packedValue = (w << 30) | (z << 20) | (y << 10) | (x); 1661e5c31af7Sopenharmony_ci 1662e5c31af7Sopenharmony_ci alignmentSafeAssignment(writePtr, packedValue); 1663e5c31af7Sopenharmony_ci writePtr += stride; 1664e5c31af7Sopenharmony_ci } 1665e5c31af7Sopenharmony_ci 1666e5c31af7Sopenharmony_ci return data; 1667e5c31af7Sopenharmony_ci} 1668e5c31af7Sopenharmony_ci 1669e5c31af7Sopenharmony_cichar* RandomArrayGenerator::generateIndices (int seed, int elementCount, DrawTestSpec::IndexType type, int offset, int min, int max, int indexBase) 1670e5c31af7Sopenharmony_ci{ 1671e5c31af7Sopenharmony_ci char* data = DE_NULL; 1672e5c31af7Sopenharmony_ci 1673e5c31af7Sopenharmony_ci switch (type) 1674e5c31af7Sopenharmony_ci { 1675e5c31af7Sopenharmony_ci case DrawTestSpec::INDEXTYPE_BYTE: 1676e5c31af7Sopenharmony_ci data = createIndices<deUint8>(seed, elementCount, offset, min, max, indexBase); 1677e5c31af7Sopenharmony_ci break; 1678e5c31af7Sopenharmony_ci 1679e5c31af7Sopenharmony_ci case DrawTestSpec::INDEXTYPE_SHORT: 1680e5c31af7Sopenharmony_ci data = createIndices<deUint16>(seed, elementCount, offset, min, max, indexBase); 1681e5c31af7Sopenharmony_ci break; 1682e5c31af7Sopenharmony_ci 1683e5c31af7Sopenharmony_ci case DrawTestSpec::INDEXTYPE_INT: 1684e5c31af7Sopenharmony_ci data = createIndices<deUint32>(seed, elementCount, offset, min, max, indexBase); 1685e5c31af7Sopenharmony_ci break; 1686e5c31af7Sopenharmony_ci 1687e5c31af7Sopenharmony_ci default: 1688e5c31af7Sopenharmony_ci DE_ASSERT(false); 1689e5c31af7Sopenharmony_ci break; 1690e5c31af7Sopenharmony_ci } 1691e5c31af7Sopenharmony_ci 1692e5c31af7Sopenharmony_ci return data; 1693e5c31af7Sopenharmony_ci} 1694e5c31af7Sopenharmony_ci 1695e5c31af7Sopenharmony_citemplate<typename T> 1696e5c31af7Sopenharmony_cichar* RandomArrayGenerator::createIndices (int seed, int elementCount, int offset, int min, int max, int indexBase) 1697e5c31af7Sopenharmony_ci{ 1698e5c31af7Sopenharmony_ci const size_t elementSize = sizeof(T); 1699e5c31af7Sopenharmony_ci const size_t bufferSize = offset + elementCount * elementSize; 1700e5c31af7Sopenharmony_ci 1701e5c31af7Sopenharmony_ci char* data = new char[bufferSize]; 1702e5c31af7Sopenharmony_ci char* writePtr = data + offset; 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci deUint32 oldNdx1 = deUint32(-1); 1705e5c31af7Sopenharmony_ci deUint32 oldNdx2 = deUint32(-1); 1706e5c31af7Sopenharmony_ci 1707e5c31af7Sopenharmony_ci deRandom rnd; 1708e5c31af7Sopenharmony_ci deRandom_init(&rnd, seed); 1709e5c31af7Sopenharmony_ci 1710e5c31af7Sopenharmony_ci DE_ASSERT(indexBase >= 0); // watch for underflows 1711e5c31af7Sopenharmony_ci 1712e5c31af7Sopenharmony_ci if (min < 0 || (size_t)min > std::numeric_limits<T>::max() || 1713e5c31af7Sopenharmony_ci max < 0 || (size_t)max > std::numeric_limits<T>::max() || 1714e5c31af7Sopenharmony_ci min > max) 1715e5c31af7Sopenharmony_ci DE_FATAL("Invalid range"); 1716e5c31af7Sopenharmony_ci 1717e5c31af7Sopenharmony_ci for (int elementNdx = 0; elementNdx < elementCount; ++elementNdx) 1718e5c31af7Sopenharmony_ci { 1719e5c31af7Sopenharmony_ci deUint32 ndx = getRandom(rnd, GLValue::Uint::create(min), GLValue::Uint::create(max)).getValue(); 1720e5c31af7Sopenharmony_ci 1721e5c31af7Sopenharmony_ci // Try not to generate same index as any of previous two. This prevents 1722e5c31af7Sopenharmony_ci // generation of degenerate triangles and lines. If [min, max] is too 1723e5c31af7Sopenharmony_ci // small this cannot be guaranteed. 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_ci if (ndx == oldNdx1) ++ndx; 1726e5c31af7Sopenharmony_ci if (ndx > (deUint32)max) ndx = min; 1727e5c31af7Sopenharmony_ci if (ndx == oldNdx2) ++ndx; 1728e5c31af7Sopenharmony_ci if (ndx > (deUint32)max) ndx = min; 1729e5c31af7Sopenharmony_ci if (ndx == oldNdx1) ++ndx; 1730e5c31af7Sopenharmony_ci if (ndx > (deUint32)max) ndx = min; 1731e5c31af7Sopenharmony_ci 1732e5c31af7Sopenharmony_ci oldNdx2 = oldNdx1; 1733e5c31af7Sopenharmony_ci oldNdx1 = ndx; 1734e5c31af7Sopenharmony_ci 1735e5c31af7Sopenharmony_ci ndx += indexBase; 1736e5c31af7Sopenharmony_ci 1737e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(writePtr + elementSize * elementNdx, T(ndx)); 1738e5c31af7Sopenharmony_ci } 1739e5c31af7Sopenharmony_ci 1740e5c31af7Sopenharmony_ci return data; 1741e5c31af7Sopenharmony_ci} 1742e5c31af7Sopenharmony_ci 1743e5c31af7Sopenharmony_cirr::GenericVec4 RandomArrayGenerator::generateAttributeValue (int seed, DrawTestSpec::InputType type) 1744e5c31af7Sopenharmony_ci{ 1745e5c31af7Sopenharmony_ci de::Random random(seed); 1746e5c31af7Sopenharmony_ci 1747e5c31af7Sopenharmony_ci switch (type) 1748e5c31af7Sopenharmony_ci { 1749e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_FLOAT: 1750e5c31af7Sopenharmony_ci return rr::GenericVec4(generateRandomVec4(random)); 1751e5c31af7Sopenharmony_ci 1752e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_INT: 1753e5c31af7Sopenharmony_ci return rr::GenericVec4(generateRandomIVec4(random)); 1754e5c31af7Sopenharmony_ci 1755e5c31af7Sopenharmony_ci case DrawTestSpec::INPUTTYPE_UNSIGNED_INT: 1756e5c31af7Sopenharmony_ci return rr::GenericVec4(generateRandomUVec4(random)); 1757e5c31af7Sopenharmony_ci 1758e5c31af7Sopenharmony_ci default: 1759e5c31af7Sopenharmony_ci DE_ASSERT(false); 1760e5c31af7Sopenharmony_ci return rr::GenericVec4(tcu::Vec4(1, 1, 1, 1)); 1761e5c31af7Sopenharmony_ci } 1762e5c31af7Sopenharmony_ci} 1763e5c31af7Sopenharmony_ci 1764e5c31af7Sopenharmony_ci} // anonymous 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci// AttributePack 1767e5c31af7Sopenharmony_ci 1768e5c31af7Sopenharmony_ciclass AttributePack 1769e5c31af7Sopenharmony_ci{ 1770e5c31af7Sopenharmony_cipublic: 1771e5c31af7Sopenharmony_ci 1772e5c31af7Sopenharmony_ci AttributePack (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, sglr::Context& drawContext, const tcu::UVec2& screenSize, bool useVao, bool logEnabled); 1773e5c31af7Sopenharmony_ci ~AttributePack (void); 1774e5c31af7Sopenharmony_ci 1775e5c31af7Sopenharmony_ci AttributeArray* getArray (int i); 1776e5c31af7Sopenharmony_ci int getArrayCount (void); 1777e5c31af7Sopenharmony_ci 1778e5c31af7Sopenharmony_ci void newArray (DrawTestSpec::Storage storage); 1779e5c31af7Sopenharmony_ci void clearArrays (void); 1780e5c31af7Sopenharmony_ci void updateProgram (void); 1781e5c31af7Sopenharmony_ci 1782e5c31af7Sopenharmony_ci void render (DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex, int vertexCount, DrawTestSpec::IndexType indexType, const void* indexOffset, int rangeStart, int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale, float colorScale, AttributeArray* indexArray); 1783e5c31af7Sopenharmony_ci 1784e5c31af7Sopenharmony_ci const tcu::Surface& getSurface (void) const { return m_screen; } 1785e5c31af7Sopenharmony_ciprivate: 1786e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 1787e5c31af7Sopenharmony_ci glu::RenderContext& m_renderCtx; 1788e5c31af7Sopenharmony_ci sglr::Context& m_ctx; 1789e5c31af7Sopenharmony_ci 1790e5c31af7Sopenharmony_ci std::vector<AttributeArray*>m_arrays; 1791e5c31af7Sopenharmony_ci sglr::ShaderProgram* m_program; 1792e5c31af7Sopenharmony_ci tcu::Surface m_screen; 1793e5c31af7Sopenharmony_ci const bool m_useVao; 1794e5c31af7Sopenharmony_ci const bool m_logEnabled; 1795e5c31af7Sopenharmony_ci deUint32 m_programID; 1796e5c31af7Sopenharmony_ci deUint32 m_vaoID; 1797e5c31af7Sopenharmony_ci}; 1798e5c31af7Sopenharmony_ci 1799e5c31af7Sopenharmony_ciAttributePack::AttributePack (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, sglr::Context& drawContext, const tcu::UVec2& screenSize, bool useVao, bool logEnabled) 1800e5c31af7Sopenharmony_ci : m_testCtx (testCtx) 1801e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 1802e5c31af7Sopenharmony_ci , m_ctx (drawContext) 1803e5c31af7Sopenharmony_ci , m_program (DE_NULL) 1804e5c31af7Sopenharmony_ci , m_screen (screenSize.x(), screenSize.y()) 1805e5c31af7Sopenharmony_ci , m_useVao (useVao) 1806e5c31af7Sopenharmony_ci , m_logEnabled (logEnabled) 1807e5c31af7Sopenharmony_ci , m_programID (0) 1808e5c31af7Sopenharmony_ci , m_vaoID (0) 1809e5c31af7Sopenharmony_ci{ 1810e5c31af7Sopenharmony_ci if (m_useVao) 1811e5c31af7Sopenharmony_ci m_ctx.genVertexArrays(1, &m_vaoID); 1812e5c31af7Sopenharmony_ci} 1813e5c31af7Sopenharmony_ci 1814e5c31af7Sopenharmony_ciAttributePack::~AttributePack (void) 1815e5c31af7Sopenharmony_ci{ 1816e5c31af7Sopenharmony_ci clearArrays(); 1817e5c31af7Sopenharmony_ci 1818e5c31af7Sopenharmony_ci if (m_programID) 1819e5c31af7Sopenharmony_ci m_ctx.deleteProgram(m_programID); 1820e5c31af7Sopenharmony_ci 1821e5c31af7Sopenharmony_ci if (m_program) 1822e5c31af7Sopenharmony_ci delete m_program; 1823e5c31af7Sopenharmony_ci 1824e5c31af7Sopenharmony_ci if (m_useVao) 1825e5c31af7Sopenharmony_ci m_ctx.deleteVertexArrays(1, &m_vaoID); 1826e5c31af7Sopenharmony_ci} 1827e5c31af7Sopenharmony_ci 1828e5c31af7Sopenharmony_ciAttributeArray* AttributePack::getArray (int i) 1829e5c31af7Sopenharmony_ci{ 1830e5c31af7Sopenharmony_ci return m_arrays.at(i); 1831e5c31af7Sopenharmony_ci} 1832e5c31af7Sopenharmony_ci 1833e5c31af7Sopenharmony_ciint AttributePack::getArrayCount (void) 1834e5c31af7Sopenharmony_ci{ 1835e5c31af7Sopenharmony_ci return (int)m_arrays.size(); 1836e5c31af7Sopenharmony_ci} 1837e5c31af7Sopenharmony_ci 1838e5c31af7Sopenharmony_civoid AttributePack::newArray (DrawTestSpec::Storage storage) 1839e5c31af7Sopenharmony_ci{ 1840e5c31af7Sopenharmony_ci m_arrays.push_back(new AttributeArray(storage, m_ctx)); 1841e5c31af7Sopenharmony_ci} 1842e5c31af7Sopenharmony_ci 1843e5c31af7Sopenharmony_civoid AttributePack::clearArrays (void) 1844e5c31af7Sopenharmony_ci{ 1845e5c31af7Sopenharmony_ci for (std::vector<AttributeArray*>::iterator itr = m_arrays.begin(); itr != m_arrays.end(); itr++) 1846e5c31af7Sopenharmony_ci delete *itr; 1847e5c31af7Sopenharmony_ci m_arrays.clear(); 1848e5c31af7Sopenharmony_ci} 1849e5c31af7Sopenharmony_ci 1850e5c31af7Sopenharmony_civoid AttributePack::updateProgram (void) 1851e5c31af7Sopenharmony_ci{ 1852e5c31af7Sopenharmony_ci if (m_programID) 1853e5c31af7Sopenharmony_ci m_ctx.deleteProgram(m_programID); 1854e5c31af7Sopenharmony_ci if (m_program) 1855e5c31af7Sopenharmony_ci delete m_program; 1856e5c31af7Sopenharmony_ci 1857e5c31af7Sopenharmony_ci m_program = new DrawTestShaderProgram(m_renderCtx, m_arrays); 1858e5c31af7Sopenharmony_ci m_programID = m_ctx.createProgram(m_program); 1859e5c31af7Sopenharmony_ci} 1860e5c31af7Sopenharmony_ci 1861e5c31af7Sopenharmony_civoid AttributePack::render (DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex, int vertexCount, DrawTestSpec::IndexType indexType, const void* indexOffset, int rangeStart, int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale, float colorScale, AttributeArray* indexArray) 1862e5c31af7Sopenharmony_ci{ 1863e5c31af7Sopenharmony_ci DE_ASSERT(m_program != DE_NULL); 1864e5c31af7Sopenharmony_ci DE_ASSERT(m_programID != 0); 1865e5c31af7Sopenharmony_ci 1866e5c31af7Sopenharmony_ci m_ctx.viewport(0, 0, m_screen.getWidth(), m_screen.getHeight()); 1867e5c31af7Sopenharmony_ci m_ctx.clearColor(0.0, 0.0, 0.0, 1.0); 1868e5c31af7Sopenharmony_ci m_ctx.clear(GL_COLOR_BUFFER_BIT); 1869e5c31af7Sopenharmony_ci 1870e5c31af7Sopenharmony_ci m_ctx.useProgram(m_programID); 1871e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glUseProgram()"); 1872e5c31af7Sopenharmony_ci 1873e5c31af7Sopenharmony_ci m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_coordScale"), coordScale); 1874e5c31af7Sopenharmony_ci m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_colorScale"), colorScale); 1875e5c31af7Sopenharmony_ci 1876e5c31af7Sopenharmony_ci if (m_useVao) 1877e5c31af7Sopenharmony_ci m_ctx.bindVertexArray(m_vaoID); 1878e5c31af7Sopenharmony_ci 1879e5c31af7Sopenharmony_ci if (indexArray) 1880e5c31af7Sopenharmony_ci indexArray->bindIndexArray(DrawTestSpec::TARGET_ELEMENT_ARRAY); 1881e5c31af7Sopenharmony_ci 1882e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++) 1883e5c31af7Sopenharmony_ci { 1884e5c31af7Sopenharmony_ci std::stringstream attribName; 1885e5c31af7Sopenharmony_ci attribName << "a_" << arrayNdx; 1886e5c31af7Sopenharmony_ci 1887e5c31af7Sopenharmony_ci deUint32 loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str()); 1888e5c31af7Sopenharmony_ci 1889e5c31af7Sopenharmony_ci if (m_arrays[arrayNdx]->isBound()) 1890e5c31af7Sopenharmony_ci { 1891e5c31af7Sopenharmony_ci m_ctx.enableVertexAttribArray(loc); 1892e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glEnableVertexAttribArray()"); 1893e5c31af7Sopenharmony_ci } 1894e5c31af7Sopenharmony_ci 1895e5c31af7Sopenharmony_ci m_arrays[arrayNdx]->bindAttribute(loc); 1896e5c31af7Sopenharmony_ci } 1897e5c31af7Sopenharmony_ci 1898e5c31af7Sopenharmony_ci if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS) 1899e5c31af7Sopenharmony_ci { 1900e5c31af7Sopenharmony_ci m_ctx.drawArrays(primitiveToGL(primitive), firstVertex, vertexCount); 1901e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArrays()"); 1902e5c31af7Sopenharmony_ci } 1903e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED) 1904e5c31af7Sopenharmony_ci { 1905e5c31af7Sopenharmony_ci m_ctx.drawArraysInstanced(primitiveToGL(primitive), firstVertex, vertexCount, instanceCount); 1906e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysInstanced()"); 1907e5c31af7Sopenharmony_ci } 1908e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS) 1909e5c31af7Sopenharmony_ci { 1910e5c31af7Sopenharmony_ci m_ctx.drawElements(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset); 1911e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElements()"); 1912e5c31af7Sopenharmony_ci } 1913e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED) 1914e5c31af7Sopenharmony_ci { 1915e5c31af7Sopenharmony_ci m_ctx.drawRangeElements(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount, indexTypeToGL(indexType), indexOffset); 1916e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElements()"); 1917e5c31af7Sopenharmony_ci } 1918e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED) 1919e5c31af7Sopenharmony_ci { 1920e5c31af7Sopenharmony_ci m_ctx.drawElementsInstanced(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset, instanceCount); 1921e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstanced()"); 1922e5c31af7Sopenharmony_ci } 1923e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT) 1924e5c31af7Sopenharmony_ci { 1925e5c31af7Sopenharmony_ci struct DrawCommand 1926e5c31af7Sopenharmony_ci { 1927e5c31af7Sopenharmony_ci GLuint count; 1928e5c31af7Sopenharmony_ci GLuint primCount; 1929e5c31af7Sopenharmony_ci GLuint first; 1930e5c31af7Sopenharmony_ci GLuint reservedMustBeZero; 1931e5c31af7Sopenharmony_ci }; 1932e5c31af7Sopenharmony_ci deUint8* buffer = new deUint8[sizeof(DrawCommand) + indirectOffset]; 1933e5c31af7Sopenharmony_ci 1934e5c31af7Sopenharmony_ci { 1935e5c31af7Sopenharmony_ci DrawCommand command; 1936e5c31af7Sopenharmony_ci 1937e5c31af7Sopenharmony_ci command.count = vertexCount; 1938e5c31af7Sopenharmony_ci command.primCount = instanceCount; 1939e5c31af7Sopenharmony_ci command.first = firstVertex; 1940e5c31af7Sopenharmony_ci command.reservedMustBeZero = 0; 1941e5c31af7Sopenharmony_ci 1942e5c31af7Sopenharmony_ci memcpy(buffer + indirectOffset, &command, sizeof(command)); 1943e5c31af7Sopenharmony_ci 1944e5c31af7Sopenharmony_ci if (m_logEnabled) 1945e5c31af7Sopenharmony_ci m_testCtx.getLog() 1946e5c31af7Sopenharmony_ci << tcu::TestLog::Message 1947e5c31af7Sopenharmony_ci << "DrawArraysIndirectCommand:\n" 1948e5c31af7Sopenharmony_ci << "\tcount: " << command.count << "\n" 1949e5c31af7Sopenharmony_ci << "\tprimCount: " << command.primCount << "\n" 1950e5c31af7Sopenharmony_ci << "\tfirst: " << command.first << "\n" 1951e5c31af7Sopenharmony_ci << "\treservedMustBeZero: " << command.reservedMustBeZero << "\n" 1952e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1953e5c31af7Sopenharmony_ci } 1954e5c31af7Sopenharmony_ci 1955e5c31af7Sopenharmony_ci GLuint indirectBuf = 0; 1956e5c31af7Sopenharmony_ci m_ctx.genBuffers(1, &indirectBuf); 1957e5c31af7Sopenharmony_ci m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf); 1958e5c31af7Sopenharmony_ci m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW); 1959e5c31af7Sopenharmony_ci delete [] buffer; 1960e5c31af7Sopenharmony_ci 1961e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer"); 1962e5c31af7Sopenharmony_ci 1963e5c31af7Sopenharmony_ci m_ctx.drawArraysIndirect(primitiveToGL(primitive), glu::BufferOffsetAsPointer(indirectOffset)); 1964e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()"); 1965e5c31af7Sopenharmony_ci 1966e5c31af7Sopenharmony_ci m_ctx.deleteBuffers(1, &indirectBuf); 1967e5c31af7Sopenharmony_ci } 1968e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT) 1969e5c31af7Sopenharmony_ci { 1970e5c31af7Sopenharmony_ci struct DrawCommand 1971e5c31af7Sopenharmony_ci { 1972e5c31af7Sopenharmony_ci GLuint count; 1973e5c31af7Sopenharmony_ci GLuint primCount; 1974e5c31af7Sopenharmony_ci GLuint firstIndex; 1975e5c31af7Sopenharmony_ci GLint baseVertex; 1976e5c31af7Sopenharmony_ci GLuint reservedMustBeZero; 1977e5c31af7Sopenharmony_ci }; 1978e5c31af7Sopenharmony_ci deUint8* buffer = new deUint8[sizeof(DrawCommand) + indirectOffset]; 1979e5c31af7Sopenharmony_ci 1980e5c31af7Sopenharmony_ci { 1981e5c31af7Sopenharmony_ci DrawCommand command; 1982e5c31af7Sopenharmony_ci 1983e5c31af7Sopenharmony_ci // index offset must be converted to firstIndex by dividing with the index element size 1984e5c31af7Sopenharmony_ci const auto offsetAsInteger = reinterpret_cast<uintptr_t>(indexOffset); 1985e5c31af7Sopenharmony_ci DE_ASSERT(offsetAsInteger % gls::DrawTestSpec::indexTypeSize(indexType) == 0); // \note This is checked in spec validation 1986e5c31af7Sopenharmony_ci 1987e5c31af7Sopenharmony_ci command.count = vertexCount; 1988e5c31af7Sopenharmony_ci command.primCount = instanceCount; 1989e5c31af7Sopenharmony_ci command.firstIndex = (glw::GLuint)(offsetAsInteger / gls::DrawTestSpec::indexTypeSize(indexType)); 1990e5c31af7Sopenharmony_ci command.baseVertex = baseVertex; 1991e5c31af7Sopenharmony_ci command.reservedMustBeZero = 0; 1992e5c31af7Sopenharmony_ci 1993e5c31af7Sopenharmony_ci memcpy(buffer + indirectOffset, &command, sizeof(command)); 1994e5c31af7Sopenharmony_ci 1995e5c31af7Sopenharmony_ci if (m_logEnabled) 1996e5c31af7Sopenharmony_ci m_testCtx.getLog() 1997e5c31af7Sopenharmony_ci << tcu::TestLog::Message 1998e5c31af7Sopenharmony_ci << "DrawElementsIndirectCommand:\n" 1999e5c31af7Sopenharmony_ci << "\tcount: " << command.count << "\n" 2000e5c31af7Sopenharmony_ci << "\tprimCount: " << command.primCount << "\n" 2001e5c31af7Sopenharmony_ci << "\tfirstIndex: " << command.firstIndex << "\n" 2002e5c31af7Sopenharmony_ci << "\tbaseVertex: " << command.baseVertex << "\n" 2003e5c31af7Sopenharmony_ci << "\treservedMustBeZero: " << command.reservedMustBeZero << "\n" 2004e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2005e5c31af7Sopenharmony_ci } 2006e5c31af7Sopenharmony_ci 2007e5c31af7Sopenharmony_ci GLuint indirectBuf = 0; 2008e5c31af7Sopenharmony_ci m_ctx.genBuffers(1, &indirectBuf); 2009e5c31af7Sopenharmony_ci m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf); 2010e5c31af7Sopenharmony_ci m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW); 2011e5c31af7Sopenharmony_ci delete [] buffer; 2012e5c31af7Sopenharmony_ci 2013e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer"); 2014e5c31af7Sopenharmony_ci 2015e5c31af7Sopenharmony_ci m_ctx.drawElementsIndirect(primitiveToGL(primitive), indexTypeToGL(indexType), glu::BufferOffsetAsPointer(indirectOffset)); 2016e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()"); 2017e5c31af7Sopenharmony_ci 2018e5c31af7Sopenharmony_ci m_ctx.deleteBuffers(1, &indirectBuf); 2019e5c31af7Sopenharmony_ci } 2020e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX) 2021e5c31af7Sopenharmony_ci { 2022e5c31af7Sopenharmony_ci m_ctx.drawElementsBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset, baseVertex); 2023e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsBaseVertex()"); 2024e5c31af7Sopenharmony_ci } 2025e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX) 2026e5c31af7Sopenharmony_ci { 2027e5c31af7Sopenharmony_ci m_ctx.drawElementsInstancedBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset, instanceCount, baseVertex); 2028e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstancedBaseVertex()"); 2029e5c31af7Sopenharmony_ci } 2030e5c31af7Sopenharmony_ci else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX) 2031e5c31af7Sopenharmony_ci { 2032e5c31af7Sopenharmony_ci m_ctx.drawRangeElementsBaseVertex(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount, indexTypeToGL(indexType), indexOffset, baseVertex); 2033e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElementsBaseVertex()"); 2034e5c31af7Sopenharmony_ci } 2035e5c31af7Sopenharmony_ci else 2036e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2037e5c31af7Sopenharmony_ci 2038e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++) 2039e5c31af7Sopenharmony_ci { 2040e5c31af7Sopenharmony_ci if (m_arrays[arrayNdx]->isBound()) 2041e5c31af7Sopenharmony_ci { 2042e5c31af7Sopenharmony_ci std::stringstream attribName; 2043e5c31af7Sopenharmony_ci attribName << "a_" << arrayNdx; 2044e5c31af7Sopenharmony_ci 2045e5c31af7Sopenharmony_ci deUint32 loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str()); 2046e5c31af7Sopenharmony_ci 2047e5c31af7Sopenharmony_ci m_ctx.disableVertexAttribArray(loc); 2048e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDisableVertexAttribArray()"); 2049e5c31af7Sopenharmony_ci } 2050e5c31af7Sopenharmony_ci } 2051e5c31af7Sopenharmony_ci 2052e5c31af7Sopenharmony_ci if (m_useVao) 2053e5c31af7Sopenharmony_ci m_ctx.bindVertexArray(0); 2054e5c31af7Sopenharmony_ci 2055e5c31af7Sopenharmony_ci m_ctx.useProgram(0); 2056e5c31af7Sopenharmony_ci m_ctx.readPixels(m_screen, 0, 0, m_screen.getWidth(), m_screen.getHeight()); 2057e5c31af7Sopenharmony_ci} 2058e5c31af7Sopenharmony_ci 2059e5c31af7Sopenharmony_ci// DrawTestSpec 2060e5c31af7Sopenharmony_ci 2061e5c31af7Sopenharmony_ciDrawTestSpec::AttributeSpec DrawTestSpec::AttributeSpec::createAttributeArray (InputType inputType, OutputType outputType, Storage storage, Usage usage, int componentCount, int offset, int stride, bool normalize, int instanceDivisor) 2062e5c31af7Sopenharmony_ci{ 2063e5c31af7Sopenharmony_ci DrawTestSpec::AttributeSpec spec; 2064e5c31af7Sopenharmony_ci 2065e5c31af7Sopenharmony_ci spec.inputType = inputType; 2066e5c31af7Sopenharmony_ci spec.outputType = outputType; 2067e5c31af7Sopenharmony_ci spec.storage = storage; 2068e5c31af7Sopenharmony_ci spec.usage = usage; 2069e5c31af7Sopenharmony_ci spec.componentCount = componentCount; 2070e5c31af7Sopenharmony_ci spec.offset = offset; 2071e5c31af7Sopenharmony_ci spec.stride = stride; 2072e5c31af7Sopenharmony_ci spec.normalize = normalize; 2073e5c31af7Sopenharmony_ci spec.instanceDivisor = instanceDivisor; 2074e5c31af7Sopenharmony_ci 2075e5c31af7Sopenharmony_ci spec.useDefaultAttribute= false; 2076e5c31af7Sopenharmony_ci 2077e5c31af7Sopenharmony_ci return spec; 2078e5c31af7Sopenharmony_ci} 2079e5c31af7Sopenharmony_ci 2080e5c31af7Sopenharmony_ciDrawTestSpec::AttributeSpec DrawTestSpec::AttributeSpec::createDefaultAttribute (InputType inputType, OutputType outputType, int componentCount) 2081e5c31af7Sopenharmony_ci{ 2082e5c31af7Sopenharmony_ci DE_ASSERT(inputType == INPUTTYPE_INT || inputType == INPUTTYPE_UNSIGNED_INT || inputType == INPUTTYPE_FLOAT); 2083e5c31af7Sopenharmony_ci DE_ASSERT(inputType == INPUTTYPE_FLOAT || componentCount == 4); 2084e5c31af7Sopenharmony_ci 2085e5c31af7Sopenharmony_ci DrawTestSpec::AttributeSpec spec; 2086e5c31af7Sopenharmony_ci 2087e5c31af7Sopenharmony_ci spec.inputType = inputType; 2088e5c31af7Sopenharmony_ci spec.outputType = outputType; 2089e5c31af7Sopenharmony_ci spec.storage = DrawTestSpec::STORAGE_LAST; 2090e5c31af7Sopenharmony_ci spec.usage = DrawTestSpec::USAGE_LAST; 2091e5c31af7Sopenharmony_ci spec.componentCount = componentCount; 2092e5c31af7Sopenharmony_ci spec.offset = 0; 2093e5c31af7Sopenharmony_ci spec.stride = 0; 2094e5c31af7Sopenharmony_ci spec.normalize = 0; 2095e5c31af7Sopenharmony_ci spec.instanceDivisor = 0; 2096e5c31af7Sopenharmony_ci 2097e5c31af7Sopenharmony_ci spec.useDefaultAttribute = true; 2098e5c31af7Sopenharmony_ci 2099e5c31af7Sopenharmony_ci return spec; 2100e5c31af7Sopenharmony_ci} 2101e5c31af7Sopenharmony_ci 2102e5c31af7Sopenharmony_ciDrawTestSpec::AttributeSpec::AttributeSpec (void) 2103e5c31af7Sopenharmony_ci{ 2104e5c31af7Sopenharmony_ci inputType = DrawTestSpec::INPUTTYPE_LAST; 2105e5c31af7Sopenharmony_ci outputType = DrawTestSpec::OUTPUTTYPE_LAST; 2106e5c31af7Sopenharmony_ci storage = DrawTestSpec::STORAGE_LAST; 2107e5c31af7Sopenharmony_ci usage = DrawTestSpec::USAGE_LAST; 2108e5c31af7Sopenharmony_ci componentCount = 0; 2109e5c31af7Sopenharmony_ci offset = 0; 2110e5c31af7Sopenharmony_ci stride = 0; 2111e5c31af7Sopenharmony_ci normalize = false; 2112e5c31af7Sopenharmony_ci instanceDivisor = 0; 2113e5c31af7Sopenharmony_ci useDefaultAttribute = false; 2114e5c31af7Sopenharmony_ci additionalPositionAttribute = false; 2115e5c31af7Sopenharmony_ci bgraComponentOrder = false; 2116e5c31af7Sopenharmony_ci} 2117e5c31af7Sopenharmony_ci 2118e5c31af7Sopenharmony_ciint DrawTestSpec::AttributeSpec::hash (void) const 2119e5c31af7Sopenharmony_ci{ 2120e5c31af7Sopenharmony_ci if (useDefaultAttribute) 2121e5c31af7Sopenharmony_ci { 2122e5c31af7Sopenharmony_ci return 1 * int(inputType) + 7 * int(outputType) + 13 * componentCount; 2123e5c31af7Sopenharmony_ci } 2124e5c31af7Sopenharmony_ci else 2125e5c31af7Sopenharmony_ci { 2126e5c31af7Sopenharmony_ci return 1 * int(inputType) + 2 * int(outputType) + 3 * int(storage) + 5 * int(usage) + 7 * componentCount + 11 * offset + 13 * stride + 17 * (normalize ? 0 : 1) + 19 * instanceDivisor; 2127e5c31af7Sopenharmony_ci } 2128e5c31af7Sopenharmony_ci} 2129e5c31af7Sopenharmony_ci 2130e5c31af7Sopenharmony_cibool DrawTestSpec::AttributeSpec::valid (glu::ApiType ctxType) const 2131e5c31af7Sopenharmony_ci{ 2132e5c31af7Sopenharmony_ci const bool inputTypeFloat = inputType == DrawTestSpec::INPUTTYPE_FLOAT || inputType == DrawTestSpec::INPUTTYPE_FIXED || inputType == DrawTestSpec::INPUTTYPE_HALF; 2133e5c31af7Sopenharmony_ci const bool inputTypeUnsignedInteger = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE || inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT || inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT || inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10; 2134e5c31af7Sopenharmony_ci const bool inputTypeSignedInteger = inputType == DrawTestSpec::INPUTTYPE_BYTE || inputType == DrawTestSpec::INPUTTYPE_SHORT || inputType == DrawTestSpec::INPUTTYPE_INT || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10; 2135e5c31af7Sopenharmony_ci const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10; 2136e5c31af7Sopenharmony_ci 2137e5c31af7Sopenharmony_ci const bool outputTypeFloat = outputType == DrawTestSpec::OUTPUTTYPE_FLOAT || outputType == DrawTestSpec::OUTPUTTYPE_VEC2 || outputType == DrawTestSpec::OUTPUTTYPE_VEC3 || outputType == DrawTestSpec::OUTPUTTYPE_VEC4; 2138e5c31af7Sopenharmony_ci const bool outputTypeSignedInteger = outputType == DrawTestSpec::OUTPUTTYPE_INT || outputType == DrawTestSpec::OUTPUTTYPE_IVEC2 || outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_IVEC4; 2139e5c31af7Sopenharmony_ci const bool outputTypeUnsignedInteger = outputType == DrawTestSpec::OUTPUTTYPE_UINT || outputType == DrawTestSpec::OUTPUTTYPE_UVEC2 || outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_UVEC4; 2140e5c31af7Sopenharmony_ci 2141e5c31af7Sopenharmony_ci if (useDefaultAttribute) 2142e5c31af7Sopenharmony_ci { 2143e5c31af7Sopenharmony_ci if (inputType != DrawTestSpec::INPUTTYPE_INT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT && inputType != DrawTestSpec::INPUTTYPE_FLOAT) 2144e5c31af7Sopenharmony_ci return false; 2145e5c31af7Sopenharmony_ci 2146e5c31af7Sopenharmony_ci if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && componentCount != 4) 2147e5c31af7Sopenharmony_ci return false; 2148e5c31af7Sopenharmony_ci 2149e5c31af7Sopenharmony_ci // no casting allowed (undefined results) 2150e5c31af7Sopenharmony_ci if (inputType == DrawTestSpec::INPUTTYPE_INT && !outputTypeSignedInteger) 2151e5c31af7Sopenharmony_ci return false; 2152e5c31af7Sopenharmony_ci if (inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT && !outputTypeUnsignedInteger) 2153e5c31af7Sopenharmony_ci return false; 2154e5c31af7Sopenharmony_ci } 2155e5c31af7Sopenharmony_ci 2156e5c31af7Sopenharmony_ci if (inputTypePacked && componentCount != 4) 2157e5c31af7Sopenharmony_ci return false; 2158e5c31af7Sopenharmony_ci 2159e5c31af7Sopenharmony_ci // Invalid conversions: 2160e5c31af7Sopenharmony_ci 2161e5c31af7Sopenharmony_ci // float -> [u]int 2162e5c31af7Sopenharmony_ci if (inputTypeFloat && !outputTypeFloat) 2163e5c31af7Sopenharmony_ci return false; 2164e5c31af7Sopenharmony_ci 2165e5c31af7Sopenharmony_ci // uint -> int (undefined results) 2166e5c31af7Sopenharmony_ci if (inputTypeUnsignedInteger && outputTypeSignedInteger) 2167e5c31af7Sopenharmony_ci return false; 2168e5c31af7Sopenharmony_ci 2169e5c31af7Sopenharmony_ci // int -> uint (undefined results) 2170e5c31af7Sopenharmony_ci if (inputTypeSignedInteger && outputTypeUnsignedInteger) 2171e5c31af7Sopenharmony_ci return false; 2172e5c31af7Sopenharmony_ci 2173e5c31af7Sopenharmony_ci // packed -> non-float (packed formats are converted to floats) 2174e5c31af7Sopenharmony_ci if (inputTypePacked && !outputTypeFloat) 2175e5c31af7Sopenharmony_ci return false; 2176e5c31af7Sopenharmony_ci 2177e5c31af7Sopenharmony_ci // Invalid normalize. Normalize is only valid if output type is float 2178e5c31af7Sopenharmony_ci if (normalize && !outputTypeFloat) 2179e5c31af7Sopenharmony_ci return false; 2180e5c31af7Sopenharmony_ci 2181e5c31af7Sopenharmony_ci // Allow reverse order (GL_BGRA) only for packed and 4-component ubyte 2182e5c31af7Sopenharmony_ci if (bgraComponentOrder && componentCount != 4) 2183e5c31af7Sopenharmony_ci return false; 2184e5c31af7Sopenharmony_ci if (bgraComponentOrder && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 && inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10 && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE) 2185e5c31af7Sopenharmony_ci return false; 2186e5c31af7Sopenharmony_ci if (bgraComponentOrder && normalize != true) 2187e5c31af7Sopenharmony_ci return false; 2188e5c31af7Sopenharmony_ci 2189e5c31af7Sopenharmony_ci // GLES2 limits 2190e5c31af7Sopenharmony_ci if (ctxType == glu::ApiType::es(2,0)) 2191e5c31af7Sopenharmony_ci { 2192e5c31af7Sopenharmony_ci if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && inputType != DrawTestSpec::INPUTTYPE_FIXED && 2193e5c31af7Sopenharmony_ci inputType != DrawTestSpec::INPUTTYPE_BYTE && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE && 2194e5c31af7Sopenharmony_ci inputType != DrawTestSpec::INPUTTYPE_SHORT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT) 2195e5c31af7Sopenharmony_ci return false; 2196e5c31af7Sopenharmony_ci 2197e5c31af7Sopenharmony_ci if (!outputTypeFloat) 2198e5c31af7Sopenharmony_ci return false; 2199e5c31af7Sopenharmony_ci 2200e5c31af7Sopenharmony_ci if (bgraComponentOrder) 2201e5c31af7Sopenharmony_ci return false; 2202e5c31af7Sopenharmony_ci } 2203e5c31af7Sopenharmony_ci 2204e5c31af7Sopenharmony_ci // GLES3 limits 2205e5c31af7Sopenharmony_ci if (ctxType.getProfile() == glu::PROFILE_ES && ctxType.getMajorVersion() == 3) 2206e5c31af7Sopenharmony_ci { 2207e5c31af7Sopenharmony_ci if (bgraComponentOrder) 2208e5c31af7Sopenharmony_ci return false; 2209e5c31af7Sopenharmony_ci } 2210e5c31af7Sopenharmony_ci 2211e5c31af7Sopenharmony_ci // No user pointers in GL core 2212e5c31af7Sopenharmony_ci if (ctxType.getProfile() == glu::PROFILE_CORE) 2213e5c31af7Sopenharmony_ci { 2214e5c31af7Sopenharmony_ci if (!useDefaultAttribute && storage == DrawTestSpec::STORAGE_USER) 2215e5c31af7Sopenharmony_ci return false; 2216e5c31af7Sopenharmony_ci } 2217e5c31af7Sopenharmony_ci 2218e5c31af7Sopenharmony_ci return true; 2219e5c31af7Sopenharmony_ci} 2220e5c31af7Sopenharmony_ci 2221e5c31af7Sopenharmony_cibool DrawTestSpec::AttributeSpec::isBufferAligned (void) const 2222e5c31af7Sopenharmony_ci{ 2223e5c31af7Sopenharmony_ci const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10; 2224e5c31af7Sopenharmony_ci 2225e5c31af7Sopenharmony_ci // Buffer alignment, offset is a multiple of underlying data type size? 2226e5c31af7Sopenharmony_ci if (storage == STORAGE_BUFFER) 2227e5c31af7Sopenharmony_ci { 2228e5c31af7Sopenharmony_ci int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType); 2229e5c31af7Sopenharmony_ci if (inputTypePacked) 2230e5c31af7Sopenharmony_ci dataTypeSize = 4; 2231e5c31af7Sopenharmony_ci 2232e5c31af7Sopenharmony_ci if (offset % dataTypeSize != 0) 2233e5c31af7Sopenharmony_ci return false; 2234e5c31af7Sopenharmony_ci } 2235e5c31af7Sopenharmony_ci 2236e5c31af7Sopenharmony_ci return true; 2237e5c31af7Sopenharmony_ci} 2238e5c31af7Sopenharmony_ci 2239e5c31af7Sopenharmony_cibool DrawTestSpec::AttributeSpec::isBufferStrideAligned (void) const 2240e5c31af7Sopenharmony_ci{ 2241e5c31af7Sopenharmony_ci const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10; 2242e5c31af7Sopenharmony_ci 2243e5c31af7Sopenharmony_ci // Buffer alignment, offset is a multiple of underlying data type size? 2244e5c31af7Sopenharmony_ci if (storage == STORAGE_BUFFER) 2245e5c31af7Sopenharmony_ci { 2246e5c31af7Sopenharmony_ci int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType); 2247e5c31af7Sopenharmony_ci if (inputTypePacked) 2248e5c31af7Sopenharmony_ci dataTypeSize = 4; 2249e5c31af7Sopenharmony_ci 2250e5c31af7Sopenharmony_ci if (stride % dataTypeSize != 0) 2251e5c31af7Sopenharmony_ci return false; 2252e5c31af7Sopenharmony_ci } 2253e5c31af7Sopenharmony_ci 2254e5c31af7Sopenharmony_ci return true; 2255e5c31af7Sopenharmony_ci} 2256e5c31af7Sopenharmony_ci 2257e5c31af7Sopenharmony_cistd::string DrawTestSpec::targetToString(Target target) 2258e5c31af7Sopenharmony_ci{ 2259e5c31af7Sopenharmony_ci static const char* targets[] = 2260e5c31af7Sopenharmony_ci { 2261e5c31af7Sopenharmony_ci "element_array", // TARGET_ELEMENT_ARRAY = 0, 2262e5c31af7Sopenharmony_ci "array" // TARGET_ARRAY, 2263e5c31af7Sopenharmony_ci }; 2264e5c31af7Sopenharmony_ci 2265e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target); 2266e5c31af7Sopenharmony_ci} 2267e5c31af7Sopenharmony_ci 2268e5c31af7Sopenharmony_cistd::string DrawTestSpec::inputTypeToString(InputType type) 2269e5c31af7Sopenharmony_ci{ 2270e5c31af7Sopenharmony_ci static const char* types[] = 2271e5c31af7Sopenharmony_ci { 2272e5c31af7Sopenharmony_ci "float", // INPUTTYPE_FLOAT = 0, 2273e5c31af7Sopenharmony_ci "fixed", // INPUTTYPE_FIXED, 2274e5c31af7Sopenharmony_ci "double", // INPUTTYPE_DOUBLE 2275e5c31af7Sopenharmony_ci 2276e5c31af7Sopenharmony_ci "byte", // INPUTTYPE_BYTE, 2277e5c31af7Sopenharmony_ci "short", // INPUTTYPE_SHORT, 2278e5c31af7Sopenharmony_ci 2279e5c31af7Sopenharmony_ci "unsigned_byte", // INPUTTYPE_UNSIGNED_BYTE, 2280e5c31af7Sopenharmony_ci "unsigned_short", // INPUTTYPE_UNSIGNED_SHORT, 2281e5c31af7Sopenharmony_ci 2282e5c31af7Sopenharmony_ci "int", // INPUTTYPE_INT, 2283e5c31af7Sopenharmony_ci "unsigned_int", // INPUTTYPE_UNSIGNED_INT, 2284e5c31af7Sopenharmony_ci "half", // INPUTTYPE_HALF, 2285e5c31af7Sopenharmony_ci "unsigned_int2_10_10_10", // INPUTTYPE_UNSIGNED_INT_2_10_10_10, 2286e5c31af7Sopenharmony_ci "int2_10_10_10" // INPUTTYPE_INT_2_10_10_10, 2287e5c31af7Sopenharmony_ci }; 2288e5c31af7Sopenharmony_ci 2289e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type); 2290e5c31af7Sopenharmony_ci} 2291e5c31af7Sopenharmony_ci 2292e5c31af7Sopenharmony_cistd::string DrawTestSpec::outputTypeToString(OutputType type) 2293e5c31af7Sopenharmony_ci{ 2294e5c31af7Sopenharmony_ci static const char* types[] = 2295e5c31af7Sopenharmony_ci { 2296e5c31af7Sopenharmony_ci "float", // OUTPUTTYPE_FLOAT = 0, 2297e5c31af7Sopenharmony_ci "vec2", // OUTPUTTYPE_VEC2, 2298e5c31af7Sopenharmony_ci "vec3", // OUTPUTTYPE_VEC3, 2299e5c31af7Sopenharmony_ci "vec4", // OUTPUTTYPE_VEC4, 2300e5c31af7Sopenharmony_ci 2301e5c31af7Sopenharmony_ci "int", // OUTPUTTYPE_INT, 2302e5c31af7Sopenharmony_ci "uint", // OUTPUTTYPE_UINT, 2303e5c31af7Sopenharmony_ci 2304e5c31af7Sopenharmony_ci "ivec2", // OUTPUTTYPE_IVEC2, 2305e5c31af7Sopenharmony_ci "ivec3", // OUTPUTTYPE_IVEC3, 2306e5c31af7Sopenharmony_ci "ivec4", // OUTPUTTYPE_IVEC4, 2307e5c31af7Sopenharmony_ci 2308e5c31af7Sopenharmony_ci "uvec2", // OUTPUTTYPE_UVEC2, 2309e5c31af7Sopenharmony_ci "uvec3", // OUTPUTTYPE_UVEC3, 2310e5c31af7Sopenharmony_ci "uvec4", // OUTPUTTYPE_UVEC4, 2311e5c31af7Sopenharmony_ci }; 2312e5c31af7Sopenharmony_ci 2313e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type); 2314e5c31af7Sopenharmony_ci} 2315e5c31af7Sopenharmony_ci 2316e5c31af7Sopenharmony_cistd::string DrawTestSpec::usageTypeToString(Usage usage) 2317e5c31af7Sopenharmony_ci{ 2318e5c31af7Sopenharmony_ci static const char* usages[] = 2319e5c31af7Sopenharmony_ci { 2320e5c31af7Sopenharmony_ci "dynamic_draw", // USAGE_DYNAMIC_DRAW = 0, 2321e5c31af7Sopenharmony_ci "static_draw", // USAGE_STATIC_DRAW, 2322e5c31af7Sopenharmony_ci "stream_draw", // USAGE_STREAM_DRAW, 2323e5c31af7Sopenharmony_ci 2324e5c31af7Sopenharmony_ci "stream_read", // USAGE_STREAM_READ, 2325e5c31af7Sopenharmony_ci "stream_copy", // USAGE_STREAM_COPY, 2326e5c31af7Sopenharmony_ci 2327e5c31af7Sopenharmony_ci "static_read", // USAGE_STATIC_READ, 2328e5c31af7Sopenharmony_ci "static_copy", // USAGE_STATIC_COPY, 2329e5c31af7Sopenharmony_ci 2330e5c31af7Sopenharmony_ci "dynamic_read", // USAGE_DYNAMIC_READ, 2331e5c31af7Sopenharmony_ci "dynamic_copy", // USAGE_DYNAMIC_COPY, 2332e5c31af7Sopenharmony_ci }; 2333e5c31af7Sopenharmony_ci 2334e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage); 2335e5c31af7Sopenharmony_ci} 2336e5c31af7Sopenharmony_ci 2337e5c31af7Sopenharmony_cistd::string DrawTestSpec::storageToString (Storage storage) 2338e5c31af7Sopenharmony_ci{ 2339e5c31af7Sopenharmony_ci static const char* storages[] = 2340e5c31af7Sopenharmony_ci { 2341e5c31af7Sopenharmony_ci "user_ptr", // STORAGE_USER = 0, 2342e5c31af7Sopenharmony_ci "buffer" // STORAGE_BUFFER, 2343e5c31af7Sopenharmony_ci }; 2344e5c31af7Sopenharmony_ci 2345e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::STORAGE_LAST>(storages, (int)storage); 2346e5c31af7Sopenharmony_ci} 2347e5c31af7Sopenharmony_ci 2348e5c31af7Sopenharmony_cistd::string DrawTestSpec::primitiveToString (Primitive primitive) 2349e5c31af7Sopenharmony_ci{ 2350e5c31af7Sopenharmony_ci static const char* primitives[] = 2351e5c31af7Sopenharmony_ci { 2352e5c31af7Sopenharmony_ci "points", // PRIMITIVE_POINTS , 2353e5c31af7Sopenharmony_ci "triangles", // PRIMITIVE_TRIANGLES, 2354e5c31af7Sopenharmony_ci "triangle_fan", // PRIMITIVE_TRIANGLE_FAN, 2355e5c31af7Sopenharmony_ci "triangle_strip", // PRIMITIVE_TRIANGLE_STRIP, 2356e5c31af7Sopenharmony_ci "lines", // PRIMITIVE_LINES 2357e5c31af7Sopenharmony_ci "line_strip", // PRIMITIVE_LINE_STRIP 2358e5c31af7Sopenharmony_ci "line_loop", // PRIMITIVE_LINE_LOOP 2359e5c31af7Sopenharmony_ci "lines_adjacency", // PRIMITIVE_LINES_ADJACENCY 2360e5c31af7Sopenharmony_ci "line_strip_adjacency", // PRIMITIVE_LINE_STRIP_ADJACENCY 2361e5c31af7Sopenharmony_ci "triangles_adjacency", // PRIMITIVE_TRIANGLES_ADJACENCY 2362e5c31af7Sopenharmony_ci "triangle_strip_adjacency", // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY 2363e5c31af7Sopenharmony_ci }; 2364e5c31af7Sopenharmony_ci 2365e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive); 2366e5c31af7Sopenharmony_ci} 2367e5c31af7Sopenharmony_ci 2368e5c31af7Sopenharmony_cistd::string DrawTestSpec::indexTypeToString (IndexType type) 2369e5c31af7Sopenharmony_ci{ 2370e5c31af7Sopenharmony_ci static const char* indexTypes[] = 2371e5c31af7Sopenharmony_ci { 2372e5c31af7Sopenharmony_ci "byte", // INDEXTYPE_BYTE = 0, 2373e5c31af7Sopenharmony_ci "short", // INDEXTYPE_SHORT, 2374e5c31af7Sopenharmony_ci "int", // INDEXTYPE_INT, 2375e5c31af7Sopenharmony_ci }; 2376e5c31af7Sopenharmony_ci 2377e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)type); 2378e5c31af7Sopenharmony_ci} 2379e5c31af7Sopenharmony_ci 2380e5c31af7Sopenharmony_cistd::string DrawTestSpec::drawMethodToString (DrawTestSpec::DrawMethod method) 2381e5c31af7Sopenharmony_ci{ 2382e5c31af7Sopenharmony_ci static const char* methods[] = 2383e5c31af7Sopenharmony_ci { 2384e5c31af7Sopenharmony_ci "draw_arrays", //!< DRAWMETHOD_DRAWARRAYS 2385e5c31af7Sopenharmony_ci "draw_arrays_instanced", //!< DRAWMETHOD_DRAWARRAYS_INSTANCED 2386e5c31af7Sopenharmony_ci "draw_arrays_indirect", //!< DRAWMETHOD_DRAWARRAYS_INDIRECT 2387e5c31af7Sopenharmony_ci "draw_elements", //!< DRAWMETHOD_DRAWELEMENTS 2388e5c31af7Sopenharmony_ci "draw_range_elements", //!< DRAWMETHOD_DRAWELEMENTS_RANGED 2389e5c31af7Sopenharmony_ci "draw_elements_instanced", //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED 2390e5c31af7Sopenharmony_ci "draw_elements_indirect", //!< DRAWMETHOD_DRAWELEMENTS_INDIRECT 2391e5c31af7Sopenharmony_ci "draw_elements_base_vertex", //!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX, 2392e5c31af7Sopenharmony_ci "draw_elements_instanced_base_vertex", //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX, 2393e5c31af7Sopenharmony_ci "draw_range_elements_base_vertex", //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX, 2394e5c31af7Sopenharmony_ci }; 2395e5c31af7Sopenharmony_ci 2396e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(methods, (int)method); 2397e5c31af7Sopenharmony_ci} 2398e5c31af7Sopenharmony_ci 2399e5c31af7Sopenharmony_ciint DrawTestSpec::inputTypeSize (InputType type) 2400e5c31af7Sopenharmony_ci{ 2401e5c31af7Sopenharmony_ci static const int size[] = 2402e5c31af7Sopenharmony_ci { 2403e5c31af7Sopenharmony_ci (int)sizeof(float), // INPUTTYPE_FLOAT = 0, 2404e5c31af7Sopenharmony_ci (int)sizeof(deInt32), // INPUTTYPE_FIXED, 2405e5c31af7Sopenharmony_ci (int)sizeof(double), // INPUTTYPE_DOUBLE 2406e5c31af7Sopenharmony_ci 2407e5c31af7Sopenharmony_ci (int)sizeof(deInt8), // INPUTTYPE_BYTE, 2408e5c31af7Sopenharmony_ci (int)sizeof(deInt16), // INPUTTYPE_SHORT, 2409e5c31af7Sopenharmony_ci 2410e5c31af7Sopenharmony_ci (int)sizeof(deUint8), // INPUTTYPE_UNSIGNED_BYTE, 2411e5c31af7Sopenharmony_ci (int)sizeof(deUint16), // INPUTTYPE_UNSIGNED_SHORT, 2412e5c31af7Sopenharmony_ci 2413e5c31af7Sopenharmony_ci (int)sizeof(deInt32), // INPUTTYPE_INT, 2414e5c31af7Sopenharmony_ci (int)sizeof(deUint32), // INPUTTYPE_UNSIGNED_INT, 2415e5c31af7Sopenharmony_ci (int)sizeof(deFloat16), // INPUTTYPE_HALF, 2416e5c31af7Sopenharmony_ci (int)sizeof(deUint32) / 4, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, 2417e5c31af7Sopenharmony_ci (int)sizeof(deUint32) / 4 // INPUTTYPE_INT_2_10_10_10, 2418e5c31af7Sopenharmony_ci }; 2419e5c31af7Sopenharmony_ci 2420e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(size, (int)type); 2421e5c31af7Sopenharmony_ci} 2422e5c31af7Sopenharmony_ci 2423e5c31af7Sopenharmony_ciint DrawTestSpec::indexTypeSize (IndexType type) 2424e5c31af7Sopenharmony_ci{ 2425e5c31af7Sopenharmony_ci static const int size[] = 2426e5c31af7Sopenharmony_ci { 2427e5c31af7Sopenharmony_ci sizeof(deUint8), // INDEXTYPE_BYTE, 2428e5c31af7Sopenharmony_ci sizeof(deUint16), // INDEXTYPE_SHORT, 2429e5c31af7Sopenharmony_ci sizeof(deUint32), // INDEXTYPE_INT, 2430e5c31af7Sopenharmony_ci }; 2431e5c31af7Sopenharmony_ci 2432e5c31af7Sopenharmony_ci return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(size, (int)type); 2433e5c31af7Sopenharmony_ci} 2434e5c31af7Sopenharmony_ci 2435e5c31af7Sopenharmony_cistd::string DrawTestSpec::getName (void) const 2436e5c31af7Sopenharmony_ci{ 2437e5c31af7Sopenharmony_ci const MethodInfo methodInfo = getMethodInfo(drawMethod); 2438e5c31af7Sopenharmony_ci const bool hasFirst = methodInfo.first; 2439e5c31af7Sopenharmony_ci const bool instanced = methodInfo.instanced; 2440e5c31af7Sopenharmony_ci const bool ranged = methodInfo.ranged; 2441e5c31af7Sopenharmony_ci const bool indexed = methodInfo.indexed; 2442e5c31af7Sopenharmony_ci 2443e5c31af7Sopenharmony_ci std::stringstream name; 2444e5c31af7Sopenharmony_ci 2445e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < attribs.size(); ++ndx) 2446e5c31af7Sopenharmony_ci { 2447e5c31af7Sopenharmony_ci const AttributeSpec& attrib = attribs[ndx]; 2448e5c31af7Sopenharmony_ci 2449e5c31af7Sopenharmony_ci if (attribs.size() > 1) 2450e5c31af7Sopenharmony_ci name << "attrib" << ndx << "_"; 2451e5c31af7Sopenharmony_ci 2452e5c31af7Sopenharmony_ci if (ndx == 0|| attrib.additionalPositionAttribute) 2453e5c31af7Sopenharmony_ci name << "pos_"; 2454e5c31af7Sopenharmony_ci else 2455e5c31af7Sopenharmony_ci name << "col_"; 2456e5c31af7Sopenharmony_ci 2457e5c31af7Sopenharmony_ci if (attrib.useDefaultAttribute) 2458e5c31af7Sopenharmony_ci { 2459e5c31af7Sopenharmony_ci name 2460e5c31af7Sopenharmony_ci << "non_array_" 2461e5c31af7Sopenharmony_ci << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "_" 2462e5c31af7Sopenharmony_ci << attrib.componentCount << "_" 2463e5c31af7Sopenharmony_ci << DrawTestSpec::outputTypeToString(attrib.outputType) << "_"; 2464e5c31af7Sopenharmony_ci } 2465e5c31af7Sopenharmony_ci else 2466e5c31af7Sopenharmony_ci { 2467e5c31af7Sopenharmony_ci name 2468e5c31af7Sopenharmony_ci << DrawTestSpec::storageToString(attrib.storage) << "_" 2469e5c31af7Sopenharmony_ci << attrib.offset << "_" 2470e5c31af7Sopenharmony_ci << attrib.stride << "_" 2471e5c31af7Sopenharmony_ci << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType); 2472e5c31af7Sopenharmony_ci if (attrib.inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 && attrib.inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10) 2473e5c31af7Sopenharmony_ci name << attrib.componentCount; 2474e5c31af7Sopenharmony_ci name 2475e5c31af7Sopenharmony_ci << "_" 2476e5c31af7Sopenharmony_ci << (attrib.normalize ? "normalized_" : "") 2477e5c31af7Sopenharmony_ci << DrawTestSpec::outputTypeToString(attrib.outputType) << "_" 2478e5c31af7Sopenharmony_ci << DrawTestSpec::usageTypeToString(attrib.usage) << "_" 2479e5c31af7Sopenharmony_ci << attrib.instanceDivisor << "_"; 2480e5c31af7Sopenharmony_ci } 2481e5c31af7Sopenharmony_ci } 2482e5c31af7Sopenharmony_ci 2483e5c31af7Sopenharmony_ci if (indexed) 2484e5c31af7Sopenharmony_ci name 2485e5c31af7Sopenharmony_ci << "index_" << DrawTestSpec::indexTypeToString(indexType) << "_" 2486e5c31af7Sopenharmony_ci << DrawTestSpec::storageToString(indexStorage) << "_" 2487e5c31af7Sopenharmony_ci << "offset" << indexPointerOffset << "_"; 2488e5c31af7Sopenharmony_ci if (hasFirst) 2489e5c31af7Sopenharmony_ci name << "first" << first << "_"; 2490e5c31af7Sopenharmony_ci if (ranged) 2491e5c31af7Sopenharmony_ci name << "ranged_" << indexMin << "_" << indexMax << "_"; 2492e5c31af7Sopenharmony_ci if (instanced) 2493e5c31af7Sopenharmony_ci name << "instances" << instanceCount << "_"; 2494e5c31af7Sopenharmony_ci 2495e5c31af7Sopenharmony_ci switch (primitive) 2496e5c31af7Sopenharmony_ci { 2497e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_POINTS: 2498e5c31af7Sopenharmony_ci name << "points_"; 2499e5c31af7Sopenharmony_ci break; 2500e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES: 2501e5c31af7Sopenharmony_ci name << "triangles_"; 2502e5c31af7Sopenharmony_ci break; 2503e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN: 2504e5c31af7Sopenharmony_ci name << "triangle_fan_"; 2505e5c31af7Sopenharmony_ci break; 2506e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP: 2507e5c31af7Sopenharmony_ci name << "triangle_strip_"; 2508e5c31af7Sopenharmony_ci break; 2509e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES: 2510e5c31af7Sopenharmony_ci name << "lines_"; 2511e5c31af7Sopenharmony_ci break; 2512e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP: 2513e5c31af7Sopenharmony_ci name << "line_strip_"; 2514e5c31af7Sopenharmony_ci break; 2515e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_LOOP: 2516e5c31af7Sopenharmony_ci name << "line_loop_"; 2517e5c31af7Sopenharmony_ci break; 2518e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY: 2519e5c31af7Sopenharmony_ci name << "line_adjancency"; 2520e5c31af7Sopenharmony_ci break; 2521e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY: 2522e5c31af7Sopenharmony_ci name << "line_strip_adjancency"; 2523e5c31af7Sopenharmony_ci break; 2524e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY: 2525e5c31af7Sopenharmony_ci name << "triangles_adjancency"; 2526e5c31af7Sopenharmony_ci break; 2527e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY: 2528e5c31af7Sopenharmony_ci name << "triangle_strip_adjancency"; 2529e5c31af7Sopenharmony_ci break; 2530e5c31af7Sopenharmony_ci default: 2531e5c31af7Sopenharmony_ci DE_ASSERT(false); 2532e5c31af7Sopenharmony_ci break; 2533e5c31af7Sopenharmony_ci } 2534e5c31af7Sopenharmony_ci 2535e5c31af7Sopenharmony_ci name << primitiveCount; 2536e5c31af7Sopenharmony_ci 2537e5c31af7Sopenharmony_ci return name.str(); 2538e5c31af7Sopenharmony_ci} 2539e5c31af7Sopenharmony_ci 2540e5c31af7Sopenharmony_cistd::string DrawTestSpec::getDesc (void) const 2541e5c31af7Sopenharmony_ci{ 2542e5c31af7Sopenharmony_ci std::stringstream desc; 2543e5c31af7Sopenharmony_ci 2544e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < attribs.size(); ++ndx) 2545e5c31af7Sopenharmony_ci { 2546e5c31af7Sopenharmony_ci const AttributeSpec& attrib = attribs[ndx]; 2547e5c31af7Sopenharmony_ci 2548e5c31af7Sopenharmony_ci if (attrib.useDefaultAttribute) 2549e5c31af7Sopenharmony_ci { 2550e5c31af7Sopenharmony_ci desc 2551e5c31af7Sopenharmony_ci << "Attribute " << ndx << ": default, " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position ,") : ("color ,")) 2552e5c31af7Sopenharmony_ci << "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << ", " 2553e5c31af7Sopenharmony_ci << "input component count " << attrib.componentCount << ", " 2554e5c31af7Sopenharmony_ci << "used as " << DrawTestSpec::outputTypeToString(attrib.outputType) << ", "; 2555e5c31af7Sopenharmony_ci } 2556e5c31af7Sopenharmony_ci else 2557e5c31af7Sopenharmony_ci { 2558e5c31af7Sopenharmony_ci desc 2559e5c31af7Sopenharmony_ci << "Attribute " << ndx << ": " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position ,") : ("color ,")) 2560e5c31af7Sopenharmony_ci << "Storage in " << DrawTestSpec::storageToString(attrib.storage) << ", " 2561e5c31af7Sopenharmony_ci << "stride " << attrib.stride << ", " 2562e5c31af7Sopenharmony_ci << "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << ", " 2563e5c31af7Sopenharmony_ci << "input component count " << attrib.componentCount << ", " 2564e5c31af7Sopenharmony_ci << (attrib.normalize ? "normalized, " : "") 2565e5c31af7Sopenharmony_ci << "used as " << DrawTestSpec::outputTypeToString(attrib.outputType) << ", " 2566e5c31af7Sopenharmony_ci << "instance divisor " << attrib.instanceDivisor << ", "; 2567e5c31af7Sopenharmony_ci } 2568e5c31af7Sopenharmony_ci } 2569e5c31af7Sopenharmony_ci 2570e5c31af7Sopenharmony_ci if (drawMethod == DRAWMETHOD_DRAWARRAYS) 2571e5c31af7Sopenharmony_ci { 2572e5c31af7Sopenharmony_ci desc 2573e5c31af7Sopenharmony_ci << "drawArrays(), " 2574e5c31af7Sopenharmony_ci << "first " << first << ", "; 2575e5c31af7Sopenharmony_ci } 2576e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED) 2577e5c31af7Sopenharmony_ci { 2578e5c31af7Sopenharmony_ci desc 2579e5c31af7Sopenharmony_ci << "drawArraysInstanced(), " 2580e5c31af7Sopenharmony_ci << "first " << first << ", " 2581e5c31af7Sopenharmony_ci << "instance count " << instanceCount << ", "; 2582e5c31af7Sopenharmony_ci } 2583e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS) 2584e5c31af7Sopenharmony_ci { 2585e5c31af7Sopenharmony_ci desc 2586e5c31af7Sopenharmony_ci << "drawElements(), " 2587e5c31af7Sopenharmony_ci << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", " 2588e5c31af7Sopenharmony_ci << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", " 2589e5c31af7Sopenharmony_ci << "index offset " << indexPointerOffset << ", "; 2590e5c31af7Sopenharmony_ci } 2591e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED) 2592e5c31af7Sopenharmony_ci { 2593e5c31af7Sopenharmony_ci desc 2594e5c31af7Sopenharmony_ci << "drawElementsRanged(), " 2595e5c31af7Sopenharmony_ci << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", " 2596e5c31af7Sopenharmony_ci << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", " 2597e5c31af7Sopenharmony_ci << "index offset " << indexPointerOffset << ", " 2598e5c31af7Sopenharmony_ci << "range start " << indexMin << ", " 2599e5c31af7Sopenharmony_ci << "range end " << indexMax << ", "; 2600e5c31af7Sopenharmony_ci } 2601e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED) 2602e5c31af7Sopenharmony_ci { 2603e5c31af7Sopenharmony_ci desc 2604e5c31af7Sopenharmony_ci << "drawElementsInstanced(), " 2605e5c31af7Sopenharmony_ci << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", " 2606e5c31af7Sopenharmony_ci << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", " 2607e5c31af7Sopenharmony_ci << "index offset " << indexPointerOffset << ", " 2608e5c31af7Sopenharmony_ci << "instance count " << instanceCount << ", "; 2609e5c31af7Sopenharmony_ci } 2610e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT) 2611e5c31af7Sopenharmony_ci { 2612e5c31af7Sopenharmony_ci desc 2613e5c31af7Sopenharmony_ci << "drawArraysIndirect(), " 2614e5c31af7Sopenharmony_ci << "first " << first << ", " 2615e5c31af7Sopenharmony_ci << "instance count " << instanceCount << ", " 2616e5c31af7Sopenharmony_ci << "indirect offset " << indirectOffset << ", "; 2617e5c31af7Sopenharmony_ci } 2618e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT) 2619e5c31af7Sopenharmony_ci { 2620e5c31af7Sopenharmony_ci desc 2621e5c31af7Sopenharmony_ci << "drawElementsIndirect(), " 2622e5c31af7Sopenharmony_ci << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", " 2623e5c31af7Sopenharmony_ci << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", " 2624e5c31af7Sopenharmony_ci << "index offset " << indexPointerOffset << ", " 2625e5c31af7Sopenharmony_ci << "instance count " << instanceCount << ", " 2626e5c31af7Sopenharmony_ci << "indirect offset " << indirectOffset << ", " 2627e5c31af7Sopenharmony_ci << "base vertex " << baseVertex << ", "; 2628e5c31af7Sopenharmony_ci } 2629e5c31af7Sopenharmony_ci else 2630e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2631e5c31af7Sopenharmony_ci 2632e5c31af7Sopenharmony_ci desc << primitiveCount; 2633e5c31af7Sopenharmony_ci 2634e5c31af7Sopenharmony_ci switch (primitive) 2635e5c31af7Sopenharmony_ci { 2636e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_POINTS: 2637e5c31af7Sopenharmony_ci desc << "points"; 2638e5c31af7Sopenharmony_ci break; 2639e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES: 2640e5c31af7Sopenharmony_ci desc << "triangles"; 2641e5c31af7Sopenharmony_ci break; 2642e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN: 2643e5c31af7Sopenharmony_ci desc << "triangles (fan)"; 2644e5c31af7Sopenharmony_ci break; 2645e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP: 2646e5c31af7Sopenharmony_ci desc << "triangles (strip)"; 2647e5c31af7Sopenharmony_ci break; 2648e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES: 2649e5c31af7Sopenharmony_ci desc << "lines"; 2650e5c31af7Sopenharmony_ci break; 2651e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP: 2652e5c31af7Sopenharmony_ci desc << "lines (strip)"; 2653e5c31af7Sopenharmony_ci break; 2654e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_LOOP: 2655e5c31af7Sopenharmony_ci desc << "lines (loop)"; 2656e5c31af7Sopenharmony_ci break; 2657e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY: 2658e5c31af7Sopenharmony_ci desc << "lines (adjancency)"; 2659e5c31af7Sopenharmony_ci break; 2660e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY: 2661e5c31af7Sopenharmony_ci desc << "lines (strip, adjancency)"; 2662e5c31af7Sopenharmony_ci break; 2663e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY: 2664e5c31af7Sopenharmony_ci desc << "triangles (adjancency)"; 2665e5c31af7Sopenharmony_ci break; 2666e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY: 2667e5c31af7Sopenharmony_ci desc << "triangles (strip, adjancency)"; 2668e5c31af7Sopenharmony_ci break; 2669e5c31af7Sopenharmony_ci default: 2670e5c31af7Sopenharmony_ci DE_ASSERT(false); 2671e5c31af7Sopenharmony_ci break; 2672e5c31af7Sopenharmony_ci } 2673e5c31af7Sopenharmony_ci 2674e5c31af7Sopenharmony_ci return desc.str(); 2675e5c31af7Sopenharmony_ci} 2676e5c31af7Sopenharmony_ci 2677e5c31af7Sopenharmony_cistd::string DrawTestSpec::getMultilineDesc (void) const 2678e5c31af7Sopenharmony_ci{ 2679e5c31af7Sopenharmony_ci std::stringstream desc; 2680e5c31af7Sopenharmony_ci 2681e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < attribs.size(); ++ndx) 2682e5c31af7Sopenharmony_ci { 2683e5c31af7Sopenharmony_ci const AttributeSpec& attrib = attribs[ndx]; 2684e5c31af7Sopenharmony_ci 2685e5c31af7Sopenharmony_ci if (attrib.useDefaultAttribute) 2686e5c31af7Sopenharmony_ci { 2687e5c31af7Sopenharmony_ci desc 2688e5c31af7Sopenharmony_ci << "Attribute " << ndx << ": default, " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position\n") : ("color\n")) 2689e5c31af7Sopenharmony_ci << "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "\n" 2690e5c31af7Sopenharmony_ci << "\tinput component count " << attrib.componentCount << "\n" 2691e5c31af7Sopenharmony_ci << "\tused as " << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n"; 2692e5c31af7Sopenharmony_ci } 2693e5c31af7Sopenharmony_ci else 2694e5c31af7Sopenharmony_ci { 2695e5c31af7Sopenharmony_ci desc 2696e5c31af7Sopenharmony_ci << "Attribute " << ndx << ": " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position\n") : ("color\n")) 2697e5c31af7Sopenharmony_ci << "\tStorage in " << DrawTestSpec::storageToString(attrib.storage) << "\n" 2698e5c31af7Sopenharmony_ci << "\tstride " << attrib.stride << "\n" 2699e5c31af7Sopenharmony_ci << "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "\n" 2700e5c31af7Sopenharmony_ci << "\tinput component count " << attrib.componentCount << "\n" 2701e5c31af7Sopenharmony_ci << (attrib.normalize ? "\tnormalized\n" : "") 2702e5c31af7Sopenharmony_ci << "\tused as " << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n" 2703e5c31af7Sopenharmony_ci << "\tinstance divisor " << attrib.instanceDivisor << "\n"; 2704e5c31af7Sopenharmony_ci } 2705e5c31af7Sopenharmony_ci } 2706e5c31af7Sopenharmony_ci 2707e5c31af7Sopenharmony_ci if (drawMethod == DRAWMETHOD_DRAWARRAYS) 2708e5c31af7Sopenharmony_ci { 2709e5c31af7Sopenharmony_ci desc 2710e5c31af7Sopenharmony_ci << "drawArrays()\n" 2711e5c31af7Sopenharmony_ci << "\tfirst " << first << "\n"; 2712e5c31af7Sopenharmony_ci } 2713e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED) 2714e5c31af7Sopenharmony_ci { 2715e5c31af7Sopenharmony_ci desc 2716e5c31af7Sopenharmony_ci << "drawArraysInstanced()\n" 2717e5c31af7Sopenharmony_ci << "\tfirst " << first << "\n" 2718e5c31af7Sopenharmony_ci << "\tinstance count " << instanceCount << "\n"; 2719e5c31af7Sopenharmony_ci } 2720e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS) 2721e5c31af7Sopenharmony_ci { 2722e5c31af7Sopenharmony_ci desc 2723e5c31af7Sopenharmony_ci << "drawElements()\n" 2724e5c31af7Sopenharmony_ci << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n" 2725e5c31af7Sopenharmony_ci << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n" 2726e5c31af7Sopenharmony_ci << "\tindex offset " << indexPointerOffset << "\n"; 2727e5c31af7Sopenharmony_ci } 2728e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED) 2729e5c31af7Sopenharmony_ci { 2730e5c31af7Sopenharmony_ci desc 2731e5c31af7Sopenharmony_ci << "drawElementsRanged()\n" 2732e5c31af7Sopenharmony_ci << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n" 2733e5c31af7Sopenharmony_ci << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n" 2734e5c31af7Sopenharmony_ci << "\tindex offset " << indexPointerOffset << "\n" 2735e5c31af7Sopenharmony_ci << "\trange start " << indexMin << "\n" 2736e5c31af7Sopenharmony_ci << "\trange end " << indexMax << "\n"; 2737e5c31af7Sopenharmony_ci } 2738e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED) 2739e5c31af7Sopenharmony_ci { 2740e5c31af7Sopenharmony_ci desc 2741e5c31af7Sopenharmony_ci << "drawElementsInstanced()\n" 2742e5c31af7Sopenharmony_ci << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n" 2743e5c31af7Sopenharmony_ci << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n" 2744e5c31af7Sopenharmony_ci << "\tindex offset " << indexPointerOffset << "\n" 2745e5c31af7Sopenharmony_ci << "\tinstance count " << instanceCount << "\n"; 2746e5c31af7Sopenharmony_ci } 2747e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT) 2748e5c31af7Sopenharmony_ci { 2749e5c31af7Sopenharmony_ci desc 2750e5c31af7Sopenharmony_ci << "drawArraysIndirect()\n" 2751e5c31af7Sopenharmony_ci << "\tfirst " << first << "\n" 2752e5c31af7Sopenharmony_ci << "\tinstance count " << instanceCount << "\n" 2753e5c31af7Sopenharmony_ci << "\tindirect offset " << indirectOffset << "\n"; 2754e5c31af7Sopenharmony_ci } 2755e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT) 2756e5c31af7Sopenharmony_ci { 2757e5c31af7Sopenharmony_ci desc 2758e5c31af7Sopenharmony_ci << "drawElementsIndirect()\n" 2759e5c31af7Sopenharmony_ci << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n" 2760e5c31af7Sopenharmony_ci << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n" 2761e5c31af7Sopenharmony_ci << "\tindex offset " << indexPointerOffset << "\n" 2762e5c31af7Sopenharmony_ci << "\tinstance count " << instanceCount << "\n" 2763e5c31af7Sopenharmony_ci << "\tindirect offset " << indirectOffset << "\n" 2764e5c31af7Sopenharmony_ci << "\tbase vertex " << baseVertex << "\n"; 2765e5c31af7Sopenharmony_ci } 2766e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_BASEVERTEX) 2767e5c31af7Sopenharmony_ci { 2768e5c31af7Sopenharmony_ci desc 2769e5c31af7Sopenharmony_ci << "drawElementsBaseVertex()\n" 2770e5c31af7Sopenharmony_ci << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n" 2771e5c31af7Sopenharmony_ci << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n" 2772e5c31af7Sopenharmony_ci << "\tindex offset " << indexPointerOffset << "\n" 2773e5c31af7Sopenharmony_ci << "\tbase vertex " << baseVertex << "\n"; 2774e5c31af7Sopenharmony_ci } 2775e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX) 2776e5c31af7Sopenharmony_ci { 2777e5c31af7Sopenharmony_ci desc 2778e5c31af7Sopenharmony_ci << "drawElementsInstancedBaseVertex()\n" 2779e5c31af7Sopenharmony_ci << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n" 2780e5c31af7Sopenharmony_ci << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n" 2781e5c31af7Sopenharmony_ci << "\tindex offset " << indexPointerOffset << "\n" 2782e5c31af7Sopenharmony_ci << "\tinstance count " << instanceCount << "\n" 2783e5c31af7Sopenharmony_ci << "\tbase vertex " << baseVertex << "\n"; 2784e5c31af7Sopenharmony_ci } 2785e5c31af7Sopenharmony_ci else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX) 2786e5c31af7Sopenharmony_ci { 2787e5c31af7Sopenharmony_ci desc 2788e5c31af7Sopenharmony_ci << "drawRangeElementsBaseVertex()\n" 2789e5c31af7Sopenharmony_ci << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n" 2790e5c31af7Sopenharmony_ci << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n" 2791e5c31af7Sopenharmony_ci << "\tindex offset " << indexPointerOffset << "\n" 2792e5c31af7Sopenharmony_ci << "\tbase vertex " << baseVertex << "\n" 2793e5c31af7Sopenharmony_ci << "\trange start " << indexMin << "\n" 2794e5c31af7Sopenharmony_ci << "\trange end " << indexMax << "\n"; 2795e5c31af7Sopenharmony_ci } 2796e5c31af7Sopenharmony_ci else 2797e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2798e5c31af7Sopenharmony_ci 2799e5c31af7Sopenharmony_ci desc << "\t" << primitiveCount << " "; 2800e5c31af7Sopenharmony_ci 2801e5c31af7Sopenharmony_ci switch (primitive) 2802e5c31af7Sopenharmony_ci { 2803e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_POINTS: 2804e5c31af7Sopenharmony_ci desc << "points"; 2805e5c31af7Sopenharmony_ci break; 2806e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES: 2807e5c31af7Sopenharmony_ci desc << "triangles"; 2808e5c31af7Sopenharmony_ci break; 2809e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN: 2810e5c31af7Sopenharmony_ci desc << "triangles (fan)"; 2811e5c31af7Sopenharmony_ci break; 2812e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP: 2813e5c31af7Sopenharmony_ci desc << "triangles (strip)"; 2814e5c31af7Sopenharmony_ci break; 2815e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES: 2816e5c31af7Sopenharmony_ci desc << "lines"; 2817e5c31af7Sopenharmony_ci break; 2818e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP: 2819e5c31af7Sopenharmony_ci desc << "lines (strip)"; 2820e5c31af7Sopenharmony_ci break; 2821e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_LOOP: 2822e5c31af7Sopenharmony_ci desc << "lines (loop)"; 2823e5c31af7Sopenharmony_ci break; 2824e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY: 2825e5c31af7Sopenharmony_ci desc << "lines (adjancency)"; 2826e5c31af7Sopenharmony_ci break; 2827e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY: 2828e5c31af7Sopenharmony_ci desc << "lines (strip, adjancency)"; 2829e5c31af7Sopenharmony_ci break; 2830e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY: 2831e5c31af7Sopenharmony_ci desc << "triangles (adjancency)"; 2832e5c31af7Sopenharmony_ci break; 2833e5c31af7Sopenharmony_ci case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY: 2834e5c31af7Sopenharmony_ci desc << "triangles (strip, adjancency)"; 2835e5c31af7Sopenharmony_ci break; 2836e5c31af7Sopenharmony_ci default: 2837e5c31af7Sopenharmony_ci DE_ASSERT(false); 2838e5c31af7Sopenharmony_ci break; 2839e5c31af7Sopenharmony_ci } 2840e5c31af7Sopenharmony_ci 2841e5c31af7Sopenharmony_ci desc << "\n"; 2842e5c31af7Sopenharmony_ci 2843e5c31af7Sopenharmony_ci return desc.str(); 2844e5c31af7Sopenharmony_ci} 2845e5c31af7Sopenharmony_ci 2846e5c31af7Sopenharmony_ciDrawTestSpec::DrawTestSpec (void) 2847e5c31af7Sopenharmony_ci{ 2848e5c31af7Sopenharmony_ci primitive = PRIMITIVE_LAST; 2849e5c31af7Sopenharmony_ci primitiveCount = 0; 2850e5c31af7Sopenharmony_ci drawMethod = DRAWMETHOD_LAST; 2851e5c31af7Sopenharmony_ci indexType = INDEXTYPE_LAST; 2852e5c31af7Sopenharmony_ci indexPointerOffset = 0; 2853e5c31af7Sopenharmony_ci indexStorage = STORAGE_LAST; 2854e5c31af7Sopenharmony_ci first = 0; 2855e5c31af7Sopenharmony_ci indexMin = 0; 2856e5c31af7Sopenharmony_ci indexMax = 0; 2857e5c31af7Sopenharmony_ci instanceCount = 0; 2858e5c31af7Sopenharmony_ci indirectOffset = 0; 2859e5c31af7Sopenharmony_ci baseVertex = 0; 2860e5c31af7Sopenharmony_ci} 2861e5c31af7Sopenharmony_ci 2862e5c31af7Sopenharmony_ciint DrawTestSpec::hash (void) const 2863e5c31af7Sopenharmony_ci{ 2864e5c31af7Sopenharmony_ci // Use only drawmode-relevant values in "hashing" as the unrelevant values might not be set (causing non-deterministic behavior). 2865e5c31af7Sopenharmony_ci const MethodInfo methodInfo = getMethodInfo(drawMethod); 2866e5c31af7Sopenharmony_ci const bool arrayed = methodInfo.first; 2867e5c31af7Sopenharmony_ci const bool instanced = methodInfo.instanced; 2868e5c31af7Sopenharmony_ci const bool ranged = methodInfo.ranged; 2869e5c31af7Sopenharmony_ci const bool indexed = methodInfo.indexed; 2870e5c31af7Sopenharmony_ci const bool indirect = methodInfo.indirect; 2871e5c31af7Sopenharmony_ci const bool hasBaseVtx = methodInfo.baseVertex; 2872e5c31af7Sopenharmony_ci 2873e5c31af7Sopenharmony_ci const int indexHash = (!indexed) ? (0) : (int(indexType) + 10 * indexPointerOffset + 100 * int(indexStorage)); 2874e5c31af7Sopenharmony_ci const int arrayHash = (!arrayed) ? (0) : (first); 2875e5c31af7Sopenharmony_ci const int indexRangeHash = (!ranged) ? (0) : (indexMin + 10 * indexMax); 2876e5c31af7Sopenharmony_ci const int instanceHash = (!instanced) ? (0) : (instanceCount); 2877e5c31af7Sopenharmony_ci const int indirectHash = (!indirect) ? (0) : (indirectOffset); 2878e5c31af7Sopenharmony_ci const int baseVtxHash = (!hasBaseVtx) ? (0) : (baseVertex); 2879e5c31af7Sopenharmony_ci const int basicHash = int(primitive) + 10 * primitiveCount + 100 * int(drawMethod); 2880e5c31af7Sopenharmony_ci 2881e5c31af7Sopenharmony_ci return indexHash + 3 * arrayHash + 5 * indexRangeHash + 7 * instanceHash + 13 * basicHash + 17 * (int)attribs.size() + 19 * primitiveCount + 23 * indirectHash + 27 * baseVtxHash; 2882e5c31af7Sopenharmony_ci} 2883e5c31af7Sopenharmony_ci 2884e5c31af7Sopenharmony_cibool DrawTestSpec::valid (void) const 2885e5c31af7Sopenharmony_ci{ 2886e5c31af7Sopenharmony_ci DE_ASSERT(apiType.getProfile() != glu::PROFILE_LAST); 2887e5c31af7Sopenharmony_ci DE_ASSERT(primitive != PRIMITIVE_LAST); 2888e5c31af7Sopenharmony_ci DE_ASSERT(drawMethod != DRAWMETHOD_LAST); 2889e5c31af7Sopenharmony_ci 2890e5c31af7Sopenharmony_ci const MethodInfo methodInfo = getMethodInfo(drawMethod); 2891e5c31af7Sopenharmony_ci 2892e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < (int)attribs.size(); ++ndx) 2893e5c31af7Sopenharmony_ci if (!attribs[ndx].valid(apiType)) 2894e5c31af7Sopenharmony_ci return false; 2895e5c31af7Sopenharmony_ci 2896e5c31af7Sopenharmony_ci if (methodInfo.ranged) 2897e5c31af7Sopenharmony_ci { 2898e5c31af7Sopenharmony_ci deUint32 maxIndexValue = 0; 2899e5c31af7Sopenharmony_ci if (indexType == INDEXTYPE_BYTE) 2900e5c31af7Sopenharmony_ci maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_BYTE).ub.getValue(); 2901e5c31af7Sopenharmony_ci else if (indexType == INDEXTYPE_SHORT) 2902e5c31af7Sopenharmony_ci maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_SHORT).us.getValue(); 2903e5c31af7Sopenharmony_ci else if (indexType == INDEXTYPE_INT) 2904e5c31af7Sopenharmony_ci maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_INT).ui.getValue(); 2905e5c31af7Sopenharmony_ci else 2906e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2907e5c31af7Sopenharmony_ci 2908e5c31af7Sopenharmony_ci if (indexMin > indexMax) 2909e5c31af7Sopenharmony_ci return false; 2910e5c31af7Sopenharmony_ci if (indexMin < 0 || indexMax < 0) 2911e5c31af7Sopenharmony_ci return false; 2912e5c31af7Sopenharmony_ci if ((deUint32)indexMin > maxIndexValue || (deUint32)indexMax > maxIndexValue) 2913e5c31af7Sopenharmony_ci return false; 2914e5c31af7Sopenharmony_ci } 2915e5c31af7Sopenharmony_ci 2916e5c31af7Sopenharmony_ci if (methodInfo.first && first < 0) 2917e5c31af7Sopenharmony_ci return false; 2918e5c31af7Sopenharmony_ci 2919e5c31af7Sopenharmony_ci // GLES2 limits 2920e5c31af7Sopenharmony_ci if (apiType == glu::ApiType::es(2,0)) 2921e5c31af7Sopenharmony_ci { 2922e5c31af7Sopenharmony_ci if (drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS && drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS) 2923e5c31af7Sopenharmony_ci return false; 2924e5c31af7Sopenharmony_ci if (drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS && (indexType != INDEXTYPE_BYTE && indexType != INDEXTYPE_SHORT)) 2925e5c31af7Sopenharmony_ci return false; 2926e5c31af7Sopenharmony_ci } 2927e5c31af7Sopenharmony_ci 2928e5c31af7Sopenharmony_ci // Indirect limitations 2929e5c31af7Sopenharmony_ci if (methodInfo.indirect) 2930e5c31af7Sopenharmony_ci { 2931e5c31af7Sopenharmony_ci // Indirect offset alignment 2932e5c31af7Sopenharmony_ci if (indirectOffset % 4 != 0) 2933e5c31af7Sopenharmony_ci return false; 2934e5c31af7Sopenharmony_ci 2935e5c31af7Sopenharmony_ci // All attribute arrays must be stored in a buffer 2936e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < (int)attribs.size(); ++ndx) 2937e5c31af7Sopenharmony_ci if (!attribs[ndx].useDefaultAttribute && attribs[ndx].storage == gls::DrawTestSpec::STORAGE_USER) 2938e5c31af7Sopenharmony_ci return false; 2939e5c31af7Sopenharmony_ci } 2940e5c31af7Sopenharmony_ci if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT) 2941e5c31af7Sopenharmony_ci { 2942e5c31af7Sopenharmony_ci // index offset must be convertable to firstIndex 2943e5c31af7Sopenharmony_ci if (indexPointerOffset % gls::DrawTestSpec::indexTypeSize(indexType) != 0) 2944e5c31af7Sopenharmony_ci return false; 2945e5c31af7Sopenharmony_ci 2946e5c31af7Sopenharmony_ci // Indices must be in a buffer 2947e5c31af7Sopenharmony_ci if (indexStorage != STORAGE_BUFFER) 2948e5c31af7Sopenharmony_ci return false; 2949e5c31af7Sopenharmony_ci } 2950e5c31af7Sopenharmony_ci 2951e5c31af7Sopenharmony_ci // Do not allow user pointer in GL core 2952e5c31af7Sopenharmony_ci if (apiType.getProfile() == glu::PROFILE_CORE) 2953e5c31af7Sopenharmony_ci { 2954e5c31af7Sopenharmony_ci if (methodInfo.indexed && indexStorage == DrawTestSpec::STORAGE_USER) 2955e5c31af7Sopenharmony_ci return false; 2956e5c31af7Sopenharmony_ci } 2957e5c31af7Sopenharmony_ci 2958e5c31af7Sopenharmony_ci return true; 2959e5c31af7Sopenharmony_ci} 2960e5c31af7Sopenharmony_ci 2961e5c31af7Sopenharmony_ciDrawTestSpec::CompatibilityTestType DrawTestSpec::isCompatibilityTest (void) const 2962e5c31af7Sopenharmony_ci{ 2963e5c31af7Sopenharmony_ci const MethodInfo methodInfo = getMethodInfo(drawMethod); 2964e5c31af7Sopenharmony_ci 2965e5c31af7Sopenharmony_ci bool bufferAlignmentBad = false; 2966e5c31af7Sopenharmony_ci bool strideAlignmentBad = false; 2967e5c31af7Sopenharmony_ci 2968e5c31af7Sopenharmony_ci // Attribute buffer alignment 2969e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < (int)attribs.size(); ++ndx) 2970e5c31af7Sopenharmony_ci if (!attribs[ndx].isBufferAligned()) 2971e5c31af7Sopenharmony_ci bufferAlignmentBad = true; 2972e5c31af7Sopenharmony_ci 2973e5c31af7Sopenharmony_ci // Attribute stride alignment 2974e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < (int)attribs.size(); ++ndx) 2975e5c31af7Sopenharmony_ci if (!attribs[ndx].isBufferStrideAligned()) 2976e5c31af7Sopenharmony_ci strideAlignmentBad = true; 2977e5c31af7Sopenharmony_ci 2978e5c31af7Sopenharmony_ci // Index buffer alignment 2979e5c31af7Sopenharmony_ci if (methodInfo.indexed) 2980e5c31af7Sopenharmony_ci { 2981e5c31af7Sopenharmony_ci if (indexStorage == STORAGE_BUFFER) 2982e5c31af7Sopenharmony_ci { 2983e5c31af7Sopenharmony_ci int indexSize = 0; 2984e5c31af7Sopenharmony_ci if (indexType == INDEXTYPE_BYTE) 2985e5c31af7Sopenharmony_ci indexSize = 1; 2986e5c31af7Sopenharmony_ci else if (indexType == INDEXTYPE_SHORT) 2987e5c31af7Sopenharmony_ci indexSize = 2; 2988e5c31af7Sopenharmony_ci else if (indexType == INDEXTYPE_INT) 2989e5c31af7Sopenharmony_ci indexSize = 4; 2990e5c31af7Sopenharmony_ci else 2991e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2992e5c31af7Sopenharmony_ci 2993e5c31af7Sopenharmony_ci if (indexPointerOffset % indexSize != 0) 2994e5c31af7Sopenharmony_ci bufferAlignmentBad = true; 2995e5c31af7Sopenharmony_ci } 2996e5c31af7Sopenharmony_ci } 2997e5c31af7Sopenharmony_ci 2998e5c31af7Sopenharmony_ci // \note combination bad alignment & stride is treated as bad offset 2999e5c31af7Sopenharmony_ci if (bufferAlignmentBad) 3000e5c31af7Sopenharmony_ci return COMPATIBILITY_UNALIGNED_OFFSET; 3001e5c31af7Sopenharmony_ci else if (strideAlignmentBad) 3002e5c31af7Sopenharmony_ci return COMPATIBILITY_UNALIGNED_STRIDE; 3003e5c31af7Sopenharmony_ci else 3004e5c31af7Sopenharmony_ci return COMPATIBILITY_NONE; 3005e5c31af7Sopenharmony_ci} 3006e5c31af7Sopenharmony_ci 3007e5c31af7Sopenharmony_cienum PrimitiveClass 3008e5c31af7Sopenharmony_ci{ 3009e5c31af7Sopenharmony_ci PRIMITIVECLASS_POINT = 0, 3010e5c31af7Sopenharmony_ci PRIMITIVECLASS_LINE, 3011e5c31af7Sopenharmony_ci PRIMITIVECLASS_TRIANGLE, 3012e5c31af7Sopenharmony_ci 3013e5c31af7Sopenharmony_ci PRIMITIVECLASS_LAST 3014e5c31af7Sopenharmony_ci}; 3015e5c31af7Sopenharmony_ci 3016e5c31af7Sopenharmony_cistatic PrimitiveClass getDrawPrimitiveClass (gls::DrawTestSpec::Primitive primitiveType) 3017e5c31af7Sopenharmony_ci{ 3018e5c31af7Sopenharmony_ci switch (primitiveType) 3019e5c31af7Sopenharmony_ci { 3020e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_POINTS: 3021e5c31af7Sopenharmony_ci return PRIMITIVECLASS_POINT; 3022e5c31af7Sopenharmony_ci 3023e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_LINES: 3024e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP: 3025e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP: 3026e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY: 3027e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY: 3028e5c31af7Sopenharmony_ci return PRIMITIVECLASS_LINE; 3029e5c31af7Sopenharmony_ci 3030e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_TRIANGLES: 3031e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN: 3032e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP: 3033e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY: 3034e5c31af7Sopenharmony_ci case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY: 3035e5c31af7Sopenharmony_ci return PRIMITIVECLASS_TRIANGLE; 3036e5c31af7Sopenharmony_ci 3037e5c31af7Sopenharmony_ci default: 3038e5c31af7Sopenharmony_ci DE_ASSERT(false); 3039e5c31af7Sopenharmony_ci return PRIMITIVECLASS_LAST; 3040e5c31af7Sopenharmony_ci } 3041e5c31af7Sopenharmony_ci} 3042e5c31af7Sopenharmony_ci 3043e5c31af7Sopenharmony_cistatic bool containsLineCases (const std::vector<DrawTestSpec>& m_specs) 3044e5c31af7Sopenharmony_ci{ 3045e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < (int)m_specs.size(); ++ndx) 3046e5c31af7Sopenharmony_ci { 3047e5c31af7Sopenharmony_ci if (getDrawPrimitiveClass(m_specs[ndx].primitive) == PRIMITIVECLASS_LINE) 3048e5c31af7Sopenharmony_ci return true; 3049e5c31af7Sopenharmony_ci } 3050e5c31af7Sopenharmony_ci return false; 3051e5c31af7Sopenharmony_ci} 3052e5c31af7Sopenharmony_ci 3053e5c31af7Sopenharmony_ci// DrawTest 3054e5c31af7Sopenharmony_ci 3055e5c31af7Sopenharmony_ciDrawTest::DrawTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const DrawTestSpec& spec, const char* name, const char* desc) 3056e5c31af7Sopenharmony_ci : TestCase (testCtx, name, desc) 3057e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 3058e5c31af7Sopenharmony_ci , m_contextInfo (DE_NULL) 3059e5c31af7Sopenharmony_ci , m_refBuffers (DE_NULL) 3060e5c31af7Sopenharmony_ci , m_refContext (DE_NULL) 3061e5c31af7Sopenharmony_ci , m_glesContext (DE_NULL) 3062e5c31af7Sopenharmony_ci , m_glArrayPack (DE_NULL) 3063e5c31af7Sopenharmony_ci , m_rrArrayPack (DE_NULL) 3064e5c31af7Sopenharmony_ci , m_maxDiffRed (-1) 3065e5c31af7Sopenharmony_ci , m_maxDiffGreen (-1) 3066e5c31af7Sopenharmony_ci , m_maxDiffBlue (-1) 3067e5c31af7Sopenharmony_ci , m_iteration (0) 3068e5c31af7Sopenharmony_ci , m_result () // \note no per-iteration result logging (only one iteration) 3069e5c31af7Sopenharmony_ci{ 3070e5c31af7Sopenharmony_ci addIteration(spec); 3071e5c31af7Sopenharmony_ci} 3072e5c31af7Sopenharmony_ci 3073e5c31af7Sopenharmony_ciDrawTest::DrawTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc) 3074e5c31af7Sopenharmony_ci : TestCase (testCtx, name, desc) 3075e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 3076e5c31af7Sopenharmony_ci , m_contextInfo (DE_NULL) 3077e5c31af7Sopenharmony_ci , m_refBuffers (DE_NULL) 3078e5c31af7Sopenharmony_ci , m_refContext (DE_NULL) 3079e5c31af7Sopenharmony_ci , m_glesContext (DE_NULL) 3080e5c31af7Sopenharmony_ci , m_glArrayPack (DE_NULL) 3081e5c31af7Sopenharmony_ci , m_rrArrayPack (DE_NULL) 3082e5c31af7Sopenharmony_ci , m_maxDiffRed (-1) 3083e5c31af7Sopenharmony_ci , m_maxDiffGreen (-1) 3084e5c31af7Sopenharmony_ci , m_maxDiffBlue (-1) 3085e5c31af7Sopenharmony_ci , m_iteration (0) 3086e5c31af7Sopenharmony_ci , m_result (testCtx.getLog(), "Iteration result: ") 3087e5c31af7Sopenharmony_ci{ 3088e5c31af7Sopenharmony_ci} 3089e5c31af7Sopenharmony_ci 3090e5c31af7Sopenharmony_ciDrawTest::~DrawTest (void) 3091e5c31af7Sopenharmony_ci{ 3092e5c31af7Sopenharmony_ci deinit(); 3093e5c31af7Sopenharmony_ci} 3094e5c31af7Sopenharmony_ci 3095e5c31af7Sopenharmony_civoid DrawTest::addIteration (const DrawTestSpec& spec, const char* description) 3096e5c31af7Sopenharmony_ci{ 3097e5c31af7Sopenharmony_ci // Validate spec 3098e5c31af7Sopenharmony_ci const bool validSpec = spec.valid(); 3099e5c31af7Sopenharmony_ci DE_ASSERT(validSpec); 3100e5c31af7Sopenharmony_ci 3101e5c31af7Sopenharmony_ci if (!validSpec) 3102e5c31af7Sopenharmony_ci return; 3103e5c31af7Sopenharmony_ci 3104e5c31af7Sopenharmony_ci // Check the context type is the same with other iterations 3105e5c31af7Sopenharmony_ci if (!m_specs.empty()) 3106e5c31af7Sopenharmony_ci { 3107e5c31af7Sopenharmony_ci const bool validContext = m_specs[0].apiType == spec.apiType; 3108e5c31af7Sopenharmony_ci DE_ASSERT(validContext); 3109e5c31af7Sopenharmony_ci 3110e5c31af7Sopenharmony_ci if (!validContext) 3111e5c31af7Sopenharmony_ci return; 3112e5c31af7Sopenharmony_ci } 3113e5c31af7Sopenharmony_ci 3114e5c31af7Sopenharmony_ci m_specs.push_back(spec); 3115e5c31af7Sopenharmony_ci 3116e5c31af7Sopenharmony_ci if (description) 3117e5c31af7Sopenharmony_ci m_iteration_descriptions.push_back(std::string(description)); 3118e5c31af7Sopenharmony_ci else 3119e5c31af7Sopenharmony_ci m_iteration_descriptions.push_back(std::string()); 3120e5c31af7Sopenharmony_ci} 3121e5c31af7Sopenharmony_ci 3122e5c31af7Sopenharmony_civoid DrawTest::init (void) 3123e5c31af7Sopenharmony_ci{ 3124e5c31af7Sopenharmony_ci DE_ASSERT(!m_specs.empty()); 3125e5c31af7Sopenharmony_ci DE_ASSERT(contextSupports(m_renderCtx.getType(), m_specs[0].apiType)); 3126e5c31af7Sopenharmony_ci 3127e5c31af7Sopenharmony_ci const int renderTargetWidth = de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getWidth()); 3128e5c31af7Sopenharmony_ci const int renderTargetHeight = de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getHeight()); 3129e5c31af7Sopenharmony_ci 3130e5c31af7Sopenharmony_ci // lines have significantly different rasterization in MSAA mode 3131e5c31af7Sopenharmony_ci const bool isLineCase = containsLineCases(m_specs); 3132e5c31af7Sopenharmony_ci const bool isMSAACase = m_renderCtx.getRenderTarget().getNumSamples() > 1; 3133e5c31af7Sopenharmony_ci const int renderTargetSamples = (isMSAACase && isLineCase) ? (4) : (1); 3134e5c31af7Sopenharmony_ci 3135e5c31af7Sopenharmony_ci sglr::ReferenceContextLimits limits (m_renderCtx); 3136e5c31af7Sopenharmony_ci bool useVao = false; 3137e5c31af7Sopenharmony_ci 3138e5c31af7Sopenharmony_ci m_glesContext = new sglr::GLContext(m_renderCtx, m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS, tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight)); 3139e5c31af7Sopenharmony_ci 3140e5c31af7Sopenharmony_ci if (m_renderCtx.getType().getAPI() == glu::ApiType::es(2,0) || m_renderCtx.getType().getAPI() == glu::ApiType::es(3,0)) 3141e5c31af7Sopenharmony_ci useVao = false; 3142e5c31af7Sopenharmony_ci else if (contextSupports(m_renderCtx.getType(), glu::ApiType::es(3,1)) || glu::isContextTypeGLCore(m_renderCtx.getType())) 3143e5c31af7Sopenharmony_ci useVao = true; 3144e5c31af7Sopenharmony_ci else 3145e5c31af7Sopenharmony_ci DE_FATAL("Unknown context type"); 3146e5c31af7Sopenharmony_ci 3147e5c31af7Sopenharmony_ci m_refBuffers = new sglr::ReferenceContextBuffers(m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, renderTargetWidth, renderTargetHeight, renderTargetSamples); 3148e5c31af7Sopenharmony_ci m_refContext = new sglr::ReferenceContext(limits, m_refBuffers->getColorbuffer(), m_refBuffers->getDepthbuffer(), m_refBuffers->getStencilbuffer()); 3149e5c31af7Sopenharmony_ci 3150e5c31af7Sopenharmony_ci m_glArrayPack = new AttributePack(m_testCtx, m_renderCtx, *m_glesContext, tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, true); 3151e5c31af7Sopenharmony_ci m_rrArrayPack = new AttributePack(m_testCtx, m_renderCtx, *m_refContext, tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, false); 3152e5c31af7Sopenharmony_ci 3153e5c31af7Sopenharmony_ci m_maxDiffRed = deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits))); 3154e5c31af7Sopenharmony_ci m_maxDiffGreen = deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits))); 3155e5c31af7Sopenharmony_ci m_maxDiffBlue = deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().blueBits))); 3156e5c31af7Sopenharmony_ci m_contextInfo = glu::ContextInfo::create(m_renderCtx); 3157e5c31af7Sopenharmony_ci} 3158e5c31af7Sopenharmony_ci 3159e5c31af7Sopenharmony_civoid DrawTest::deinit (void) 3160e5c31af7Sopenharmony_ci{ 3161e5c31af7Sopenharmony_ci delete m_glArrayPack; 3162e5c31af7Sopenharmony_ci delete m_rrArrayPack; 3163e5c31af7Sopenharmony_ci delete m_refBuffers; 3164e5c31af7Sopenharmony_ci delete m_refContext; 3165e5c31af7Sopenharmony_ci delete m_glesContext; 3166e5c31af7Sopenharmony_ci delete m_contextInfo; 3167e5c31af7Sopenharmony_ci 3168e5c31af7Sopenharmony_ci m_glArrayPack = DE_NULL; 3169e5c31af7Sopenharmony_ci m_rrArrayPack = DE_NULL; 3170e5c31af7Sopenharmony_ci m_refBuffers = DE_NULL; 3171e5c31af7Sopenharmony_ci m_refContext = DE_NULL; 3172e5c31af7Sopenharmony_ci m_glesContext = DE_NULL; 3173e5c31af7Sopenharmony_ci m_contextInfo = DE_NULL; 3174e5c31af7Sopenharmony_ci} 3175e5c31af7Sopenharmony_ci 3176e5c31af7Sopenharmony_ciDrawTest::IterateResult DrawTest::iterate (void) 3177e5c31af7Sopenharmony_ci{ 3178e5c31af7Sopenharmony_ci const int specNdx = (m_iteration / 2); 3179e5c31af7Sopenharmony_ci const DrawTestSpec& spec = m_specs[specNdx]; 3180e5c31af7Sopenharmony_ci 3181e5c31af7Sopenharmony_ci if (spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX || 3182e5c31af7Sopenharmony_ci spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX || 3183e5c31af7Sopenharmony_ci spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX) 3184e5c31af7Sopenharmony_ci { 3185e5c31af7Sopenharmony_ci const bool supportsES32orGL45 = contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 2)) || 3186e5c31af7Sopenharmony_ci contextSupports(m_renderCtx.getType(), glu::ApiType::core(4, 5)); 3187e5c31af7Sopenharmony_ci TCU_CHECK_AND_THROW(NotSupportedError, supportsES32orGL45 || m_contextInfo->isExtensionSupported("GL_EXT_draw_elements_base_vertex"), "GL_EXT_draw_elements_base_vertex is not supported."); 3188e5c31af7Sopenharmony_ci } 3189e5c31af7Sopenharmony_ci 3190e5c31af7Sopenharmony_ci const bool drawStep = (m_iteration % 2) == 0; 3191e5c31af7Sopenharmony_ci const bool compareStep = (m_iteration % 2) == 1; 3192e5c31af7Sopenharmony_ci const IterateResult iterateResult = ((size_t)m_iteration + 1 == m_specs.size()*2) ? (STOP) : (CONTINUE); 3193e5c31af7Sopenharmony_ci const bool updateProgram = (m_iteration == 0) || (drawStep && !checkSpecsShaderCompatible(m_specs[specNdx], m_specs[specNdx-1])); // try to use the same shader in all iterations 3194e5c31af7Sopenharmony_ci IterationLogSectionEmitter sectionEmitter (m_testCtx.getLog(), specNdx, m_specs.size(), m_iteration_descriptions[specNdx], drawStep && m_specs.size()!=1); 3195e5c31af7Sopenharmony_ci 3196e5c31af7Sopenharmony_ci if (drawStep) 3197e5c31af7Sopenharmony_ci { 3198e5c31af7Sopenharmony_ci const MethodInfo methodInfo = getMethodInfo(spec.drawMethod); 3199e5c31af7Sopenharmony_ci const bool indexed = methodInfo.indexed; 3200e5c31af7Sopenharmony_ci const bool instanced = methodInfo.instanced; 3201e5c31af7Sopenharmony_ci const bool ranged = methodInfo.ranged; 3202e5c31af7Sopenharmony_ci const bool hasFirst = methodInfo.first; 3203e5c31af7Sopenharmony_ci const bool hasBaseVtx = methodInfo.baseVertex; 3204e5c31af7Sopenharmony_ci 3205e5c31af7Sopenharmony_ci const size_t primitiveElementCount = getElementCount(spec.primitive, spec.primitiveCount); // !< elements to be drawn 3206e5c31af7Sopenharmony_ci const int indexMin = (ranged) ? (spec.indexMin) : (0); 3207e5c31af7Sopenharmony_ci const int firstAddition = (hasFirst) ? (spec.first) : (0); 3208e5c31af7Sopenharmony_ci const int baseVertexAddition = (hasBaseVtx && spec.baseVertex > 0) ? ( spec.baseVertex) : (0); // spec.baseVertex > 0 => Create bigger attribute buffer 3209e5c31af7Sopenharmony_ci const int indexBase = (hasBaseVtx && spec.baseVertex < 0) ? (-spec.baseVertex) : (0); // spec.baseVertex < 0 => Create bigger indices 3210e5c31af7Sopenharmony_ci const size_t elementCount = primitiveElementCount + indexMin + firstAddition + baseVertexAddition; // !< elements in buffer (buffer should have at least primitiveElementCount ACCESSIBLE (index range, first) elements) 3211e5c31af7Sopenharmony_ci const int maxElementIndex = (int)primitiveElementCount + indexMin + firstAddition - 1; 3212e5c31af7Sopenharmony_ci const int indexMax = de::max(0, (ranged) ? (de::clamp<int>(spec.indexMax, 0, maxElementIndex)) : (maxElementIndex)); 3213e5c31af7Sopenharmony_ci float coordScale = getCoordScale(spec); 3214e5c31af7Sopenharmony_ci float colorScale = getColorScale(spec); 3215e5c31af7Sopenharmony_ci 3216e5c31af7Sopenharmony_ci rr::GenericVec4 nullAttribValue; 3217e5c31af7Sopenharmony_ci 3218e5c31af7Sopenharmony_ci // Log info 3219e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << spec.getMultilineDesc() << TestLog::EndMessage; 3220e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << TestLog::EndMessage; // extra line for clarity 3221e5c31af7Sopenharmony_ci 3222e5c31af7Sopenharmony_ci // Data 3223e5c31af7Sopenharmony_ci 3224e5c31af7Sopenharmony_ci m_glArrayPack->clearArrays(); 3225e5c31af7Sopenharmony_ci m_rrArrayPack->clearArrays(); 3226e5c31af7Sopenharmony_ci 3227e5c31af7Sopenharmony_ci for (int attribNdx = 0; attribNdx < (int)spec.attribs.size(); attribNdx++) 3228e5c31af7Sopenharmony_ci { 3229e5c31af7Sopenharmony_ci DrawTestSpec::AttributeSpec attribSpec = spec.attribs[attribNdx]; 3230e5c31af7Sopenharmony_ci const bool isPositionAttr = (attribNdx == 0) || (attribSpec.additionalPositionAttribute); 3231e5c31af7Sopenharmony_ci 3232e5c31af7Sopenharmony_ci if (attribSpec.useDefaultAttribute) 3233e5c31af7Sopenharmony_ci { 3234e5c31af7Sopenharmony_ci const int seed = 10 * attribSpec.hash() + 100 * spec.hash() + attribNdx; 3235e5c31af7Sopenharmony_ci rr::GenericVec4 attribValue = RandomArrayGenerator::generateAttributeValue(seed, attribSpec.inputType); 3236e5c31af7Sopenharmony_ci 3237e5c31af7Sopenharmony_ci m_glArrayPack->newArray(DrawTestSpec::STORAGE_USER); 3238e5c31af7Sopenharmony_ci m_rrArrayPack->newArray(DrawTestSpec::STORAGE_USER); 3239e5c31af7Sopenharmony_ci 3240e5c31af7Sopenharmony_ci m_glArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, false, 0, 0, attribValue, isPositionAttr, false); 3241e5c31af7Sopenharmony_ci m_rrArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, false, 0, 0, attribValue, isPositionAttr, false); 3242e5c31af7Sopenharmony_ci } 3243e5c31af7Sopenharmony_ci else 3244e5c31af7Sopenharmony_ci { 3245e5c31af7Sopenharmony_ci const int seed = attribSpec.hash() + 100 * spec.hash() + attribNdx; 3246e5c31af7Sopenharmony_ci const size_t elementSize = attribSpec.componentCount * DrawTestSpec::inputTypeSize(attribSpec.inputType); 3247e5c31af7Sopenharmony_ci const size_t stride = (attribSpec.stride == 0) ? (elementSize) : (attribSpec.stride); 3248e5c31af7Sopenharmony_ci const size_t evaluatedElementCount = (instanced && attribSpec.instanceDivisor > 0) ? (spec.instanceCount / attribSpec.instanceDivisor + 1) : (elementCount); 3249e5c31af7Sopenharmony_ci const size_t referencedElementCount = (ranged) ? (de::max<size_t>(evaluatedElementCount, spec.indexMax + 1)) : (evaluatedElementCount); 3250e5c31af7Sopenharmony_ci const size_t bufferSize = attribSpec.offset + stride * (referencedElementCount - 1) + elementSize; 3251e5c31af7Sopenharmony_ci const char* data = RandomArrayGenerator::generateArray(seed, (int)referencedElementCount, attribSpec.componentCount, attribSpec.offset, (int)stride, attribSpec.inputType); 3252e5c31af7Sopenharmony_ci 3253e5c31af7Sopenharmony_ci try 3254e5c31af7Sopenharmony_ci { 3255e5c31af7Sopenharmony_ci m_glArrayPack->newArray(attribSpec.storage); 3256e5c31af7Sopenharmony_ci m_rrArrayPack->newArray(attribSpec.storage); 3257e5c31af7Sopenharmony_ci 3258e5c31af7Sopenharmony_ci m_glArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data, attribSpec.usage); 3259e5c31af7Sopenharmony_ci m_rrArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data, attribSpec.usage); 3260e5c31af7Sopenharmony_ci 3261e5c31af7Sopenharmony_ci m_glArrayPack->getArray(attribNdx)->setupArray(true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue, isPositionAttr, attribSpec.bgraComponentOrder); 3262e5c31af7Sopenharmony_ci m_rrArrayPack->getArray(attribNdx)->setupArray(true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue, isPositionAttr, attribSpec.bgraComponentOrder); 3263e5c31af7Sopenharmony_ci 3264e5c31af7Sopenharmony_ci delete [] data; 3265e5c31af7Sopenharmony_ci data = NULL; 3266e5c31af7Sopenharmony_ci } 3267e5c31af7Sopenharmony_ci catch (...) 3268e5c31af7Sopenharmony_ci { 3269e5c31af7Sopenharmony_ci delete [] data; 3270e5c31af7Sopenharmony_ci throw; 3271e5c31af7Sopenharmony_ci } 3272e5c31af7Sopenharmony_ci } 3273e5c31af7Sopenharmony_ci } 3274e5c31af7Sopenharmony_ci 3275e5c31af7Sopenharmony_ci // Shader program 3276e5c31af7Sopenharmony_ci if (updateProgram) 3277e5c31af7Sopenharmony_ci { 3278e5c31af7Sopenharmony_ci m_glArrayPack->updateProgram(); 3279e5c31af7Sopenharmony_ci m_rrArrayPack->updateProgram(); 3280e5c31af7Sopenharmony_ci } 3281e5c31af7Sopenharmony_ci 3282e5c31af7Sopenharmony_ci // Draw 3283e5c31af7Sopenharmony_ci try 3284e5c31af7Sopenharmony_ci { 3285e5c31af7Sopenharmony_ci // indices 3286e5c31af7Sopenharmony_ci if (indexed) 3287e5c31af7Sopenharmony_ci { 3288e5c31af7Sopenharmony_ci const int seed = spec.hash(); 3289e5c31af7Sopenharmony_ci const size_t indexElementSize = DrawTestSpec::indexTypeSize(spec.indexType); 3290e5c31af7Sopenharmony_ci const size_t indexArraySize = spec.indexPointerOffset + indexElementSize * elementCount; 3291e5c31af7Sopenharmony_ci const char* indexArray = RandomArrayGenerator::generateIndices(seed, (int)elementCount, spec.indexType, spec.indexPointerOffset, indexMin, indexMax, indexBase); 3292e5c31af7Sopenharmony_ci const char* indexPointerBase = (spec.indexStorage == DrawTestSpec::STORAGE_USER) ? (indexArray) : ((char*)DE_NULL); 3293e5c31af7Sopenharmony_ci const char* indexPointer = indexPointerBase + spec.indexPointerOffset; 3294e5c31af7Sopenharmony_ci 3295e5c31af7Sopenharmony_ci de::UniquePtr<AttributeArray> glArray (new AttributeArray(spec.indexStorage, *m_glesContext)); 3296e5c31af7Sopenharmony_ci de::UniquePtr<AttributeArray> rrArray (new AttributeArray(spec.indexStorage, *m_refContext)); 3297e5c31af7Sopenharmony_ci 3298e5c31af7Sopenharmony_ci try 3299e5c31af7Sopenharmony_ci { 3300e5c31af7Sopenharmony_ci glArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray, DrawTestSpec::USAGE_STATIC_DRAW); 3301e5c31af7Sopenharmony_ci rrArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray, DrawTestSpec::USAGE_STATIC_DRAW); 3302e5c31af7Sopenharmony_ci 3303e5c31af7Sopenharmony_ci m_glArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount, spec.indexType, indexPointer, spec.indexMin, spec.indexMax, spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale, colorScale, glArray.get()); 3304e5c31af7Sopenharmony_ci m_rrArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount, spec.indexType, indexPointer, spec.indexMin, spec.indexMax, spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale, colorScale, rrArray.get()); 3305e5c31af7Sopenharmony_ci 3306e5c31af7Sopenharmony_ci delete [] indexArray; 3307e5c31af7Sopenharmony_ci indexArray = NULL; 3308e5c31af7Sopenharmony_ci } 3309e5c31af7Sopenharmony_ci catch (...) 3310e5c31af7Sopenharmony_ci { 3311e5c31af7Sopenharmony_ci delete [] indexArray; 3312e5c31af7Sopenharmony_ci throw; 3313e5c31af7Sopenharmony_ci } 3314e5c31af7Sopenharmony_ci } 3315e5c31af7Sopenharmony_ci else 3316e5c31af7Sopenharmony_ci { 3317e5c31af7Sopenharmony_ci m_glArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount, DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount, spec.indirectOffset, 0, coordScale, colorScale, DE_NULL); 3318e5c31af7Sopenharmony_ci m_testCtx.touchWatchdog(); 3319e5c31af7Sopenharmony_ci m_rrArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount, DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount, spec.indirectOffset, 0, coordScale, colorScale, DE_NULL); 3320e5c31af7Sopenharmony_ci } 3321e5c31af7Sopenharmony_ci } 3322e5c31af7Sopenharmony_ci catch (glu::Error& err) 3323e5c31af7Sopenharmony_ci { 3324e5c31af7Sopenharmony_ci // GL Errors are ok if the mode is not properly aligned 3325e5c31af7Sopenharmony_ci 3326e5c31af7Sopenharmony_ci const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest(); 3327e5c31af7Sopenharmony_ci 3328e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "Got error: " << err.what() << TestLog::EndMessage; 3329e5c31af7Sopenharmony_ci 3330e5c31af7Sopenharmony_ci if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET) 3331e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers."); 3332e5c31af7Sopenharmony_ci else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE) 3333e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride."); 3334e5c31af7Sopenharmony_ci else 3335e5c31af7Sopenharmony_ci throw; 3336e5c31af7Sopenharmony_ci } 3337e5c31af7Sopenharmony_ci } 3338e5c31af7Sopenharmony_ci else if (compareStep) 3339e5c31af7Sopenharmony_ci { 3340e5c31af7Sopenharmony_ci if (!compare(spec.primitive)) 3341e5c31af7Sopenharmony_ci { 3342e5c31af7Sopenharmony_ci const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest(); 3343e5c31af7Sopenharmony_ci 3344e5c31af7Sopenharmony_ci if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET) 3345e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers."); 3346e5c31af7Sopenharmony_ci else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE) 3347e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride."); 3348e5c31af7Sopenharmony_ci else 3349e5c31af7Sopenharmony_ci m_result.addResult(QP_TEST_RESULT_FAIL, "Image comparison failed."); 3350e5c31af7Sopenharmony_ci } 3351e5c31af7Sopenharmony_ci } 3352e5c31af7Sopenharmony_ci else 3353e5c31af7Sopenharmony_ci { 3354e5c31af7Sopenharmony_ci DE_ASSERT(false); 3355e5c31af7Sopenharmony_ci return STOP; 3356e5c31af7Sopenharmony_ci } 3357e5c31af7Sopenharmony_ci 3358e5c31af7Sopenharmony_ci m_result.setTestContextResult(m_testCtx); 3359e5c31af7Sopenharmony_ci 3360e5c31af7Sopenharmony_ci m_iteration++; 3361e5c31af7Sopenharmony_ci return iterateResult; 3362e5c31af7Sopenharmony_ci} 3363e5c31af7Sopenharmony_ci 3364e5c31af7Sopenharmony_cistatic bool isBlack (const tcu::RGBA& c) 3365e5c31af7Sopenharmony_ci{ 3366e5c31af7Sopenharmony_ci // ignore alpha channel 3367e5c31af7Sopenharmony_ci return c.getRed() == 0 && c.getGreen() == 0 && c.getBlue() == 0; 3368e5c31af7Sopenharmony_ci} 3369e5c31af7Sopenharmony_ci 3370e5c31af7Sopenharmony_cistatic bool isEdgeTripletComponent (int c1, int c2, int c3, int renderTargetDifference) 3371e5c31af7Sopenharmony_ci{ 3372e5c31af7Sopenharmony_ci const int roundingDifference = 2 * renderTargetDifference; // src and dst pixels rounded to different directions 3373e5c31af7Sopenharmony_ci const int d1 = c2 - c1; 3374e5c31af7Sopenharmony_ci const int d2 = c3 - c2; 3375e5c31af7Sopenharmony_ci const int rampDiff = de::abs(d2 - d1); 3376e5c31af7Sopenharmony_ci 3377e5c31af7Sopenharmony_ci return rampDiff > roundingDifference; 3378e5c31af7Sopenharmony_ci} 3379e5c31af7Sopenharmony_ci 3380e5c31af7Sopenharmony_cistatic bool isEdgeTriplet (const tcu::RGBA& c1, const tcu::RGBA& c2, const tcu::RGBA& c3, const tcu::IVec3& renderTargetThreshold) 3381e5c31af7Sopenharmony_ci{ 3382e5c31af7Sopenharmony_ci // black (background color) and non-black is always an edge 3383e5c31af7Sopenharmony_ci { 3384e5c31af7Sopenharmony_ci const bool b1 = isBlack(c1); 3385e5c31af7Sopenharmony_ci const bool b2 = isBlack(c2); 3386e5c31af7Sopenharmony_ci const bool b3 = isBlack(c3); 3387e5c31af7Sopenharmony_ci 3388e5c31af7Sopenharmony_ci // both pixels with coverage and pixels without coverage 3389e5c31af7Sopenharmony_ci if ((b1 && b2 && b3) == false && (b1 || b2 || b3) == true) 3390e5c31af7Sopenharmony_ci return true; 3391e5c31af7Sopenharmony_ci // all black 3392e5c31af7Sopenharmony_ci if (b1 && b2 && b3) 3393e5c31af7Sopenharmony_ci return false; 3394e5c31af7Sopenharmony_ci // all with coverage 3395e5c31af7Sopenharmony_ci DE_ASSERT(!b1 && !b2 && !b3); 3396e5c31af7Sopenharmony_ci } 3397e5c31af7Sopenharmony_ci 3398e5c31af7Sopenharmony_ci // Color is always linearly interpolated => component values change nearly linearly 3399e5c31af7Sopenharmony_ci // in any constant direction on triangle hull. (df/dx ~= C). 3400e5c31af7Sopenharmony_ci 3401e5c31af7Sopenharmony_ci // Edge detection (this function) is run against the reference image 3402e5c31af7Sopenharmony_ci // => no dithering to worry about 3403e5c31af7Sopenharmony_ci 3404e5c31af7Sopenharmony_ci return isEdgeTripletComponent(c1.getRed(), c2.getRed(), c3.getRed(), renderTargetThreshold.x()) || 3405e5c31af7Sopenharmony_ci isEdgeTripletComponent(c1.getGreen(), c2.getGreen(), c3.getGreen(), renderTargetThreshold.y()) || 3406e5c31af7Sopenharmony_ci isEdgeTripletComponent(c1.getBlue(), c2.getBlue(), c3.getBlue(), renderTargetThreshold.z()); 3407e5c31af7Sopenharmony_ci} 3408e5c31af7Sopenharmony_ci 3409e5c31af7Sopenharmony_cistatic bool pixelNearEdge (int x, int y, const tcu::Surface& ref, const tcu::IVec3& renderTargetThreshold) 3410e5c31af7Sopenharmony_ci{ 3411e5c31af7Sopenharmony_ci // should not be called for edge pixels 3412e5c31af7Sopenharmony_ci DE_ASSERT(x >= 1 && x <= ref.getWidth()-2); 3413e5c31af7Sopenharmony_ci DE_ASSERT(y >= 1 && y <= ref.getHeight()-2); 3414e5c31af7Sopenharmony_ci 3415e5c31af7Sopenharmony_ci // horizontal 3416e5c31af7Sopenharmony_ci 3417e5c31af7Sopenharmony_ci for (int dy = -1; dy < 2; ++dy) 3418e5c31af7Sopenharmony_ci { 3419e5c31af7Sopenharmony_ci const tcu::RGBA c1 = ref.getPixel(x-1, y+dy); 3420e5c31af7Sopenharmony_ci const tcu::RGBA c2 = ref.getPixel(x, y+dy); 3421e5c31af7Sopenharmony_ci const tcu::RGBA c3 = ref.getPixel(x+1, y+dy); 3422e5c31af7Sopenharmony_ci if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold)) 3423e5c31af7Sopenharmony_ci return true; 3424e5c31af7Sopenharmony_ci } 3425e5c31af7Sopenharmony_ci 3426e5c31af7Sopenharmony_ci // vertical 3427e5c31af7Sopenharmony_ci 3428e5c31af7Sopenharmony_ci for (int dx = -1; dx < 2; ++dx) 3429e5c31af7Sopenharmony_ci { 3430e5c31af7Sopenharmony_ci const tcu::RGBA c1 = ref.getPixel(x+dx, y-1); 3431e5c31af7Sopenharmony_ci const tcu::RGBA c2 = ref.getPixel(x+dx, y); 3432e5c31af7Sopenharmony_ci const tcu::RGBA c3 = ref.getPixel(x+dx, y+1); 3433e5c31af7Sopenharmony_ci if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold)) 3434e5c31af7Sopenharmony_ci return true; 3435e5c31af7Sopenharmony_ci } 3436e5c31af7Sopenharmony_ci 3437e5c31af7Sopenharmony_ci return false; 3438e5c31af7Sopenharmony_ci} 3439e5c31af7Sopenharmony_ci 3440e5c31af7Sopenharmony_cistatic deUint32 getVisualizationGrayscaleColor (const tcu::RGBA& c) 3441e5c31af7Sopenharmony_ci{ 3442e5c31af7Sopenharmony_ci // make triangle coverage and error pixels obvious by converting coverage to grayscale 3443e5c31af7Sopenharmony_ci if (isBlack(c)) 3444e5c31af7Sopenharmony_ci return 0; 3445e5c31af7Sopenharmony_ci else 3446e5c31af7Sopenharmony_ci return 50u + (deUint32)(c.getRed() + c.getBlue() + c.getGreen()) / 8u; 3447e5c31af7Sopenharmony_ci} 3448e5c31af7Sopenharmony_ci 3449e5c31af7Sopenharmony_cistatic bool pixelNearLineIntersection (int x, int y, const tcu::Surface& target) 3450e5c31af7Sopenharmony_ci{ 3451e5c31af7Sopenharmony_ci // should not be called for edge pixels 3452e5c31af7Sopenharmony_ci DE_ASSERT(x >= 1 && x <= target.getWidth()-2); 3453e5c31af7Sopenharmony_ci DE_ASSERT(y >= 1 && y <= target.getHeight()-2); 3454e5c31af7Sopenharmony_ci 3455e5c31af7Sopenharmony_ci int coveredPixels = 0; 3456e5c31af7Sopenharmony_ci 3457e5c31af7Sopenharmony_ci for (int dy = -1; dy < 2; dy++) 3458e5c31af7Sopenharmony_ci for (int dx = -1; dx < 2; dx++) 3459e5c31af7Sopenharmony_ci { 3460e5c31af7Sopenharmony_ci const bool targetCoverage = !isBlack(target.getPixel(x+dx, y+dy)); 3461e5c31af7Sopenharmony_ci if (targetCoverage) 3462e5c31af7Sopenharmony_ci { 3463e5c31af7Sopenharmony_ci ++coveredPixels; 3464e5c31af7Sopenharmony_ci 3465e5c31af7Sopenharmony_ci // A single thin line cannot have more than 3 covered pixels in a 3x3 area 3466e5c31af7Sopenharmony_ci if (coveredPixels >= 4) 3467e5c31af7Sopenharmony_ci return true; 3468e5c31af7Sopenharmony_ci } 3469e5c31af7Sopenharmony_ci } 3470e5c31af7Sopenharmony_ci 3471e5c31af7Sopenharmony_ci return false; 3472e5c31af7Sopenharmony_ci} 3473e5c31af7Sopenharmony_ci 3474e5c31af7Sopenharmony_cistatic inline bool colorsEqual (const tcu::RGBA& colorA, const tcu::RGBA& colorB, const tcu::IVec3& compareThreshold) 3475e5c31af7Sopenharmony_ci{ 3476e5c31af7Sopenharmony_ci enum 3477e5c31af7Sopenharmony_ci { 3478e5c31af7Sopenharmony_ci TCU_RGBA_RGB_MASK = tcu::RGBA::RED_MASK | tcu::RGBA::GREEN_MASK | tcu::RGBA::BLUE_MASK 3479e5c31af7Sopenharmony_ci }; 3480e5c31af7Sopenharmony_ci 3481e5c31af7Sopenharmony_ci return tcu::compareThresholdMasked(colorA, colorB, tcu::RGBA(compareThreshold.x(), compareThreshold.y(), compareThreshold.z(), 0), TCU_RGBA_RGB_MASK); 3482e5c31af7Sopenharmony_ci} 3483e5c31af7Sopenharmony_ci 3484e5c31af7Sopenharmony_ci// search 3x3 are for matching color 3485e5c31af7Sopenharmony_cistatic bool pixelNeighborhoodContainsColor (const tcu::Surface& target, int x, int y, const tcu::RGBA& color, const tcu::IVec3& compareThreshold) 3486e5c31af7Sopenharmony_ci{ 3487e5c31af7Sopenharmony_ci // should not be called for edge pixels 3488e5c31af7Sopenharmony_ci DE_ASSERT(x >= 1 && x <= target.getWidth()-2); 3489e5c31af7Sopenharmony_ci DE_ASSERT(y >= 1 && y <= target.getHeight()-2); 3490e5c31af7Sopenharmony_ci 3491e5c31af7Sopenharmony_ci for (int dy = -1; dy < 2; dy++) 3492e5c31af7Sopenharmony_ci for (int dx = -1; dx < 2; dx++) 3493e5c31af7Sopenharmony_ci { 3494e5c31af7Sopenharmony_ci const tcu::RGBA targetCmpPixel = target.getPixel(x+dx, y+dy); 3495e5c31af7Sopenharmony_ci if (colorsEqual(color, targetCmpPixel, compareThreshold)) 3496e5c31af7Sopenharmony_ci return true; 3497e5c31af7Sopenharmony_ci } 3498e5c31af7Sopenharmony_ci 3499e5c31af7Sopenharmony_ci return false; 3500e5c31af7Sopenharmony_ci} 3501e5c31af7Sopenharmony_ci 3502e5c31af7Sopenharmony_ci// search 3x3 are for matching coverage (coverage == (color != background color)) 3503e5c31af7Sopenharmony_cistatic bool pixelNeighborhoodContainsCoverage (const tcu::Surface& target, int x, int y, bool coverage) 3504e5c31af7Sopenharmony_ci{ 3505e5c31af7Sopenharmony_ci // should not be called for edge pixels 3506e5c31af7Sopenharmony_ci DE_ASSERT(x >= 1 && x <= target.getWidth()-2); 3507e5c31af7Sopenharmony_ci DE_ASSERT(y >= 1 && y <= target.getHeight()-2); 3508e5c31af7Sopenharmony_ci 3509e5c31af7Sopenharmony_ci for (int dy = -1; dy < 2; dy++) 3510e5c31af7Sopenharmony_ci for (int dx = -1; dx < 2; dx++) 3511e5c31af7Sopenharmony_ci { 3512e5c31af7Sopenharmony_ci const bool targetCmpCoverage = !isBlack(target.getPixel(x+dx, y+dy)); 3513e5c31af7Sopenharmony_ci if (targetCmpCoverage == coverage) 3514e5c31af7Sopenharmony_ci return true; 3515e5c31af7Sopenharmony_ci } 3516e5c31af7Sopenharmony_ci 3517e5c31af7Sopenharmony_ci return false; 3518e5c31af7Sopenharmony_ci} 3519e5c31af7Sopenharmony_ci 3520e5c31af7Sopenharmony_cistatic bool edgeRelaxedImageCompare (tcu::TestLog& log, const char* imageSetName, const char* imageSetDesc, const tcu::Surface& reference, const tcu::Surface& result, const tcu::IVec3& compareThreshold, const tcu::IVec3& renderTargetThreshold, int maxAllowedInvalidPixels) 3521e5c31af7Sopenharmony_ci{ 3522e5c31af7Sopenharmony_ci DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 3523e5c31af7Sopenharmony_ci 3524e5c31af7Sopenharmony_ci const tcu::IVec4 green (0, 255, 0, 255); 3525e5c31af7Sopenharmony_ci const tcu::IVec4 red (255, 0, 0, 255); 3526e5c31af7Sopenharmony_ci const int width = reference.getWidth(); 3527e5c31af7Sopenharmony_ci const int height = reference.getHeight(); 3528e5c31af7Sopenharmony_ci tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height); 3529e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess errorAccess = errorMask.getAccess(); 3530e5c31af7Sopenharmony_ci int numFailingPixels = 0; 3531e5c31af7Sopenharmony_ci 3532e5c31af7Sopenharmony_ci // clear errormask edges which would otherwise be transparent 3533e5c31af7Sopenharmony_ci 3534e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green); 3535e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, 0, height-1, width, 1), green); 3536e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green); 3537e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, width-1, 0, 1, height), green); 3538e5c31af7Sopenharmony_ci 3539e5c31af7Sopenharmony_ci // skip edge pixels since coverage on edge cannot be verified 3540e5c31af7Sopenharmony_ci 3541e5c31af7Sopenharmony_ci for (int y = 1; y < height - 1; ++y) 3542e5c31af7Sopenharmony_ci for (int x = 1; x < width - 1; ++x) 3543e5c31af7Sopenharmony_ci { 3544e5c31af7Sopenharmony_ci const tcu::RGBA refPixel = reference.getPixel(x, y); 3545e5c31af7Sopenharmony_ci const tcu::RGBA screenPixel = result.getPixel(x, y); 3546e5c31af7Sopenharmony_ci const bool directMatch = colorsEqual(refPixel, screenPixel, compareThreshold); 3547e5c31af7Sopenharmony_ci const bool isOkReferencePixel = directMatch || pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.) 3548e5c31af7Sopenharmony_ci const bool isOkScreenPixel = directMatch || pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.) 3549e5c31af7Sopenharmony_ci 3550e5c31af7Sopenharmony_ci if (isOkScreenPixel && isOkReferencePixel) 3551e5c31af7Sopenharmony_ci { 3552e5c31af7Sopenharmony_ci // pixel valid, write greenish pixels to make the result image easier to read 3553e5c31af7Sopenharmony_ci const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); 3554e5c31af7Sopenharmony_ci errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); 3555e5c31af7Sopenharmony_ci } 3556e5c31af7Sopenharmony_ci else if (!pixelNearEdge(x, y, reference, renderTargetThreshold)) 3557e5c31af7Sopenharmony_ci { 3558e5c31af7Sopenharmony_ci // non-edge pixel values must be within threshold of the reference values 3559e5c31af7Sopenharmony_ci errorAccess.setPixel(red, x, y); 3560e5c31af7Sopenharmony_ci ++numFailingPixels; 3561e5c31af7Sopenharmony_ci } 3562e5c31af7Sopenharmony_ci else 3563e5c31af7Sopenharmony_ci { 3564e5c31af7Sopenharmony_ci // we are on/near an edge, verify only coverage (coverage == not background colored) 3565e5c31af7Sopenharmony_ci const bool referenceCoverage = !isBlack(refPixel); 3566e5c31af7Sopenharmony_ci const bool screenCoverage = !isBlack(screenPixel); 3567e5c31af7Sopenharmony_ci const bool isOkReferenceCoverage = pixelNeighborhoodContainsCoverage(result, x, y, referenceCoverage); // Check reference pixel against screen pixel 3568e5c31af7Sopenharmony_ci const bool isOkScreenCoverage = pixelNeighborhoodContainsCoverage(reference, x, y, screenCoverage); // Check screen pixels against reference pixel 3569e5c31af7Sopenharmony_ci 3570e5c31af7Sopenharmony_ci if (isOkScreenCoverage && isOkReferenceCoverage) 3571e5c31af7Sopenharmony_ci { 3572e5c31af7Sopenharmony_ci // pixel valid, write greenish pixels to make the result image easier to read 3573e5c31af7Sopenharmony_ci const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); 3574e5c31af7Sopenharmony_ci errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); 3575e5c31af7Sopenharmony_ci } 3576e5c31af7Sopenharmony_ci else 3577e5c31af7Sopenharmony_ci { 3578e5c31af7Sopenharmony_ci // coverage does not match 3579e5c31af7Sopenharmony_ci errorAccess.setPixel(red, x, y); 3580e5c31af7Sopenharmony_ci ++numFailingPixels; 3581e5c31af7Sopenharmony_ci } 3582e5c31af7Sopenharmony_ci } 3583e5c31af7Sopenharmony_ci } 3584e5c31af7Sopenharmony_ci 3585e5c31af7Sopenharmony_ci log << TestLog::Message 3586e5c31af7Sopenharmony_ci << "Comparing images:\n" 3587e5c31af7Sopenharmony_ci << "\tallowed deviation in pixel positions = 1\n" 3588e5c31af7Sopenharmony_ci << "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n" 3589e5c31af7Sopenharmony_ci << "\tnumber of invalid pixels = " << numFailingPixels 3590e5c31af7Sopenharmony_ci << TestLog::EndMessage; 3591e5c31af7Sopenharmony_ci 3592e5c31af7Sopenharmony_ci if (numFailingPixels > maxAllowedInvalidPixels) 3593e5c31af7Sopenharmony_ci { 3594e5c31af7Sopenharmony_ci log << TestLog::Message 3595e5c31af7Sopenharmony_ci << "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", " << compareThreshold.y() << ", " << compareThreshold.z() << ")" 3596e5c31af7Sopenharmony_ci << TestLog::EndMessage 3597e5c31af7Sopenharmony_ci << TestLog::ImageSet(imageSetName, imageSetDesc) 3598e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", result) 3599e5c31af7Sopenharmony_ci << TestLog::Image("Reference", "Reference", reference) 3600e5c31af7Sopenharmony_ci << TestLog::Image("ErrorMask", "Error mask", errorMask) 3601e5c31af7Sopenharmony_ci << TestLog::EndImageSet; 3602e5c31af7Sopenharmony_ci 3603e5c31af7Sopenharmony_ci return false; 3604e5c31af7Sopenharmony_ci } 3605e5c31af7Sopenharmony_ci else 3606e5c31af7Sopenharmony_ci { 3607e5c31af7Sopenharmony_ci log << TestLog::ImageSet(imageSetName, imageSetDesc) 3608e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", result) 3609e5c31af7Sopenharmony_ci << TestLog::EndImageSet; 3610e5c31af7Sopenharmony_ci 3611e5c31af7Sopenharmony_ci return true; 3612e5c31af7Sopenharmony_ci } 3613e5c31af7Sopenharmony_ci} 3614e5c31af7Sopenharmony_ci 3615e5c31af7Sopenharmony_cistatic bool intersectionRelaxedLineImageCompare (tcu::TestLog& log, const char* imageSetName, const char* imageSetDesc, const tcu::Surface& reference, const tcu::Surface& result, const tcu::IVec3& compareThreshold, int maxAllowedInvalidPixels) 3616e5c31af7Sopenharmony_ci{ 3617e5c31af7Sopenharmony_ci DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 3618e5c31af7Sopenharmony_ci 3619e5c31af7Sopenharmony_ci const tcu::IVec4 green (0, 255, 0, 255); 3620e5c31af7Sopenharmony_ci const tcu::IVec4 red (255, 0, 0, 255); 3621e5c31af7Sopenharmony_ci const int width = reference.getWidth(); 3622e5c31af7Sopenharmony_ci const int height = reference.getHeight(); 3623e5c31af7Sopenharmony_ci tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height); 3624e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess errorAccess = errorMask.getAccess(); 3625e5c31af7Sopenharmony_ci int numFailingPixels = 0; 3626e5c31af7Sopenharmony_ci 3627e5c31af7Sopenharmony_ci // clear errormask edges which would otherwise be transparent 3628e5c31af7Sopenharmony_ci 3629e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green); 3630e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, 0, height-1, width, 1), green); 3631e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green); 3632e5c31af7Sopenharmony_ci tcu::clear(tcu::getSubregion(errorAccess, width-1, 0, 1, height), green); 3633e5c31af7Sopenharmony_ci 3634e5c31af7Sopenharmony_ci // skip edge pixels since coverage on edge cannot be verified 3635e5c31af7Sopenharmony_ci 3636e5c31af7Sopenharmony_ci for (int y = 1; y < height - 1; ++y) 3637e5c31af7Sopenharmony_ci for (int x = 1; x < width - 1; ++x) 3638e5c31af7Sopenharmony_ci { 3639e5c31af7Sopenharmony_ci const tcu::RGBA refPixel = reference.getPixel(x, y); 3640e5c31af7Sopenharmony_ci const tcu::RGBA screenPixel = result.getPixel(x, y); 3641e5c31af7Sopenharmony_ci const bool directMatch = colorsEqual(refPixel, screenPixel, compareThreshold); 3642e5c31af7Sopenharmony_ci const bool isOkScreenPixel = directMatch || pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.) 3643e5c31af7Sopenharmony_ci const bool isOkReferencePixel = directMatch || pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.) 3644e5c31af7Sopenharmony_ci 3645e5c31af7Sopenharmony_ci if (isOkScreenPixel && isOkReferencePixel) 3646e5c31af7Sopenharmony_ci { 3647e5c31af7Sopenharmony_ci // pixel valid, write greenish pixels to make the result image easier to read 3648e5c31af7Sopenharmony_ci const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); 3649e5c31af7Sopenharmony_ci errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); 3650e5c31af7Sopenharmony_ci } 3651e5c31af7Sopenharmony_ci else if (!pixelNearLineIntersection(x, y, reference) && 3652e5c31af7Sopenharmony_ci !pixelNearLineIntersection(x, y, result)) 3653e5c31af7Sopenharmony_ci { 3654e5c31af7Sopenharmony_ci // non-intersection pixel values must be within threshold of the reference values 3655e5c31af7Sopenharmony_ci errorAccess.setPixel(red, x, y); 3656e5c31af7Sopenharmony_ci ++numFailingPixels; 3657e5c31af7Sopenharmony_ci } 3658e5c31af7Sopenharmony_ci else 3659e5c31af7Sopenharmony_ci { 3660e5c31af7Sopenharmony_ci // pixel is near a line intersection 3661e5c31af7Sopenharmony_ci // we are on/near an edge, verify only coverage (coverage == not background colored) 3662e5c31af7Sopenharmony_ci const bool referenceCoverage = !isBlack(refPixel); 3663e5c31af7Sopenharmony_ci const bool screenCoverage = !isBlack(screenPixel); 3664e5c31af7Sopenharmony_ci const bool isOkScreenCoverage = pixelNeighborhoodContainsCoverage(reference, x, y, screenCoverage); // Check screen pixels against reference pixel 3665e5c31af7Sopenharmony_ci const bool isOkReferenceCoverage = pixelNeighborhoodContainsCoverage(result, x, y, referenceCoverage); // Check reference pixel against screen pixel 3666e5c31af7Sopenharmony_ci 3667e5c31af7Sopenharmony_ci if (isOkScreenCoverage && isOkReferenceCoverage) 3668e5c31af7Sopenharmony_ci { 3669e5c31af7Sopenharmony_ci // pixel valid, write greenish pixels to make the result image easier to read 3670e5c31af7Sopenharmony_ci const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); 3671e5c31af7Sopenharmony_ci errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); 3672e5c31af7Sopenharmony_ci } 3673e5c31af7Sopenharmony_ci else 3674e5c31af7Sopenharmony_ci { 3675e5c31af7Sopenharmony_ci // coverage does not match 3676e5c31af7Sopenharmony_ci errorAccess.setPixel(red, x, y); 3677e5c31af7Sopenharmony_ci ++numFailingPixels; 3678e5c31af7Sopenharmony_ci } 3679e5c31af7Sopenharmony_ci } 3680e5c31af7Sopenharmony_ci } 3681e5c31af7Sopenharmony_ci 3682e5c31af7Sopenharmony_ci log << TestLog::Message 3683e5c31af7Sopenharmony_ci << "Comparing images:\n" 3684e5c31af7Sopenharmony_ci << "\tallowed deviation in pixel positions = 1\n" 3685e5c31af7Sopenharmony_ci << "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n" 3686e5c31af7Sopenharmony_ci << "\tnumber of invalid pixels = " << numFailingPixels 3687e5c31af7Sopenharmony_ci << TestLog::EndMessage; 3688e5c31af7Sopenharmony_ci 3689e5c31af7Sopenharmony_ci if (numFailingPixels > maxAllowedInvalidPixels) 3690e5c31af7Sopenharmony_ci { 3691e5c31af7Sopenharmony_ci log << TestLog::Message 3692e5c31af7Sopenharmony_ci << "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", " << compareThreshold.y() << ", " << compareThreshold.z() << ")" 3693e5c31af7Sopenharmony_ci << TestLog::EndMessage 3694e5c31af7Sopenharmony_ci << TestLog::ImageSet(imageSetName, imageSetDesc) 3695e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", result) 3696e5c31af7Sopenharmony_ci << TestLog::Image("Reference", "Reference", reference) 3697e5c31af7Sopenharmony_ci << TestLog::Image("ErrorMask", "Error mask", errorMask) 3698e5c31af7Sopenharmony_ci << TestLog::EndImageSet; 3699e5c31af7Sopenharmony_ci 3700e5c31af7Sopenharmony_ci return false; 3701e5c31af7Sopenharmony_ci } 3702e5c31af7Sopenharmony_ci else 3703e5c31af7Sopenharmony_ci { 3704e5c31af7Sopenharmony_ci log << TestLog::ImageSet(imageSetName, imageSetDesc) 3705e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", result) 3706e5c31af7Sopenharmony_ci << TestLog::EndImageSet; 3707e5c31af7Sopenharmony_ci 3708e5c31af7Sopenharmony_ci return true; 3709e5c31af7Sopenharmony_ci } 3710e5c31af7Sopenharmony_ci} 3711e5c31af7Sopenharmony_ci 3712e5c31af7Sopenharmony_cibool DrawTest::compare (gls::DrawTestSpec::Primitive primitiveType) 3713e5c31af7Sopenharmony_ci{ 3714e5c31af7Sopenharmony_ci const tcu::Surface& ref = m_rrArrayPack->getSurface(); 3715e5c31af7Sopenharmony_ci const tcu::Surface& screen = m_glArrayPack->getSurface(); 3716e5c31af7Sopenharmony_ci 3717e5c31af7Sopenharmony_ci if (m_renderCtx.getRenderTarget().getNumSamples() > 1) 3718e5c31af7Sopenharmony_ci { 3719e5c31af7Sopenharmony_ci // \todo [mika] Improve compare when using multisampling 3720e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Warning: Comparision of result from multisample render targets are not as stricts as without multisampling. Might produce false positives!" << tcu::TestLog::EndMessage; 3721e5c31af7Sopenharmony_ci return tcu::fuzzyCompare(m_testCtx.getLog(), "Compare Results", "Compare Results", ref.getAccess(), screen.getAccess(), 0.3f, tcu::COMPARE_LOG_RESULT); 3722e5c31af7Sopenharmony_ci } 3723e5c31af7Sopenharmony_ci else 3724e5c31af7Sopenharmony_ci { 3725e5c31af7Sopenharmony_ci const PrimitiveClass primitiveClass = getDrawPrimitiveClass(primitiveType); 3726e5c31af7Sopenharmony_ci const int maxAllowedInvalidPixelsWithPoints = 0; //!< points are unlikely to have overlapping fragments 3727e5c31af7Sopenharmony_ci const int maxAllowedInvalidPixelsWithLines = 5; //!< line are allowed to have a few bad pixels 3728e5c31af7Sopenharmony_ci const int maxAllowedInvalidPixelsWithTriangles = 10; 3729e5c31af7Sopenharmony_ci 3730e5c31af7Sopenharmony_ci switch (primitiveClass) 3731e5c31af7Sopenharmony_ci { 3732e5c31af7Sopenharmony_ci case PRIMITIVECLASS_POINT: 3733e5c31af7Sopenharmony_ci { 3734e5c31af7Sopenharmony_ci // Point are extremely unlikely to have overlapping regions, don't allow any no extra / missing pixels 3735e5c31af7Sopenharmony_ci return tcu::intThresholdPositionDeviationErrorThresholdCompare(m_testCtx.getLog(), 3736e5c31af7Sopenharmony_ci "CompareResult", 3737e5c31af7Sopenharmony_ci "Result of rendering", 3738e5c31af7Sopenharmony_ci ref.getAccess(), 3739e5c31af7Sopenharmony_ci screen.getAccess(), 3740e5c31af7Sopenharmony_ci tcu::UVec4(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue, 256), 3741e5c31af7Sopenharmony_ci tcu::IVec3(1, 1, 0), //!< 3x3 search kernel 3742e5c31af7Sopenharmony_ci true, //!< relax comparison on the image boundary 3743e5c31af7Sopenharmony_ci maxAllowedInvalidPixelsWithPoints, //!< error threshold 3744e5c31af7Sopenharmony_ci tcu::COMPARE_LOG_RESULT); 3745e5c31af7Sopenharmony_ci } 3746e5c31af7Sopenharmony_ci 3747e5c31af7Sopenharmony_ci case PRIMITIVECLASS_LINE: 3748e5c31af7Sopenharmony_ci { 3749e5c31af7Sopenharmony_ci // Lines can potentially have a large number of overlapping pixels. Pixel comparison may potentially produce 3750e5c31af7Sopenharmony_ci // false negatives in such pixels if for example the pixel in question is overdrawn by another line in the 3751e5c31af7Sopenharmony_ci // reference image but not in the resultin image. Relax comparison near line intersection points (areas) and 3752e5c31af7Sopenharmony_ci // compare only coverage, not color, in such pixels 3753e5c31af7Sopenharmony_ci return intersectionRelaxedLineImageCompare(m_testCtx.getLog(), 3754e5c31af7Sopenharmony_ci "CompareResult", 3755e5c31af7Sopenharmony_ci "Result of rendering", 3756e5c31af7Sopenharmony_ci ref, 3757e5c31af7Sopenharmony_ci screen, 3758e5c31af7Sopenharmony_ci tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue), 3759e5c31af7Sopenharmony_ci maxAllowedInvalidPixelsWithLines); 3760e5c31af7Sopenharmony_ci } 3761e5c31af7Sopenharmony_ci 3762e5c31af7Sopenharmony_ci case PRIMITIVECLASS_TRIANGLE: 3763e5c31af7Sopenharmony_ci { 3764e5c31af7Sopenharmony_ci // Triangles are likely to partially or fully overlap. Pixel difference comparison is fragile in pixels 3765e5c31af7Sopenharmony_ci // where there could be potential overlapping since the pixels might be covered by one triangle in the 3766e5c31af7Sopenharmony_ci // reference image and by the other in the result image. Relax comparsion near primitive edges and 3767e5c31af7Sopenharmony_ci // compare only coverage, not color, in such pixels. 3768e5c31af7Sopenharmony_ci const tcu::IVec3 renderTargetThreshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold().toIVec().xyz(); 3769e5c31af7Sopenharmony_ci 3770e5c31af7Sopenharmony_ci return edgeRelaxedImageCompare(m_testCtx.getLog(), 3771e5c31af7Sopenharmony_ci "CompareResult", 3772e5c31af7Sopenharmony_ci "Result of rendering", 3773e5c31af7Sopenharmony_ci ref, 3774e5c31af7Sopenharmony_ci screen, 3775e5c31af7Sopenharmony_ci tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue), 3776e5c31af7Sopenharmony_ci renderTargetThreshold, 3777e5c31af7Sopenharmony_ci maxAllowedInvalidPixelsWithTriangles); 3778e5c31af7Sopenharmony_ci } 3779e5c31af7Sopenharmony_ci 3780e5c31af7Sopenharmony_ci default: 3781e5c31af7Sopenharmony_ci DE_ASSERT(false); 3782e5c31af7Sopenharmony_ci return false; 3783e5c31af7Sopenharmony_ci } 3784e5c31af7Sopenharmony_ci } 3785e5c31af7Sopenharmony_ci} 3786e5c31af7Sopenharmony_ci 3787e5c31af7Sopenharmony_cifloat DrawTest::getCoordScale (const DrawTestSpec& spec) const 3788e5c31af7Sopenharmony_ci{ 3789e5c31af7Sopenharmony_ci float maxValue = 1.0f; 3790e5c31af7Sopenharmony_ci 3791e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)spec.attribs.size(); arrayNdx++) 3792e5c31af7Sopenharmony_ci { 3793e5c31af7Sopenharmony_ci DrawTestSpec::AttributeSpec attribSpec = spec.attribs[arrayNdx]; 3794e5c31af7Sopenharmony_ci const bool isPositionAttr = (arrayNdx == 0) || (attribSpec.additionalPositionAttribute); 3795e5c31af7Sopenharmony_ci float attrMaxValue = 0; 3796e5c31af7Sopenharmony_ci 3797e5c31af7Sopenharmony_ci if (!isPositionAttr) 3798e5c31af7Sopenharmony_ci continue; 3799e5c31af7Sopenharmony_ci 3800e5c31af7Sopenharmony_ci if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10) 3801e5c31af7Sopenharmony_ci { 3802e5c31af7Sopenharmony_ci if (attribSpec.normalize) 3803e5c31af7Sopenharmony_ci attrMaxValue += 1.0f; 3804e5c31af7Sopenharmony_ci else 3805e5c31af7Sopenharmony_ci attrMaxValue += 1024.0f; 3806e5c31af7Sopenharmony_ci } 3807e5c31af7Sopenharmony_ci else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10) 3808e5c31af7Sopenharmony_ci { 3809e5c31af7Sopenharmony_ci if (attribSpec.normalize) 3810e5c31af7Sopenharmony_ci attrMaxValue += 1.0f; 3811e5c31af7Sopenharmony_ci else 3812e5c31af7Sopenharmony_ci attrMaxValue += 512.0f; 3813e5c31af7Sopenharmony_ci } 3814e5c31af7Sopenharmony_ci else 3815e5c31af7Sopenharmony_ci { 3816e5c31af7Sopenharmony_ci const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat(); 3817e5c31af7Sopenharmony_ci 3818e5c31af7Sopenharmony_ci attrMaxValue += (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType)) ? (1.0f) : (max * 1.1f); 3819e5c31af7Sopenharmony_ci } 3820e5c31af7Sopenharmony_ci 3821e5c31af7Sopenharmony_ci if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC3 || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4 3822e5c31af7Sopenharmony_ci || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4 3823e5c31af7Sopenharmony_ci || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4) 3824e5c31af7Sopenharmony_ci attrMaxValue *= 2; 3825e5c31af7Sopenharmony_ci 3826e5c31af7Sopenharmony_ci maxValue += attrMaxValue; 3827e5c31af7Sopenharmony_ci } 3828e5c31af7Sopenharmony_ci 3829e5c31af7Sopenharmony_ci return 1.0f / maxValue; 3830e5c31af7Sopenharmony_ci} 3831e5c31af7Sopenharmony_ci 3832e5c31af7Sopenharmony_cifloat DrawTest::getColorScale (const DrawTestSpec& spec) const 3833e5c31af7Sopenharmony_ci{ 3834e5c31af7Sopenharmony_ci float colorScale = 1.0f; 3835e5c31af7Sopenharmony_ci 3836e5c31af7Sopenharmony_ci for (int arrayNdx = 1; arrayNdx < (int)spec.attribs.size(); arrayNdx++) 3837e5c31af7Sopenharmony_ci { 3838e5c31af7Sopenharmony_ci DrawTestSpec::AttributeSpec attribSpec = spec.attribs[arrayNdx]; 3839e5c31af7Sopenharmony_ci const bool isPositionAttr = (arrayNdx == 0) || (attribSpec.additionalPositionAttribute); 3840e5c31af7Sopenharmony_ci 3841e5c31af7Sopenharmony_ci if (isPositionAttr) 3842e5c31af7Sopenharmony_ci continue; 3843e5c31af7Sopenharmony_ci 3844e5c31af7Sopenharmony_ci if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10) 3845e5c31af7Sopenharmony_ci { 3846e5c31af7Sopenharmony_ci if (!attribSpec.normalize) 3847e5c31af7Sopenharmony_ci colorScale *= 1.0f / 1024.0f; 3848e5c31af7Sopenharmony_ci } 3849e5c31af7Sopenharmony_ci else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10) 3850e5c31af7Sopenharmony_ci { 3851e5c31af7Sopenharmony_ci if (!attribSpec.normalize) 3852e5c31af7Sopenharmony_ci colorScale *= 1.0f / 512.0f; 3853e5c31af7Sopenharmony_ci } 3854e5c31af7Sopenharmony_ci else 3855e5c31af7Sopenharmony_ci { 3856e5c31af7Sopenharmony_ci const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat(); 3857e5c31af7Sopenharmony_ci 3858e5c31af7Sopenharmony_ci colorScale *= (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f : float(1.0 / double(max))); 3859e5c31af7Sopenharmony_ci if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4 || 3860e5c31af7Sopenharmony_ci attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4 || 3861e5c31af7Sopenharmony_ci attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4) 3862e5c31af7Sopenharmony_ci colorScale *= (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f : float(1.0 / double(max))); 3863e5c31af7Sopenharmony_ci } 3864e5c31af7Sopenharmony_ci } 3865e5c31af7Sopenharmony_ci 3866e5c31af7Sopenharmony_ci return colorScale; 3867e5c31af7Sopenharmony_ci} 3868e5c31af7Sopenharmony_ci 3869e5c31af7Sopenharmony_ci} // gls 3870e5c31af7Sopenharmony_ci} // deqp 3871