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 Vertex array and buffer tests 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "glsVertexArrayTests.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "deRandom.h" 27e5c31af7Sopenharmony_ci 28e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 29e5c31af7Sopenharmony_ci#include "tcuPixelFormat.hpp" 30e5c31af7Sopenharmony_ci#include "tcuRGBA.hpp" 31e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 32e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 33e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 34e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 35e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 36e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 39e5c31af7Sopenharmony_ci#include "gluCallLogWrapper.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#include "sglrContext.hpp" 42e5c31af7Sopenharmony_ci#include "sglrReferenceContext.hpp" 43e5c31af7Sopenharmony_ci#include "sglrGLContext.hpp" 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci#include "deMath.h" 46e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 47e5c31af7Sopenharmony_ci#include "deArrayUtil.hpp" 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ci#include <cstring> 50e5c31af7Sopenharmony_ci#include <cmath> 51e5c31af7Sopenharmony_ci#include <vector> 52e5c31af7Sopenharmony_ci#include <sstream> 53e5c31af7Sopenharmony_ci#include <limits> 54e5c31af7Sopenharmony_ci#include <algorithm> 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ci#include "glwDefs.hpp" 57e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_cinamespace deqp 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_cinamespace gls 62e5c31af7Sopenharmony_ci{ 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_ciusing tcu::TestLog; 65e5c31af7Sopenharmony_ciusing namespace glw; // GL types 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_cistd::string Array::targetToString(Target target) 68e5c31af7Sopenharmony_ci{ 69e5c31af7Sopenharmony_ci static const char* targets[] = 70e5c31af7Sopenharmony_ci { 71e5c31af7Sopenharmony_ci "element_array", // TARGET_ELEMENT_ARRAY = 0, 72e5c31af7Sopenharmony_ci "array" // TARGET_ARRAY, 73e5c31af7Sopenharmony_ci }; 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::TARGET_LAST>(targets, (int)target); 76e5c31af7Sopenharmony_ci} 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_cistd::string Array::inputTypeToString(InputType type) 79e5c31af7Sopenharmony_ci{ 80e5c31af7Sopenharmony_ci static const char* types[] = 81e5c31af7Sopenharmony_ci { 82e5c31af7Sopenharmony_ci "float", // INPUTTYPE_FLOAT = 0, 83e5c31af7Sopenharmony_ci "fixed", // INPUTTYPE_FIXED, 84e5c31af7Sopenharmony_ci "double", // INPUTTYPE_DOUBLE 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ci "byte", // INPUTTYPE_BYTE, 87e5c31af7Sopenharmony_ci "short", // INPUTTYPE_SHORT, 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci "unsigned_byte", // INPUTTYPE_UNSIGNED_BYTE, 90e5c31af7Sopenharmony_ci "unsigned_short", // INPUTTYPE_UNSIGNED_SHORT, 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ci "int", // INPUTTYPE_INT, 93e5c31af7Sopenharmony_ci "unsigned_int", // INPUTTYPE_UNSIGNED_INT, 94e5c31af7Sopenharmony_ci "half", // INPUTTYPE_HALF, 95e5c31af7Sopenharmony_ci "usigned_int2_10_10_10", // INPUTTYPE_UNSIGNED_INT_2_10_10_10, 96e5c31af7Sopenharmony_ci "int2_10_10_10" // INPUTTYPE_INT_2_10_10_10, 97e5c31af7Sopenharmony_ci }; 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::INPUTTYPE_LAST>(types, (int)type); 100e5c31af7Sopenharmony_ci} 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_cistd::string Array::outputTypeToString(OutputType type) 103e5c31af7Sopenharmony_ci{ 104e5c31af7Sopenharmony_ci static const char* types[] = 105e5c31af7Sopenharmony_ci { 106e5c31af7Sopenharmony_ci "float", // OUTPUTTYPE_FLOAT = 0, 107e5c31af7Sopenharmony_ci "vec2", // OUTPUTTYPE_VEC2, 108e5c31af7Sopenharmony_ci "vec3", // OUTPUTTYPE_VEC3, 109e5c31af7Sopenharmony_ci "vec4", // OUTPUTTYPE_VEC4, 110e5c31af7Sopenharmony_ci 111e5c31af7Sopenharmony_ci "int", // OUTPUTTYPE_INT, 112e5c31af7Sopenharmony_ci "uint", // OUTPUTTYPE_UINT, 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ci "ivec2", // OUTPUTTYPE_IVEC2, 115e5c31af7Sopenharmony_ci "ivec3", // OUTPUTTYPE_IVEC3, 116e5c31af7Sopenharmony_ci "ivec4", // OUTPUTTYPE_IVEC4, 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci "uvec2", // OUTPUTTYPE_UVEC2, 119e5c31af7Sopenharmony_ci "uvec3", // OUTPUTTYPE_UVEC3, 120e5c31af7Sopenharmony_ci "uvec4", // OUTPUTTYPE_UVEC4, 121e5c31af7Sopenharmony_ci }; 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::OUTPUTTYPE_LAST>(types, (int)type); 124e5c31af7Sopenharmony_ci} 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_cistd::string Array::usageTypeToString(Usage usage) 127e5c31af7Sopenharmony_ci{ 128e5c31af7Sopenharmony_ci static const char* usages[] = 129e5c31af7Sopenharmony_ci { 130e5c31af7Sopenharmony_ci "dynamic_draw", // USAGE_DYNAMIC_DRAW = 0, 131e5c31af7Sopenharmony_ci "static_draw", // USAGE_STATIC_DRAW, 132e5c31af7Sopenharmony_ci "stream_draw", // USAGE_STREAM_DRAW, 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci "stream_read", // USAGE_STREAM_READ, 135e5c31af7Sopenharmony_ci "stream_copy", // USAGE_STREAM_COPY, 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci "static_read", // USAGE_STATIC_READ, 138e5c31af7Sopenharmony_ci "static_copy", // USAGE_STATIC_COPY, 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci "dynamic_read", // USAGE_DYNAMIC_READ, 141e5c31af7Sopenharmony_ci "dynamic_copy", // USAGE_DYNAMIC_COPY, 142e5c31af7Sopenharmony_ci }; 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::USAGE_LAST>(usages, (int)usage); 145e5c31af7Sopenharmony_ci} 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_cistd::string Array::storageToString (Storage storage) 148e5c31af7Sopenharmony_ci{ 149e5c31af7Sopenharmony_ci static const char* storages[] = 150e5c31af7Sopenharmony_ci { 151e5c31af7Sopenharmony_ci "user_ptr", // STORAGE_USER = 0, 152e5c31af7Sopenharmony_ci "buffer" // STORAGE_BUFFER, 153e5c31af7Sopenharmony_ci }; 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::STORAGE_LAST>(storages, (int)storage); 156e5c31af7Sopenharmony_ci} 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_cistd::string Array::primitiveToString (Primitive primitive) 159e5c31af7Sopenharmony_ci{ 160e5c31af7Sopenharmony_ci static const char* primitives[] = 161e5c31af7Sopenharmony_ci { 162e5c31af7Sopenharmony_ci "points", // PRIMITIVE_POINTS , 163e5c31af7Sopenharmony_ci "triangles", // PRIMITIVE_TRIANGLES, 164e5c31af7Sopenharmony_ci "triangle_fan", // PRIMITIVE_TRIANGLE_FAN, 165e5c31af7Sopenharmony_ci "triangle_strip" // PRIMITIVE_TRIANGLE_STRIP, 166e5c31af7Sopenharmony_ci }; 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::PRIMITIVE_LAST>(primitives, (int)primitive); 169e5c31af7Sopenharmony_ci} 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ciint Array::inputTypeSize (InputType type) 172e5c31af7Sopenharmony_ci{ 173e5c31af7Sopenharmony_ci static const int size[] = 174e5c31af7Sopenharmony_ci { 175e5c31af7Sopenharmony_ci (int)sizeof(float), // INPUTTYPE_FLOAT = 0, 176e5c31af7Sopenharmony_ci (int)sizeof(deInt32), // INPUTTYPE_FIXED, 177e5c31af7Sopenharmony_ci (int)sizeof(double), // INPUTTYPE_DOUBLE 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci (int)sizeof(deInt8), // INPUTTYPE_BYTE, 180e5c31af7Sopenharmony_ci (int)sizeof(deInt16), // INPUTTYPE_SHORT, 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci (int)sizeof(deUint8), // INPUTTYPE_UNSIGNED_BYTE, 183e5c31af7Sopenharmony_ci (int)sizeof(deUint16), // INPUTTYPE_UNSIGNED_SHORT, 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci (int)sizeof(deInt32), // INPUTTYPE_INT, 186e5c31af7Sopenharmony_ci (int)sizeof(deUint32), // INPUTTYPE_UNSIGNED_INT, 187e5c31af7Sopenharmony_ci (int)sizeof(deFloat16), // INPUTTYPE_HALF, 188e5c31af7Sopenharmony_ci (int)sizeof(deUint32) / 4, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, 189e5c31af7Sopenharmony_ci (int)sizeof(deUint32) / 4 // INPUTTYPE_INT_2_10_10_10, 190e5c31af7Sopenharmony_ci }; 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::INPUTTYPE_LAST>(size, (int)type); 193e5c31af7Sopenharmony_ci} 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_cistatic bool inputTypeIsFloatType (Array::InputType type) 196e5c31af7Sopenharmony_ci{ 197e5c31af7Sopenharmony_ci if (type == Array::INPUTTYPE_FLOAT) 198e5c31af7Sopenharmony_ci return true; 199e5c31af7Sopenharmony_ci if (type == Array::INPUTTYPE_FIXED) 200e5c31af7Sopenharmony_ci return true; 201e5c31af7Sopenharmony_ci if (type == Array::INPUTTYPE_DOUBLE) 202e5c31af7Sopenharmony_ci return true; 203e5c31af7Sopenharmony_ci if (type == Array::INPUTTYPE_HALF) 204e5c31af7Sopenharmony_ci return true; 205e5c31af7Sopenharmony_ci return false; 206e5c31af7Sopenharmony_ci} 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_cistatic bool outputTypeIsFloatType (Array::OutputType type) 209e5c31af7Sopenharmony_ci{ 210e5c31af7Sopenharmony_ci if (type == Array::OUTPUTTYPE_FLOAT 211e5c31af7Sopenharmony_ci || type == Array::OUTPUTTYPE_VEC2 212e5c31af7Sopenharmony_ci || type == Array::OUTPUTTYPE_VEC3 213e5c31af7Sopenharmony_ci || type == Array::OUTPUTTYPE_VEC4) 214e5c31af7Sopenharmony_ci return true; 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci return false; 217e5c31af7Sopenharmony_ci} 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_citemplate<class T> 220e5c31af7Sopenharmony_ciinline T getRandom (deRandom& rnd, T min, T max); 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_citemplate<> 223e5c31af7Sopenharmony_ciinline GLValue::Float getRandom (deRandom& rnd, GLValue::Float min, GLValue::Float max) 224e5c31af7Sopenharmony_ci{ 225e5c31af7Sopenharmony_ci if (max < min) 226e5c31af7Sopenharmony_ci return min; 227e5c31af7Sopenharmony_ci 228e5c31af7Sopenharmony_ci return GLValue::Float::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>())); 229e5c31af7Sopenharmony_ci} 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_citemplate<> 232e5c31af7Sopenharmony_ciinline GLValue::Short getRandom (deRandom& rnd, GLValue::Short min, GLValue::Short max) 233e5c31af7Sopenharmony_ci{ 234e5c31af7Sopenharmony_ci if (max < min) 235e5c31af7Sopenharmony_ci return min; 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci return GLValue::Short::create((min == max ? min : (deInt16)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 238e5c31af7Sopenharmony_ci} 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_citemplate<> 241e5c31af7Sopenharmony_ciinline GLValue::Ushort getRandom (deRandom& rnd, GLValue::Ushort min, GLValue::Ushort max) 242e5c31af7Sopenharmony_ci{ 243e5c31af7Sopenharmony_ci if (max < min) 244e5c31af7Sopenharmony_ci return min; 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ci return GLValue::Ushort::create((min == max ? min : (deUint16)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 247e5c31af7Sopenharmony_ci} 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_citemplate<> 250e5c31af7Sopenharmony_ciinline GLValue::Byte getRandom (deRandom& rnd, GLValue::Byte min, GLValue::Byte max) 251e5c31af7Sopenharmony_ci{ 252e5c31af7Sopenharmony_ci if (max < min) 253e5c31af7Sopenharmony_ci return min; 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_ci return GLValue::Byte::create((min == max ? min : (deInt8)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 256e5c31af7Sopenharmony_ci} 257e5c31af7Sopenharmony_ci 258e5c31af7Sopenharmony_citemplate<> 259e5c31af7Sopenharmony_ciinline GLValue::Ubyte getRandom (deRandom& rnd, GLValue::Ubyte min, GLValue::Ubyte max) 260e5c31af7Sopenharmony_ci{ 261e5c31af7Sopenharmony_ci if (max < min) 262e5c31af7Sopenharmony_ci return min; 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_ci return GLValue::Ubyte::create((min == max ? min : (deUint8)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>()))))); 265e5c31af7Sopenharmony_ci} 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_citemplate<> 268e5c31af7Sopenharmony_ciinline GLValue::Fixed getRandom (deRandom& rnd, GLValue::Fixed min, GLValue::Fixed max) 269e5c31af7Sopenharmony_ci{ 270e5c31af7Sopenharmony_ci if (max < min) 271e5c31af7Sopenharmony_ci return min; 272e5c31af7Sopenharmony_ci 273e5c31af7Sopenharmony_ci return GLValue::Fixed::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>())))); 274e5c31af7Sopenharmony_ci} 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_citemplate<> 277e5c31af7Sopenharmony_ciinline GLValue::Half getRandom (deRandom& rnd, GLValue::Half min, GLValue::Half max) 278e5c31af7Sopenharmony_ci{ 279e5c31af7Sopenharmony_ci if (max < min) 280e5c31af7Sopenharmony_ci return min; 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci float fMax = max.to<float>(); 283e5c31af7Sopenharmony_ci float fMin = min.to<float>(); 284e5c31af7Sopenharmony_ci GLValue::Half h = GLValue::Half::create(fMin + deRandom_getFloat(&rnd) * (fMax - fMin)); 285e5c31af7Sopenharmony_ci return h; 286e5c31af7Sopenharmony_ci} 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_citemplate<> 289e5c31af7Sopenharmony_ciinline GLValue::Int getRandom (deRandom& rnd, GLValue::Int min, GLValue::Int max) 290e5c31af7Sopenharmony_ci{ 291e5c31af7Sopenharmony_ci if (max < min) 292e5c31af7Sopenharmony_ci return min; 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_ci return GLValue::Int::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>())))); 295e5c31af7Sopenharmony_ci} 296e5c31af7Sopenharmony_ci 297e5c31af7Sopenharmony_citemplate<> 298e5c31af7Sopenharmony_ciinline GLValue::Uint getRandom (deRandom& rnd, GLValue::Uint min, GLValue::Uint max) 299e5c31af7Sopenharmony_ci{ 300e5c31af7Sopenharmony_ci if (max < min) 301e5c31af7Sopenharmony_ci return min; 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci return GLValue::Uint::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>())))); 304e5c31af7Sopenharmony_ci} 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_citemplate<> 307e5c31af7Sopenharmony_ciinline GLValue::Double getRandom (deRandom& rnd, GLValue::Double min, GLValue::Double max) 308e5c31af7Sopenharmony_ci{ 309e5c31af7Sopenharmony_ci if (max < min) 310e5c31af7Sopenharmony_ci return min; 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci return GLValue::Double::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>())); 313e5c31af7Sopenharmony_ci} 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci// Minimum difference required between coordinates 316e5c31af7Sopenharmony_citemplate<class T> 317e5c31af7Sopenharmony_ciinline T minValue (void); 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_citemplate<> 320e5c31af7Sopenharmony_ciinline GLValue::Float minValue (void) 321e5c31af7Sopenharmony_ci{ 322e5c31af7Sopenharmony_ci return GLValue::Float::create(4 * 1.0f); 323e5c31af7Sopenharmony_ci} 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_citemplate<> 326e5c31af7Sopenharmony_ciinline GLValue::Short minValue (void) 327e5c31af7Sopenharmony_ci{ 328e5c31af7Sopenharmony_ci return GLValue::Short::create(4 * 256); 329e5c31af7Sopenharmony_ci} 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_citemplate<> 332e5c31af7Sopenharmony_ciinline GLValue::Ushort minValue (void) 333e5c31af7Sopenharmony_ci{ 334e5c31af7Sopenharmony_ci return GLValue::Ushort::create(4 * 256); 335e5c31af7Sopenharmony_ci} 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_citemplate<> 338e5c31af7Sopenharmony_ciinline GLValue::Byte minValue (void) 339e5c31af7Sopenharmony_ci{ 340e5c31af7Sopenharmony_ci return GLValue::Byte::create(4 * 1); 341e5c31af7Sopenharmony_ci} 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_citemplate<> 344e5c31af7Sopenharmony_ciinline GLValue::Ubyte minValue (void) 345e5c31af7Sopenharmony_ci{ 346e5c31af7Sopenharmony_ci return GLValue::Ubyte::create(4 * 2); 347e5c31af7Sopenharmony_ci} 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_citemplate<> 350e5c31af7Sopenharmony_ciinline GLValue::Fixed minValue (void) 351e5c31af7Sopenharmony_ci{ 352e5c31af7Sopenharmony_ci return GLValue::Fixed::create(4 * 512); 353e5c31af7Sopenharmony_ci} 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_citemplate<> 356e5c31af7Sopenharmony_ciinline GLValue::Int minValue (void) 357e5c31af7Sopenharmony_ci{ 358e5c31af7Sopenharmony_ci return GLValue::Int::create(4 * 16777216); 359e5c31af7Sopenharmony_ci} 360e5c31af7Sopenharmony_ci 361e5c31af7Sopenharmony_citemplate<> 362e5c31af7Sopenharmony_ciinline GLValue::Uint minValue (void) 363e5c31af7Sopenharmony_ci{ 364e5c31af7Sopenharmony_ci return GLValue::Uint::create(4 * 16777216); 365e5c31af7Sopenharmony_ci} 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_citemplate<> 368e5c31af7Sopenharmony_ciinline GLValue::Half minValue (void) 369e5c31af7Sopenharmony_ci{ 370e5c31af7Sopenharmony_ci return GLValue::Half::create(4 * 1.0f); 371e5c31af7Sopenharmony_ci} 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_citemplate<> 374e5c31af7Sopenharmony_ciinline GLValue::Double minValue (void) 375e5c31af7Sopenharmony_ci{ 376e5c31af7Sopenharmony_ci return GLValue::Double::create(4 * 1.0f); 377e5c31af7Sopenharmony_ci} 378e5c31af7Sopenharmony_ci 379e5c31af7Sopenharmony_citemplate<class T> 380e5c31af7Sopenharmony_cistatic inline void alignmentSafeAssignment (char* dst, T val) 381e5c31af7Sopenharmony_ci{ 382e5c31af7Sopenharmony_ci std::memcpy(dst, &val, sizeof(T)); 383e5c31af7Sopenharmony_ci} 384e5c31af7Sopenharmony_ci 385e5c31af7Sopenharmony_ciContextArray::ContextArray (Storage storage, sglr::Context& context) 386e5c31af7Sopenharmony_ci : m_storage (storage) 387e5c31af7Sopenharmony_ci , m_ctx (context) 388e5c31af7Sopenharmony_ci , m_glBuffer (0) 389e5c31af7Sopenharmony_ci , m_bound (false) 390e5c31af7Sopenharmony_ci , m_attribNdx (0) 391e5c31af7Sopenharmony_ci , m_size (0) 392e5c31af7Sopenharmony_ci , m_data (DE_NULL) 393e5c31af7Sopenharmony_ci , m_componentCount (1) 394e5c31af7Sopenharmony_ci , m_target (Array::TARGET_ARRAY) 395e5c31af7Sopenharmony_ci , m_inputType (Array::INPUTTYPE_FLOAT) 396e5c31af7Sopenharmony_ci , m_outputType (Array::OUTPUTTYPE_VEC4) 397e5c31af7Sopenharmony_ci , m_normalize (false) 398e5c31af7Sopenharmony_ci , m_stride (0) 399e5c31af7Sopenharmony_ci , m_offset (0) 400e5c31af7Sopenharmony_ci{ 401e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 402e5c31af7Sopenharmony_ci { 403e5c31af7Sopenharmony_ci m_ctx.genBuffers(1, &m_glBuffer); 404e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glGenBuffers()"); 405e5c31af7Sopenharmony_ci } 406e5c31af7Sopenharmony_ci} 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ciContextArray::~ContextArray (void) 409e5c31af7Sopenharmony_ci{ 410e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 411e5c31af7Sopenharmony_ci { 412e5c31af7Sopenharmony_ci m_ctx.deleteBuffers(1, &m_glBuffer); 413e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDeleteBuffers()"); 414e5c31af7Sopenharmony_ci } 415e5c31af7Sopenharmony_ci else if (m_storage == STORAGE_USER) 416e5c31af7Sopenharmony_ci delete[] m_data; 417e5c31af7Sopenharmony_ci else 418e5c31af7Sopenharmony_ci DE_ASSERT(false); 419e5c31af7Sopenharmony_ci} 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ciArray* ContextArrayPack::getArray (int i) 422e5c31af7Sopenharmony_ci{ 423e5c31af7Sopenharmony_ci return m_arrays.at(i); 424e5c31af7Sopenharmony_ci} 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_civoid ContextArray::data (Target target, int size, const char* ptr, Usage usage) 427e5c31af7Sopenharmony_ci{ 428e5c31af7Sopenharmony_ci m_size = size; 429e5c31af7Sopenharmony_ci m_target = target; 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 432e5c31af7Sopenharmony_ci { 433e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(target), m_glBuffer); 434e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()"); 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_ci m_ctx.bufferData(targetToGL(target), size, ptr, usageToGL(usage)); 437e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBufferData()"); 438e5c31af7Sopenharmony_ci } 439e5c31af7Sopenharmony_ci else if (m_storage == STORAGE_USER) 440e5c31af7Sopenharmony_ci { 441e5c31af7Sopenharmony_ci if (m_data) 442e5c31af7Sopenharmony_ci delete[] m_data; 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci m_data = new char[size]; 445e5c31af7Sopenharmony_ci std::memcpy(m_data, ptr, size); 446e5c31af7Sopenharmony_ci } 447e5c31af7Sopenharmony_ci else 448e5c31af7Sopenharmony_ci DE_ASSERT(false); 449e5c31af7Sopenharmony_ci} 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_civoid ContextArray::subdata (Target target, int offset, int size, const char* ptr) 452e5c31af7Sopenharmony_ci{ 453e5c31af7Sopenharmony_ci m_target = target; 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 456e5c31af7Sopenharmony_ci { 457e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(target), m_glBuffer); 458e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()"); 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_ci m_ctx.bufferSubData(targetToGL(target), offset, size, ptr); 461e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBufferSubData()"); 462e5c31af7Sopenharmony_ci } 463e5c31af7Sopenharmony_ci else if (m_storage == STORAGE_USER) 464e5c31af7Sopenharmony_ci std::memcpy(m_data + offset, ptr, size); 465e5c31af7Sopenharmony_ci else 466e5c31af7Sopenharmony_ci DE_ASSERT(false); 467e5c31af7Sopenharmony_ci} 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_civoid ContextArray::bind (int attribNdx, int offset, int size, InputType inputType, OutputType outType, bool normalized, int stride) 470e5c31af7Sopenharmony_ci{ 471e5c31af7Sopenharmony_ci m_attribNdx = attribNdx; 472e5c31af7Sopenharmony_ci m_bound = true; 473e5c31af7Sopenharmony_ci m_componentCount = size; 474e5c31af7Sopenharmony_ci m_inputType = inputType; 475e5c31af7Sopenharmony_ci m_outputType = outType; 476e5c31af7Sopenharmony_ci m_normalize = normalized; 477e5c31af7Sopenharmony_ci m_stride = stride; 478e5c31af7Sopenharmony_ci m_offset = offset; 479e5c31af7Sopenharmony_ci} 480e5c31af7Sopenharmony_ci 481e5c31af7Sopenharmony_civoid ContextArray::bindIndexArray (Array::Target target) 482e5c31af7Sopenharmony_ci{ 483e5c31af7Sopenharmony_ci if (m_storage == STORAGE_USER) 484e5c31af7Sopenharmony_ci { 485e5c31af7Sopenharmony_ci } 486e5c31af7Sopenharmony_ci else if (m_storage == STORAGE_BUFFER) 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(target), m_glBuffer); 489e5c31af7Sopenharmony_ci } 490e5c31af7Sopenharmony_ci} 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_civoid ContextArray::glBind (deUint32 loc) 493e5c31af7Sopenharmony_ci{ 494e5c31af7Sopenharmony_ci if (m_storage == STORAGE_BUFFER) 495e5c31af7Sopenharmony_ci { 496e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(m_target), m_glBuffer); 497e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()"); 498e5c31af7Sopenharmony_ci 499e5c31af7Sopenharmony_ci if (!inputTypeIsFloatType(m_inputType)) 500e5c31af7Sopenharmony_ci { 501e5c31af7Sopenharmony_ci // Input is not float type 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci if (outputTypeIsFloatType(m_outputType)) 504e5c31af7Sopenharmony_ci { 505e5c31af7Sopenharmony_ci // Output type is float type 506e5c31af7Sopenharmony_ci m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, (GLvoid*)((GLintptr)m_offset)); 507e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()"); 508e5c31af7Sopenharmony_ci } 509e5c31af7Sopenharmony_ci else 510e5c31af7Sopenharmony_ci { 511e5c31af7Sopenharmony_ci // Output type is int type 512e5c31af7Sopenharmony_ci m_ctx.vertexAttribIPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_stride, (GLvoid*)((GLintptr)m_offset)); 513e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()"); 514e5c31af7Sopenharmony_ci } 515e5c31af7Sopenharmony_ci } 516e5c31af7Sopenharmony_ci else 517e5c31af7Sopenharmony_ci { 518e5c31af7Sopenharmony_ci // Input type is float type 519e5c31af7Sopenharmony_ci 520e5c31af7Sopenharmony_ci // Output type must be float type 521e5c31af7Sopenharmony_ci DE_ASSERT(m_outputType == OUTPUTTYPE_FLOAT || m_outputType == OUTPUTTYPE_VEC2 || m_outputType == OUTPUTTYPE_VEC3 || m_outputType == OUTPUTTYPE_VEC4); 522e5c31af7Sopenharmony_ci 523e5c31af7Sopenharmony_ci m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, (GLvoid*)((GLintptr)m_offset)); 524e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()"); 525e5c31af7Sopenharmony_ci } 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(m_target), 0); 528e5c31af7Sopenharmony_ci } 529e5c31af7Sopenharmony_ci else if (m_storage == STORAGE_USER) 530e5c31af7Sopenharmony_ci { 531e5c31af7Sopenharmony_ci m_ctx.bindBuffer(targetToGL(m_target), 0); 532e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()"); 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci if (!inputTypeIsFloatType(m_inputType)) 535e5c31af7Sopenharmony_ci { 536e5c31af7Sopenharmony_ci // Input is not float type 537e5c31af7Sopenharmony_ci 538e5c31af7Sopenharmony_ci if (outputTypeIsFloatType(m_outputType)) 539e5c31af7Sopenharmony_ci { 540e5c31af7Sopenharmony_ci // Output type is float type 541e5c31af7Sopenharmony_ci m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, m_data + m_offset); 542e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()"); 543e5c31af7Sopenharmony_ci } 544e5c31af7Sopenharmony_ci else 545e5c31af7Sopenharmony_ci { 546e5c31af7Sopenharmony_ci // Output type is int type 547e5c31af7Sopenharmony_ci m_ctx.vertexAttribIPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_stride, m_data + m_offset); 548e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()"); 549e5c31af7Sopenharmony_ci } 550e5c31af7Sopenharmony_ci } 551e5c31af7Sopenharmony_ci else 552e5c31af7Sopenharmony_ci { 553e5c31af7Sopenharmony_ci // Input type is float type 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci // Output type must be float type 556e5c31af7Sopenharmony_ci DE_ASSERT(m_outputType == OUTPUTTYPE_FLOAT || m_outputType == OUTPUTTYPE_VEC2 || m_outputType == OUTPUTTYPE_VEC3 || m_outputType == OUTPUTTYPE_VEC4); 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, m_data + m_offset); 559e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()"); 560e5c31af7Sopenharmony_ci } 561e5c31af7Sopenharmony_ci } 562e5c31af7Sopenharmony_ci else 563e5c31af7Sopenharmony_ci DE_ASSERT(false); 564e5c31af7Sopenharmony_ci} 565e5c31af7Sopenharmony_ci 566e5c31af7Sopenharmony_ciGLenum ContextArray::targetToGL (Array::Target target) 567e5c31af7Sopenharmony_ci{ 568e5c31af7Sopenharmony_ci static const GLenum targets[] = 569e5c31af7Sopenharmony_ci { 570e5c31af7Sopenharmony_ci GL_ELEMENT_ARRAY_BUFFER, // TARGET_ELEMENT_ARRAY = 0, 571e5c31af7Sopenharmony_ci GL_ARRAY_BUFFER // TARGET_ARRAY, 572e5c31af7Sopenharmony_ci }; 573e5c31af7Sopenharmony_ci 574e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::TARGET_LAST>(targets, (int)target); 575e5c31af7Sopenharmony_ci} 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ciGLenum ContextArray::usageToGL (Array::Usage usage) 578e5c31af7Sopenharmony_ci{ 579e5c31af7Sopenharmony_ci static const GLenum usages[] = 580e5c31af7Sopenharmony_ci { 581e5c31af7Sopenharmony_ci GL_DYNAMIC_DRAW, // USAGE_DYNAMIC_DRAW = 0, 582e5c31af7Sopenharmony_ci GL_STATIC_DRAW, // USAGE_STATIC_DRAW, 583e5c31af7Sopenharmony_ci GL_STREAM_DRAW, // USAGE_STREAM_DRAW, 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci GL_STREAM_READ, // USAGE_STREAM_READ, 586e5c31af7Sopenharmony_ci GL_STREAM_COPY, // USAGE_STREAM_COPY, 587e5c31af7Sopenharmony_ci 588e5c31af7Sopenharmony_ci GL_STATIC_READ, // USAGE_STATIC_READ, 589e5c31af7Sopenharmony_ci GL_STATIC_COPY, // USAGE_STATIC_COPY, 590e5c31af7Sopenharmony_ci 591e5c31af7Sopenharmony_ci GL_DYNAMIC_READ, // USAGE_DYNAMIC_READ, 592e5c31af7Sopenharmony_ci GL_DYNAMIC_COPY // USAGE_DYNAMIC_COPY, 593e5c31af7Sopenharmony_ci }; 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::USAGE_LAST>(usages, (int)usage); 596e5c31af7Sopenharmony_ci} 597e5c31af7Sopenharmony_ci 598e5c31af7Sopenharmony_ciGLenum ContextArray::inputTypeToGL (Array::InputType type) 599e5c31af7Sopenharmony_ci{ 600e5c31af7Sopenharmony_ci static const GLenum types[] = 601e5c31af7Sopenharmony_ci { 602e5c31af7Sopenharmony_ci GL_FLOAT, // INPUTTYPE_FLOAT = 0, 603e5c31af7Sopenharmony_ci GL_FIXED, // INPUTTYPE_FIXED, 604e5c31af7Sopenharmony_ci GL_DOUBLE, // INPUTTYPE_DOUBLE 605e5c31af7Sopenharmony_ci GL_BYTE, // INPUTTYPE_BYTE, 606e5c31af7Sopenharmony_ci GL_SHORT, // INPUTTYPE_SHORT, 607e5c31af7Sopenharmony_ci GL_UNSIGNED_BYTE, // INPUTTYPE_UNSIGNED_BYTE, 608e5c31af7Sopenharmony_ci GL_UNSIGNED_SHORT, // INPUTTYPE_UNSIGNED_SHORT, 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ci GL_INT, // INPUTTYPE_INT, 611e5c31af7Sopenharmony_ci GL_UNSIGNED_INT, // INPUTTYPE_UNSIGNED_INT, 612e5c31af7Sopenharmony_ci GL_HALF_FLOAT, // INPUTTYPE_HALF, 613e5c31af7Sopenharmony_ci GL_UNSIGNED_INT_2_10_10_10_REV, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, 614e5c31af7Sopenharmony_ci GL_INT_2_10_10_10_REV // INPUTTYPE_INT_2_10_10_10, 615e5c31af7Sopenharmony_ci }; 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::INPUTTYPE_LAST>(types, (int)type); 618e5c31af7Sopenharmony_ci} 619e5c31af7Sopenharmony_ci 620e5c31af7Sopenharmony_cistd::string ContextArray::outputTypeToGLType (Array::OutputType type) 621e5c31af7Sopenharmony_ci{ 622e5c31af7Sopenharmony_ci static const char* types[] = 623e5c31af7Sopenharmony_ci { 624e5c31af7Sopenharmony_ci "float", // OUTPUTTYPE_FLOAT = 0, 625e5c31af7Sopenharmony_ci "vec2", // OUTPUTTYPE_VEC2, 626e5c31af7Sopenharmony_ci "vec3", // OUTPUTTYPE_VEC3, 627e5c31af7Sopenharmony_ci "vec4", // OUTPUTTYPE_VEC4, 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci "int", // OUTPUTTYPE_INT, 630e5c31af7Sopenharmony_ci "uint", // OUTPUTTYPE_UINT, 631e5c31af7Sopenharmony_ci 632e5c31af7Sopenharmony_ci "ivec2", // OUTPUTTYPE_IVEC2, 633e5c31af7Sopenharmony_ci "ivec3", // OUTPUTTYPE_IVEC3, 634e5c31af7Sopenharmony_ci "ivec4", // OUTPUTTYPE_IVEC4, 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci "uvec2", // OUTPUTTYPE_UVEC2, 637e5c31af7Sopenharmony_ci "uvec3", // OUTPUTTYPE_UVEC3, 638e5c31af7Sopenharmony_ci "uvec4", // OUTPUTTYPE_UVEC4, 639e5c31af7Sopenharmony_ci }; 640e5c31af7Sopenharmony_ci 641e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::OUTPUTTYPE_LAST>(types, (int)type); 642e5c31af7Sopenharmony_ci} 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ciGLenum ContextArray::primitiveToGL (Array::Primitive primitive) 645e5c31af7Sopenharmony_ci{ 646e5c31af7Sopenharmony_ci static const GLenum primitives[] = 647e5c31af7Sopenharmony_ci { 648e5c31af7Sopenharmony_ci GL_POINTS, // PRIMITIVE_POINTS = 0, 649e5c31af7Sopenharmony_ci GL_TRIANGLES, // PRIMITIVE_TRIANGLES, 650e5c31af7Sopenharmony_ci GL_TRIANGLE_FAN, // PRIMITIVE_TRIANGLE_FAN, 651e5c31af7Sopenharmony_ci GL_TRIANGLE_STRIP // PRIMITIVE_TRIANGLE_STRIP, 652e5c31af7Sopenharmony_ci }; 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci return de::getSizedArrayElement<Array::PRIMITIVE_LAST>(primitives, (int)primitive); 655e5c31af7Sopenharmony_ci} 656e5c31af7Sopenharmony_ci 657e5c31af7Sopenharmony_ciContextArrayPack::ContextArrayPack (glu::RenderContext& renderCtx, sglr::Context& drawContext) 658e5c31af7Sopenharmony_ci : m_renderCtx (renderCtx) 659e5c31af7Sopenharmony_ci , m_ctx (drawContext) 660e5c31af7Sopenharmony_ci , m_program (DE_NULL) 661e5c31af7Sopenharmony_ci , m_screen (std::min(512, renderCtx.getRenderTarget().getWidth()), std::min(512, renderCtx.getRenderTarget().getHeight())) 662e5c31af7Sopenharmony_ci{ 663e5c31af7Sopenharmony_ci} 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ciContextArrayPack::~ContextArrayPack (void) 666e5c31af7Sopenharmony_ci{ 667e5c31af7Sopenharmony_ci for (std::vector<ContextArray*>::iterator itr = m_arrays.begin(); itr != m_arrays.end(); itr++) 668e5c31af7Sopenharmony_ci delete *itr; 669e5c31af7Sopenharmony_ci 670e5c31af7Sopenharmony_ci delete m_program; 671e5c31af7Sopenharmony_ci} 672e5c31af7Sopenharmony_ci 673e5c31af7Sopenharmony_ciint ContextArrayPack::getArrayCount (void) 674e5c31af7Sopenharmony_ci{ 675e5c31af7Sopenharmony_ci return (int)m_arrays.size(); 676e5c31af7Sopenharmony_ci} 677e5c31af7Sopenharmony_ci 678e5c31af7Sopenharmony_civoid ContextArrayPack::newArray (Array::Storage storage) 679e5c31af7Sopenharmony_ci{ 680e5c31af7Sopenharmony_ci m_arrays.push_back(new ContextArray(storage, m_ctx)); 681e5c31af7Sopenharmony_ci} 682e5c31af7Sopenharmony_ci 683e5c31af7Sopenharmony_ciclass ContextShaderProgram : public sglr::ShaderProgram 684e5c31af7Sopenharmony_ci{ 685e5c31af7Sopenharmony_cipublic: 686e5c31af7Sopenharmony_ci ContextShaderProgram (const glu::RenderContext& ctx, const std::vector<ContextArray*>& arrays); 687e5c31af7Sopenharmony_ci 688e5c31af7Sopenharmony_ci void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const; 689e5c31af7Sopenharmony_ci void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const; 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ciprivate: 692e5c31af7Sopenharmony_ci static std::string genVertexSource (const glu::RenderContext& ctx, const std::vector<ContextArray*>& arrays); 693e5c31af7Sopenharmony_ci static std::string genFragmentSource (const glu::RenderContext& ctx); 694e5c31af7Sopenharmony_ci static rr::GenericVecType mapOutputType (const Array::OutputType& type); 695e5c31af7Sopenharmony_ci static int getComponentCount (const Array::OutputType& type); 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ci static sglr::pdec::ShaderProgramDeclaration createProgramDeclaration (const glu::RenderContext& ctx, const std::vector<ContextArray*>& arrays); 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci std::vector<int> m_componentCount; 700e5c31af7Sopenharmony_ci std::vector<rr::GenericVecType> m_attrType; 701e5c31af7Sopenharmony_ci}; 702e5c31af7Sopenharmony_ci 703e5c31af7Sopenharmony_ciContextShaderProgram::ContextShaderProgram (const glu::RenderContext& ctx, const std::vector<ContextArray*>& arrays) 704e5c31af7Sopenharmony_ci : sglr::ShaderProgram (createProgramDeclaration(ctx, arrays)) 705e5c31af7Sopenharmony_ci , m_componentCount (arrays.size()) 706e5c31af7Sopenharmony_ci , m_attrType (arrays.size()) 707e5c31af7Sopenharmony_ci{ 708e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 709e5c31af7Sopenharmony_ci { 710e5c31af7Sopenharmony_ci m_componentCount[arrayNdx] = getComponentCount(arrays[arrayNdx]->getOutputType()); 711e5c31af7Sopenharmony_ci m_attrType[arrayNdx] = mapOutputType(arrays[arrayNdx]->getOutputType()); 712e5c31af7Sopenharmony_ci } 713e5c31af7Sopenharmony_ci} 714e5c31af7Sopenharmony_ci 715e5c31af7Sopenharmony_citemplate <typename T> 716e5c31af7Sopenharmony_civoid calcShaderColorCoord (tcu::Vec2& coord, tcu::Vec3& color, const tcu::Vector<T, 4>& attribValue, bool isCoordinate, int numComponents) 717e5c31af7Sopenharmony_ci{ 718e5c31af7Sopenharmony_ci if (isCoordinate) 719e5c31af7Sopenharmony_ci switch (numComponents) 720e5c31af7Sopenharmony_ci { 721e5c31af7Sopenharmony_ci case 1: coord = tcu::Vec2((float)attribValue.x(), (float)attribValue.x()); break; 722e5c31af7Sopenharmony_ci case 2: coord = tcu::Vec2((float)attribValue.x(), (float)attribValue.y()); break; 723e5c31af7Sopenharmony_ci case 3: coord = tcu::Vec2((float)attribValue.x() + (float)attribValue.z(), (float)attribValue.y()); break; 724e5c31af7Sopenharmony_ci case 4: coord = tcu::Vec2((float)attribValue.x() + (float)attribValue.z(), (float)attribValue.y() + (float)attribValue.w()); break; 725e5c31af7Sopenharmony_ci 726e5c31af7Sopenharmony_ci default: 727e5c31af7Sopenharmony_ci DE_ASSERT(false); 728e5c31af7Sopenharmony_ci } 729e5c31af7Sopenharmony_ci else 730e5c31af7Sopenharmony_ci { 731e5c31af7Sopenharmony_ci switch (numComponents) 732e5c31af7Sopenharmony_ci { 733e5c31af7Sopenharmony_ci case 1: 734e5c31af7Sopenharmony_ci color = color * (float)attribValue.x(); 735e5c31af7Sopenharmony_ci break; 736e5c31af7Sopenharmony_ci 737e5c31af7Sopenharmony_ci case 2: 738e5c31af7Sopenharmony_ci color.x() = color.x() * (float)attribValue.x(); 739e5c31af7Sopenharmony_ci color.y() = color.y() * (float)attribValue.y(); 740e5c31af7Sopenharmony_ci break; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci case 3: 743e5c31af7Sopenharmony_ci color.x() = color.x() * (float)attribValue.x(); 744e5c31af7Sopenharmony_ci color.y() = color.y() * (float)attribValue.y(); 745e5c31af7Sopenharmony_ci color.z() = color.z() * (float)attribValue.z(); 746e5c31af7Sopenharmony_ci break; 747e5c31af7Sopenharmony_ci 748e5c31af7Sopenharmony_ci case 4: 749e5c31af7Sopenharmony_ci color.x() = color.x() * (float)attribValue.x() * (float)attribValue.w(); 750e5c31af7Sopenharmony_ci color.y() = color.y() * (float)attribValue.y() * (float)attribValue.w(); 751e5c31af7Sopenharmony_ci color.z() = color.z() * (float)attribValue.z() * (float)attribValue.w(); 752e5c31af7Sopenharmony_ci break; 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ci default: 755e5c31af7Sopenharmony_ci DE_ASSERT(false); 756e5c31af7Sopenharmony_ci } 757e5c31af7Sopenharmony_ci } 758e5c31af7Sopenharmony_ci} 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_civoid ContextShaderProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 761e5c31af7Sopenharmony_ci{ 762e5c31af7Sopenharmony_ci const float u_coordScale = getUniformByName("u_coordScale").value.f; 763e5c31af7Sopenharmony_ci const float u_colorScale = getUniformByName("u_colorScale").value.f; 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 766e5c31af7Sopenharmony_ci { 767e5c31af7Sopenharmony_ci const size_t varyingLocColor = 0; 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci rr::VertexPacket& packet = *packets[packetNdx]; 770e5c31af7Sopenharmony_ci 771e5c31af7Sopenharmony_ci // Calc output color 772e5c31af7Sopenharmony_ci tcu::Vec2 coord = tcu::Vec2(1.0, 1.0); 773e5c31af7Sopenharmony_ci tcu::Vec3 color = tcu::Vec3(1.0, 1.0, 1.0); 774e5c31af7Sopenharmony_ci 775e5c31af7Sopenharmony_ci for (int attribNdx = 0; attribNdx < (int)m_attrType.size(); attribNdx++) 776e5c31af7Sopenharmony_ci { 777e5c31af7Sopenharmony_ci const int numComponents = m_componentCount[attribNdx]; 778e5c31af7Sopenharmony_ci 779e5c31af7Sopenharmony_ci switch (m_attrType[attribNdx]) 780e5c31af7Sopenharmony_ci { 781e5c31af7Sopenharmony_ci case rr::GENERICVECTYPE_FLOAT: calcShaderColorCoord(coord, color, rr::readVertexAttribFloat(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), attribNdx == 0, numComponents); break; 782e5c31af7Sopenharmony_ci case rr::GENERICVECTYPE_INT32: calcShaderColorCoord(coord, color, rr::readVertexAttribInt (inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), attribNdx == 0, numComponents); break; 783e5c31af7Sopenharmony_ci case rr::GENERICVECTYPE_UINT32: calcShaderColorCoord(coord, color, rr::readVertexAttribUint (inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), attribNdx == 0, numComponents); break; 784e5c31af7Sopenharmony_ci default: 785e5c31af7Sopenharmony_ci DE_ASSERT(false); 786e5c31af7Sopenharmony_ci } 787e5c31af7Sopenharmony_ci } 788e5c31af7Sopenharmony_ci 789e5c31af7Sopenharmony_ci // Transform position 790e5c31af7Sopenharmony_ci { 791e5c31af7Sopenharmony_ci packet.position = tcu::Vec4(u_coordScale * coord.x(), u_coordScale * coord.y(), 1.0f, 1.0f); 792e5c31af7Sopenharmony_ci } 793e5c31af7Sopenharmony_ci 794e5c31af7Sopenharmony_ci // Pass color to FS 795e5c31af7Sopenharmony_ci { 796e5c31af7Sopenharmony_ci packet.outputs[varyingLocColor] = tcu::Vec4(u_colorScale * color.x(), u_colorScale * color.y(), u_colorScale * color.z(), 1.0f); 797e5c31af7Sopenharmony_ci } 798e5c31af7Sopenharmony_ci } 799e5c31af7Sopenharmony_ci} 800e5c31af7Sopenharmony_ci 801e5c31af7Sopenharmony_civoid ContextShaderProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 802e5c31af7Sopenharmony_ci{ 803e5c31af7Sopenharmony_ci const size_t varyingLocColor = 0; 804e5c31af7Sopenharmony_ci 805e5c31af7Sopenharmony_ci // Triangles are flashaded 806e5c31af7Sopenharmony_ci tcu::Vec4 color = rr::readTriangleVarying<float>(packets[0], context, varyingLocColor, 0); 807e5c31af7Sopenharmony_ci 808e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx) 809e5c31af7Sopenharmony_ci for (int fragNdx = 0; fragNdx < 4; ++fragNdx) 810e5c31af7Sopenharmony_ci rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); 811e5c31af7Sopenharmony_ci} 812e5c31af7Sopenharmony_ci 813e5c31af7Sopenharmony_cistd::string ContextShaderProgram::genVertexSource (const glu::RenderContext& ctx, const std::vector<ContextArray*>& arrays) 814e5c31af7Sopenharmony_ci{ 815e5c31af7Sopenharmony_ci std::stringstream vertexShaderTmpl; 816e5c31af7Sopenharmony_ci std::map<std::string, std::string> params; 817e5c31af7Sopenharmony_ci 818e5c31af7Sopenharmony_ci if (glu::isGLSLVersionSupported(ctx.getType(), glu::GLSL_VERSION_300_ES)) 819e5c31af7Sopenharmony_ci { 820e5c31af7Sopenharmony_ci params["VTX_IN"] = "in"; 821e5c31af7Sopenharmony_ci params["VTX_OUT"] = "out"; 822e5c31af7Sopenharmony_ci params["FRAG_IN"] = "in"; 823e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "dEQP_FragColor"; 824e5c31af7Sopenharmony_ci params["VTX_HDR"] = "#version 300 es\n"; 825e5c31af7Sopenharmony_ci params["FRAG_HDR"] = "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 826e5c31af7Sopenharmony_ci } 827e5c31af7Sopenharmony_ci else if (glu::isGLSLVersionSupported(ctx.getType(), glu::GLSL_VERSION_100_ES)) 828e5c31af7Sopenharmony_ci { 829e5c31af7Sopenharmony_ci params["VTX_IN"] = "attribute"; 830e5c31af7Sopenharmony_ci params["VTX_OUT"] = "varying"; 831e5c31af7Sopenharmony_ci params["FRAG_IN"] = "varying"; 832e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "gl_FragColor"; 833e5c31af7Sopenharmony_ci params["VTX_HDR"] = ""; 834e5c31af7Sopenharmony_ci params["FRAG_HDR"] = ""; 835e5c31af7Sopenharmony_ci } 836e5c31af7Sopenharmony_ci else if (glu::isGLSLVersionSupported(ctx.getType(), glu::GLSL_VERSION_330)) 837e5c31af7Sopenharmony_ci { 838e5c31af7Sopenharmony_ci params["VTX_IN"] = "in"; 839e5c31af7Sopenharmony_ci params["VTX_OUT"] = "out"; 840e5c31af7Sopenharmony_ci params["FRAG_IN"] = "in"; 841e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "dEQP_FragColor"; 842e5c31af7Sopenharmony_ci params["VTX_HDR"] = "#version 330\n"; 843e5c31af7Sopenharmony_ci params["FRAG_HDR"] = "#version 330\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 844e5c31af7Sopenharmony_ci } 845e5c31af7Sopenharmony_ci else 846e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 847e5c31af7Sopenharmony_ci 848e5c31af7Sopenharmony_ci vertexShaderTmpl << "${VTX_HDR}"; 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 851e5c31af7Sopenharmony_ci { 852e5c31af7Sopenharmony_ci vertexShaderTmpl 853e5c31af7Sopenharmony_ci << "${VTX_IN} highp " << ContextArray::outputTypeToGLType(arrays[arrayNdx]->getOutputType()) << " a_" << arrays[arrayNdx]->getAttribNdx() << ";\n"; 854e5c31af7Sopenharmony_ci } 855e5c31af7Sopenharmony_ci 856e5c31af7Sopenharmony_ci vertexShaderTmpl << 857e5c31af7Sopenharmony_ci "uniform highp float u_coordScale;\n" 858e5c31af7Sopenharmony_ci "uniform highp float u_colorScale;\n" 859e5c31af7Sopenharmony_ci "${VTX_OUT} mediump vec4 v_color;\n" 860e5c31af7Sopenharmony_ci "void main(void)\n" 861e5c31af7Sopenharmony_ci "{\n" 862e5c31af7Sopenharmony_ci "\tgl_PointSize = 1.0;\n" 863e5c31af7Sopenharmony_ci "\thighp vec2 coord = vec2(1.0, 1.0);\n" 864e5c31af7Sopenharmony_ci "\thighp vec3 color = vec3(1.0, 1.0, 1.0);\n"; 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 867e5c31af7Sopenharmony_ci { 868e5c31af7Sopenharmony_ci if (arrays[arrayNdx]->getAttribNdx() == 0) 869e5c31af7Sopenharmony_ci { 870e5c31af7Sopenharmony_ci switch (arrays[arrayNdx]->getOutputType()) 871e5c31af7Sopenharmony_ci { 872e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_FLOAT): 873e5c31af7Sopenharmony_ci vertexShaderTmpl << 874e5c31af7Sopenharmony_ci "\tcoord = vec2(a_0);\n"; 875e5c31af7Sopenharmony_ci break; 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC2): 878e5c31af7Sopenharmony_ci vertexShaderTmpl << 879e5c31af7Sopenharmony_ci "\tcoord = a_0.xy;\n"; 880e5c31af7Sopenharmony_ci break; 881e5c31af7Sopenharmony_ci 882e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC3): 883e5c31af7Sopenharmony_ci vertexShaderTmpl << 884e5c31af7Sopenharmony_ci "\tcoord = a_0.xy;\n" 885e5c31af7Sopenharmony_ci "\tcoord.x = coord.x + a_0.z;\n"; 886e5c31af7Sopenharmony_ci break; 887e5c31af7Sopenharmony_ci 888e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC4): 889e5c31af7Sopenharmony_ci vertexShaderTmpl << 890e5c31af7Sopenharmony_ci "\tcoord = a_0.xy;\n" 891e5c31af7Sopenharmony_ci "\tcoord += a_0.zw;\n"; 892e5c31af7Sopenharmony_ci break; 893e5c31af7Sopenharmony_ci 894e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC2): 895e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC2): 896e5c31af7Sopenharmony_ci vertexShaderTmpl << 897e5c31af7Sopenharmony_ci "\tcoord = vec2(a_0.xy);\n"; 898e5c31af7Sopenharmony_ci break; 899e5c31af7Sopenharmony_ci 900e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC3): 901e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC3): 902e5c31af7Sopenharmony_ci vertexShaderTmpl << 903e5c31af7Sopenharmony_ci "\tcoord = vec2(a_0.xy);\n" 904e5c31af7Sopenharmony_ci "\tcoord.x = coord.x + float(a_0.z);\n"; 905e5c31af7Sopenharmony_ci break; 906e5c31af7Sopenharmony_ci 907e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC4): 908e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC4): 909e5c31af7Sopenharmony_ci vertexShaderTmpl << 910e5c31af7Sopenharmony_ci "\tcoord = vec2(a_0.xy);\n" 911e5c31af7Sopenharmony_ci "\tcoord += vec2(a_0.zw);\n"; 912e5c31af7Sopenharmony_ci break; 913e5c31af7Sopenharmony_ci 914e5c31af7Sopenharmony_ci default: 915e5c31af7Sopenharmony_ci DE_ASSERT(false); 916e5c31af7Sopenharmony_ci break; 917e5c31af7Sopenharmony_ci } 918e5c31af7Sopenharmony_ci continue; 919e5c31af7Sopenharmony_ci } 920e5c31af7Sopenharmony_ci 921e5c31af7Sopenharmony_ci switch (arrays[arrayNdx]->getOutputType()) 922e5c31af7Sopenharmony_ci { 923e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_FLOAT): 924e5c31af7Sopenharmony_ci vertexShaderTmpl << 925e5c31af7Sopenharmony_ci "\tcolor = color * a_" << arrays[arrayNdx]->getAttribNdx() << ";\n"; 926e5c31af7Sopenharmony_ci break; 927e5c31af7Sopenharmony_ci 928e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC2): 929e5c31af7Sopenharmony_ci vertexShaderTmpl << 930e5c31af7Sopenharmony_ci "\tcolor.rg = color.rg * a_" << arrays[arrayNdx]->getAttribNdx() << ".xy;\n"; 931e5c31af7Sopenharmony_ci break; 932e5c31af7Sopenharmony_ci 933e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC3): 934e5c31af7Sopenharmony_ci vertexShaderTmpl << 935e5c31af7Sopenharmony_ci "\tcolor = color.rgb * a_" << arrays[arrayNdx]->getAttribNdx() << ".xyz;\n"; 936e5c31af7Sopenharmony_ci break; 937e5c31af7Sopenharmony_ci 938e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC4): 939e5c31af7Sopenharmony_ci vertexShaderTmpl << 940e5c31af7Sopenharmony_ci "\tcolor = color.rgb * a_" << arrays[arrayNdx]->getAttribNdx() << ".xyz * a_" << arrays[arrayNdx]->getAttribNdx() << ".w;\n"; 941e5c31af7Sopenharmony_ci break; 942e5c31af7Sopenharmony_ci 943e5c31af7Sopenharmony_ci default: 944e5c31af7Sopenharmony_ci DE_ASSERT(false); 945e5c31af7Sopenharmony_ci break; 946e5c31af7Sopenharmony_ci } 947e5c31af7Sopenharmony_ci } 948e5c31af7Sopenharmony_ci 949e5c31af7Sopenharmony_ci vertexShaderTmpl << 950e5c31af7Sopenharmony_ci "\tv_color = vec4(u_colorScale * color, 1.0);\n" 951e5c31af7Sopenharmony_ci "\tgl_Position = vec4(u_coordScale * coord, 1.0, 1.0);\n" 952e5c31af7Sopenharmony_ci "}\n"; 953e5c31af7Sopenharmony_ci 954e5c31af7Sopenharmony_ci return tcu::StringTemplate(vertexShaderTmpl.str().c_str()).specialize(params); 955e5c31af7Sopenharmony_ci} 956e5c31af7Sopenharmony_ci 957e5c31af7Sopenharmony_cistd::string ContextShaderProgram::genFragmentSource (const glu::RenderContext& ctx) 958e5c31af7Sopenharmony_ci{ 959e5c31af7Sopenharmony_ci std::map<std::string, std::string> params; 960e5c31af7Sopenharmony_ci 961e5c31af7Sopenharmony_ci if (glu::isGLSLVersionSupported(ctx.getType(), glu::GLSL_VERSION_300_ES)) 962e5c31af7Sopenharmony_ci { 963e5c31af7Sopenharmony_ci params["VTX_IN"] = "in"; 964e5c31af7Sopenharmony_ci params["VTX_OUT"] = "out"; 965e5c31af7Sopenharmony_ci params["FRAG_IN"] = "in"; 966e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "dEQP_FragColor"; 967e5c31af7Sopenharmony_ci params["VTX_HDR"] = "#version 300 es\n"; 968e5c31af7Sopenharmony_ci params["FRAG_HDR"] = "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 969e5c31af7Sopenharmony_ci } 970e5c31af7Sopenharmony_ci else if (glu::isGLSLVersionSupported(ctx.getType(), glu::GLSL_VERSION_100_ES)) 971e5c31af7Sopenharmony_ci { 972e5c31af7Sopenharmony_ci params["VTX_IN"] = "attribute"; 973e5c31af7Sopenharmony_ci params["VTX_OUT"] = "varying"; 974e5c31af7Sopenharmony_ci params["FRAG_IN"] = "varying"; 975e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "gl_FragColor"; 976e5c31af7Sopenharmony_ci params["VTX_HDR"] = ""; 977e5c31af7Sopenharmony_ci params["FRAG_HDR"] = ""; 978e5c31af7Sopenharmony_ci } 979e5c31af7Sopenharmony_ci else if (glu::isGLSLVersionSupported(ctx.getType(), glu::GLSL_VERSION_330)) 980e5c31af7Sopenharmony_ci { 981e5c31af7Sopenharmony_ci params["VTX_IN"] = "in"; 982e5c31af7Sopenharmony_ci params["VTX_OUT"] = "out"; 983e5c31af7Sopenharmony_ci params["FRAG_IN"] = "in"; 984e5c31af7Sopenharmony_ci params["FRAG_COLOR"] = "dEQP_FragColor"; 985e5c31af7Sopenharmony_ci params["VTX_HDR"] = "#version 330\n"; 986e5c31af7Sopenharmony_ci params["FRAG_HDR"] = "#version 330\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 987e5c31af7Sopenharmony_ci } 988e5c31af7Sopenharmony_ci else 989e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 990e5c31af7Sopenharmony_ci 991e5c31af7Sopenharmony_ci static const char* fragmentShaderTmpl = 992e5c31af7Sopenharmony_ci "${FRAG_HDR}" 993e5c31af7Sopenharmony_ci "${FRAG_IN} mediump vec4 v_color;\n" 994e5c31af7Sopenharmony_ci "void main(void)\n" 995e5c31af7Sopenharmony_ci "{\n" 996e5c31af7Sopenharmony_ci "\t${FRAG_COLOR} = v_color;\n" 997e5c31af7Sopenharmony_ci "}\n"; 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci return tcu::StringTemplate(fragmentShaderTmpl).specialize(params); 1000e5c31af7Sopenharmony_ci} 1001e5c31af7Sopenharmony_ci 1002e5c31af7Sopenharmony_cirr::GenericVecType ContextShaderProgram::mapOutputType (const Array::OutputType& type) 1003e5c31af7Sopenharmony_ci{ 1004e5c31af7Sopenharmony_ci switch (type) 1005e5c31af7Sopenharmony_ci { 1006e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_FLOAT): 1007e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC2): 1008e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC3): 1009e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC4): 1010e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_FLOAT; 1011e5c31af7Sopenharmony_ci 1012e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_INT): 1013e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC2): 1014e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC3): 1015e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC4): 1016e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_INT32; 1017e5c31af7Sopenharmony_ci 1018e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UINT): 1019e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC2): 1020e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC3): 1021e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC4): 1022e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_UINT32; 1023e5c31af7Sopenharmony_ci 1024e5c31af7Sopenharmony_ci default: 1025e5c31af7Sopenharmony_ci DE_ASSERT(false); 1026e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_LAST; 1027e5c31af7Sopenharmony_ci } 1028e5c31af7Sopenharmony_ci} 1029e5c31af7Sopenharmony_ci 1030e5c31af7Sopenharmony_ciint ContextShaderProgram::getComponentCount (const Array::OutputType& type) 1031e5c31af7Sopenharmony_ci{ 1032e5c31af7Sopenharmony_ci switch (type) 1033e5c31af7Sopenharmony_ci { 1034e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_FLOAT): 1035e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_INT): 1036e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UINT): 1037e5c31af7Sopenharmony_ci return 1; 1038e5c31af7Sopenharmony_ci 1039e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC2): 1040e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC2): 1041e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC2): 1042e5c31af7Sopenharmony_ci return 2; 1043e5c31af7Sopenharmony_ci 1044e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC3): 1045e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC3): 1046e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC3): 1047e5c31af7Sopenharmony_ci return 3; 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_VEC4): 1050e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_IVEC4): 1051e5c31af7Sopenharmony_ci case (Array::OUTPUTTYPE_UVEC4): 1052e5c31af7Sopenharmony_ci return 4; 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_ci default: 1055e5c31af7Sopenharmony_ci DE_ASSERT(false); 1056e5c31af7Sopenharmony_ci return 0; 1057e5c31af7Sopenharmony_ci } 1058e5c31af7Sopenharmony_ci} 1059e5c31af7Sopenharmony_ci 1060e5c31af7Sopenharmony_cisglr::pdec::ShaderProgramDeclaration ContextShaderProgram::createProgramDeclaration (const glu::RenderContext& ctx, const std::vector<ContextArray*>& arrays) 1061e5c31af7Sopenharmony_ci{ 1062e5c31af7Sopenharmony_ci sglr::pdec::ShaderProgramDeclaration decl; 1063e5c31af7Sopenharmony_ci 1064e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++) 1065e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexAttribute(std::string("a_") + de::toString(arrayNdx), mapOutputType(arrays[arrayNdx]->getOutputType())); 1066e5c31af7Sopenharmony_ci 1067e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT); 1068e5c31af7Sopenharmony_ci decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT); 1069e5c31af7Sopenharmony_ci 1070e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexSource(genVertexSource(ctx, arrays)); 1071e5c31af7Sopenharmony_ci decl << sglr::pdec::FragmentSource(genFragmentSource(ctx)); 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ci decl << sglr::pdec::Uniform("u_coordScale", glu::TYPE_FLOAT); 1074e5c31af7Sopenharmony_ci decl << sglr::pdec::Uniform("u_colorScale", glu::TYPE_FLOAT); 1075e5c31af7Sopenharmony_ci 1076e5c31af7Sopenharmony_ci return decl; 1077e5c31af7Sopenharmony_ci} 1078e5c31af7Sopenharmony_ci 1079e5c31af7Sopenharmony_civoid ContextArrayPack::updateProgram (void) 1080e5c31af7Sopenharmony_ci{ 1081e5c31af7Sopenharmony_ci delete m_program; 1082e5c31af7Sopenharmony_ci m_program = new ContextShaderProgram(m_renderCtx, m_arrays); 1083e5c31af7Sopenharmony_ci} 1084e5c31af7Sopenharmony_ci 1085e5c31af7Sopenharmony_civoid ContextArrayPack::render (Array::Primitive primitive, int firstVertex, int vertexCount, bool useVao, float coordScale, float colorScale) 1086e5c31af7Sopenharmony_ci{ 1087e5c31af7Sopenharmony_ci deUint32 program = 0; 1088e5c31af7Sopenharmony_ci deUint32 vaoId = 0; 1089e5c31af7Sopenharmony_ci 1090e5c31af7Sopenharmony_ci updateProgram(); 1091e5c31af7Sopenharmony_ci 1092e5c31af7Sopenharmony_ci m_ctx.viewport(0, 0, m_screen.getWidth(), m_screen.getHeight()); 1093e5c31af7Sopenharmony_ci m_ctx.clearColor(0.0, 0.0, 0.0, 1.0); 1094e5c31af7Sopenharmony_ci m_ctx.clear(GL_COLOR_BUFFER_BIT); 1095e5c31af7Sopenharmony_ci 1096e5c31af7Sopenharmony_ci program = m_ctx.createProgram(m_program); 1097e5c31af7Sopenharmony_ci 1098e5c31af7Sopenharmony_ci m_ctx.useProgram(program); 1099e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glUseProgram()"); 1100e5c31af7Sopenharmony_ci 1101e5c31af7Sopenharmony_ci m_ctx.uniform1f(m_ctx.getUniformLocation(program, "u_coordScale"), coordScale); 1102e5c31af7Sopenharmony_ci m_ctx.uniform1f(m_ctx.getUniformLocation(program, "u_colorScale"), colorScale); 1103e5c31af7Sopenharmony_ci 1104e5c31af7Sopenharmony_ci if (useVao) 1105e5c31af7Sopenharmony_ci { 1106e5c31af7Sopenharmony_ci m_ctx.genVertexArrays(1, &vaoId); 1107e5c31af7Sopenharmony_ci m_ctx.bindVertexArray(vaoId); 1108e5c31af7Sopenharmony_ci } 1109e5c31af7Sopenharmony_ci 1110e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++) 1111e5c31af7Sopenharmony_ci { 1112e5c31af7Sopenharmony_ci if (m_arrays[arrayNdx]->isBound()) 1113e5c31af7Sopenharmony_ci { 1114e5c31af7Sopenharmony_ci std::stringstream attribName; 1115e5c31af7Sopenharmony_ci attribName << "a_" << m_arrays[arrayNdx]->getAttribNdx(); 1116e5c31af7Sopenharmony_ci 1117e5c31af7Sopenharmony_ci deUint32 loc = m_ctx.getAttribLocation(program, attribName.str().c_str()); 1118e5c31af7Sopenharmony_ci m_ctx.enableVertexAttribArray(loc); 1119e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glEnableVertexAttribArray()"); 1120e5c31af7Sopenharmony_ci 1121e5c31af7Sopenharmony_ci m_arrays[arrayNdx]->glBind(loc); 1122e5c31af7Sopenharmony_ci } 1123e5c31af7Sopenharmony_ci } 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_ci DE_ASSERT((firstVertex % 6) == 0); 1126e5c31af7Sopenharmony_ci m_ctx.drawArrays(ContextArray::primitiveToGL(primitive), firstVertex, vertexCount - firstVertex); 1127e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArrays()"); 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++) 1130e5c31af7Sopenharmony_ci { 1131e5c31af7Sopenharmony_ci if (m_arrays[arrayNdx]->isBound()) 1132e5c31af7Sopenharmony_ci { 1133e5c31af7Sopenharmony_ci std::stringstream attribName; 1134e5c31af7Sopenharmony_ci attribName << "a_" << m_arrays[arrayNdx]->getAttribNdx(); 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_ci deUint32 loc = m_ctx.getAttribLocation(program, attribName.str().c_str()); 1137e5c31af7Sopenharmony_ci 1138e5c31af7Sopenharmony_ci m_ctx.disableVertexAttribArray(loc); 1139e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDisableVertexAttribArray()"); 1140e5c31af7Sopenharmony_ci } 1141e5c31af7Sopenharmony_ci } 1142e5c31af7Sopenharmony_ci 1143e5c31af7Sopenharmony_ci if (useVao) 1144e5c31af7Sopenharmony_ci m_ctx.deleteVertexArrays(1, &vaoId); 1145e5c31af7Sopenharmony_ci 1146e5c31af7Sopenharmony_ci m_ctx.deleteProgram(program); 1147e5c31af7Sopenharmony_ci m_ctx.useProgram(0); 1148e5c31af7Sopenharmony_ci m_ctx.readPixels(m_screen, 0, 0, m_screen.getWidth(), m_screen.getHeight()); 1149e5c31af7Sopenharmony_ci} 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_ci// GLValue 1152e5c31af7Sopenharmony_ci 1153e5c31af7Sopenharmony_ciGLValue GLValue::getMaxValue (Array::InputType type) 1154e5c31af7Sopenharmony_ci{ 1155e5c31af7Sopenharmony_ci GLValue rangesHi[(int)Array::INPUTTYPE_LAST]; 1156e5c31af7Sopenharmony_ci 1157e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_FLOAT] = GLValue(Float::create(127.0f)); 1158e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_DOUBLE] = GLValue(Double::create(127.0f)); 1159e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_BYTE] = GLValue(Byte::create(127)); 1160e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_UNSIGNED_BYTE] = GLValue(Ubyte::create(255)); 1161e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(65530)); 1162e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_SHORT] = GLValue(Short::create(32760)); 1163e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_FIXED] = GLValue(Fixed::create(32760)); 1164e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_INT] = GLValue(Int::create(2147483647)); 1165e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_UNSIGNED_INT] = GLValue(Uint::create(4294967295u)); 1166e5c31af7Sopenharmony_ci rangesHi[(int)Array::INPUTTYPE_HALF] = GLValue(Half::create(256.0f)); 1167e5c31af7Sopenharmony_ci 1168e5c31af7Sopenharmony_ci return rangesHi[(int)type]; 1169e5c31af7Sopenharmony_ci} 1170e5c31af7Sopenharmony_ci 1171e5c31af7Sopenharmony_ciGLValue GLValue::getMinValue (Array::InputType type) 1172e5c31af7Sopenharmony_ci{ 1173e5c31af7Sopenharmony_ci GLValue rangesLo[(int)Array::INPUTTYPE_LAST]; 1174e5c31af7Sopenharmony_ci 1175e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_FLOAT] = GLValue(Float::create(-127.0f)); 1176e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_DOUBLE] = GLValue(Double::create(-127.0f)); 1177e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_BYTE] = GLValue(Byte::create(-127)); 1178e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_UNSIGNED_BYTE] = GLValue(Ubyte::create(0)); 1179e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(0)); 1180e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_SHORT] = GLValue(Short::create(-32760)); 1181e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_FIXED] = GLValue(Fixed::create(-32760)); 1182e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_INT] = GLValue(Int::create(-2147483647)); 1183e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_UNSIGNED_INT] = GLValue(Uint::create(0)); 1184e5c31af7Sopenharmony_ci rangesLo[(int)Array::INPUTTYPE_HALF] = GLValue(Half::create(-256.0f)); 1185e5c31af7Sopenharmony_ci 1186e5c31af7Sopenharmony_ci return rangesLo[(int)type]; 1187e5c31af7Sopenharmony_ci} 1188e5c31af7Sopenharmony_ci 1189e5c31af7Sopenharmony_cifloat GLValue::toFloat (void) const 1190e5c31af7Sopenharmony_ci{ 1191e5c31af7Sopenharmony_ci switch (type) 1192e5c31af7Sopenharmony_ci { 1193e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FLOAT: 1194e5c31af7Sopenharmony_ci return fl.getValue(); 1195e5c31af7Sopenharmony_ci 1196e5c31af7Sopenharmony_ci case Array::INPUTTYPE_BYTE: 1197e5c31af7Sopenharmony_ci return b.getValue(); 1198e5c31af7Sopenharmony_ci 1199e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_BYTE: 1200e5c31af7Sopenharmony_ci return ub.getValue(); 1201e5c31af7Sopenharmony_ci 1202e5c31af7Sopenharmony_ci case Array::INPUTTYPE_SHORT: 1203e5c31af7Sopenharmony_ci return s.getValue(); 1204e5c31af7Sopenharmony_ci 1205e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_SHORT: 1206e5c31af7Sopenharmony_ci return us.getValue(); 1207e5c31af7Sopenharmony_ci 1208e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FIXED: 1209e5c31af7Sopenharmony_ci { 1210e5c31af7Sopenharmony_ci int maxValue = 65536; 1211e5c31af7Sopenharmony_ci return (float)(double(2 * fi.getValue() + 1) / (maxValue - 1)); 1212e5c31af7Sopenharmony_ci } 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_INT: 1215e5c31af7Sopenharmony_ci return (float)ui.getValue(); 1216e5c31af7Sopenharmony_ci 1217e5c31af7Sopenharmony_ci case Array::INPUTTYPE_INT: 1218e5c31af7Sopenharmony_ci return (float)i.getValue(); 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_ci case Array::INPUTTYPE_HALF: 1221e5c31af7Sopenharmony_ci return h.to<float>(); 1222e5c31af7Sopenharmony_ci 1223e5c31af7Sopenharmony_ci case Array::INPUTTYPE_DOUBLE: 1224e5c31af7Sopenharmony_ci return (float)d.getValue(); 1225e5c31af7Sopenharmony_ci 1226e5c31af7Sopenharmony_ci default: 1227e5c31af7Sopenharmony_ci DE_ASSERT(false); 1228e5c31af7Sopenharmony_ci return 0.0f; 1229e5c31af7Sopenharmony_ci } 1230e5c31af7Sopenharmony_ci} 1231e5c31af7Sopenharmony_ci 1232e5c31af7Sopenharmony_ciclass RandomArrayGenerator 1233e5c31af7Sopenharmony_ci{ 1234e5c31af7Sopenharmony_cipublic: 1235e5c31af7Sopenharmony_ci static char* generateArray (int seed, GLValue min, GLValue max, int count, int componentCount, int stride, Array::InputType type); 1236e5c31af7Sopenharmony_ci static char* generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize); 1237e5c31af7Sopenharmony_ci static char* generatePerQuad (int seed, int count, int componentCount, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max); 1238e5c31af7Sopenharmony_ci 1239e5c31af7Sopenharmony_ciprivate: 1240e5c31af7Sopenharmony_ci template<typename T> 1241e5c31af7Sopenharmony_ci static char* createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize); 1242e5c31af7Sopenharmony_ci template<typename T> 1243e5c31af7Sopenharmony_ci static char* createPerQuads (int seed, int count, int componentCount, int stride, Array::Primitive primitive, T min, T max); 1244e5c31af7Sopenharmony_ci static char* createQuadsPacked (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive); 1245e5c31af7Sopenharmony_ci static void setData (char* data, Array::InputType type, deRandom& rnd, GLValue min, GLValue max); 1246e5c31af7Sopenharmony_ci}; 1247e5c31af7Sopenharmony_ci 1248e5c31af7Sopenharmony_civoid RandomArrayGenerator::setData (char* data, Array::InputType type, deRandom& rnd, GLValue min, GLValue max) 1249e5c31af7Sopenharmony_ci{ 1250e5c31af7Sopenharmony_ci switch (type) 1251e5c31af7Sopenharmony_ci { 1252e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FLOAT: 1253e5c31af7Sopenharmony_ci { 1254e5c31af7Sopenharmony_ci alignmentSafeAssignment<float>(data, getRandom<GLValue::Float>(rnd, min.fl, max.fl)); 1255e5c31af7Sopenharmony_ci break; 1256e5c31af7Sopenharmony_ci } 1257e5c31af7Sopenharmony_ci 1258e5c31af7Sopenharmony_ci case Array::INPUTTYPE_DOUBLE: 1259e5c31af7Sopenharmony_ci { 1260e5c31af7Sopenharmony_ci alignmentSafeAssignment<double>(data, getRandom<GLValue::Float>(rnd, min.fl, max.fl)); 1261e5c31af7Sopenharmony_ci break; 1262e5c31af7Sopenharmony_ci } 1263e5c31af7Sopenharmony_ci 1264e5c31af7Sopenharmony_ci case Array::INPUTTYPE_SHORT: 1265e5c31af7Sopenharmony_ci { 1266e5c31af7Sopenharmony_ci alignmentSafeAssignment<deInt16>(data, getRandom<GLValue::Short>(rnd, min.s, max.s)); 1267e5c31af7Sopenharmony_ci break; 1268e5c31af7Sopenharmony_ci } 1269e5c31af7Sopenharmony_ci 1270e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_SHORT: 1271e5c31af7Sopenharmony_ci { 1272e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint16>(data, getRandom<GLValue::Ushort>(rnd, min.us, max.us)); 1273e5c31af7Sopenharmony_ci break; 1274e5c31af7Sopenharmony_ci } 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_ci case Array::INPUTTYPE_BYTE: 1277e5c31af7Sopenharmony_ci { 1278e5c31af7Sopenharmony_ci alignmentSafeAssignment<deInt8>(data, getRandom<GLValue::Byte>(rnd, min.b, max.b)); 1279e5c31af7Sopenharmony_ci break; 1280e5c31af7Sopenharmony_ci } 1281e5c31af7Sopenharmony_ci 1282e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_BYTE: 1283e5c31af7Sopenharmony_ci { 1284e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint8>(data, getRandom<GLValue::Ubyte>(rnd, min.ub, max.ub)); 1285e5c31af7Sopenharmony_ci break; 1286e5c31af7Sopenharmony_ci } 1287e5c31af7Sopenharmony_ci 1288e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FIXED: 1289e5c31af7Sopenharmony_ci { 1290e5c31af7Sopenharmony_ci alignmentSafeAssignment<deInt32>(data, getRandom<GLValue::Fixed>(rnd, min.fi, max.fi)); 1291e5c31af7Sopenharmony_ci break; 1292e5c31af7Sopenharmony_ci } 1293e5c31af7Sopenharmony_ci 1294e5c31af7Sopenharmony_ci case Array::INPUTTYPE_INT: 1295e5c31af7Sopenharmony_ci { 1296e5c31af7Sopenharmony_ci alignmentSafeAssignment<deInt32>(data, getRandom<GLValue::Int>(rnd, min.i, max.i)); 1297e5c31af7Sopenharmony_ci break; 1298e5c31af7Sopenharmony_ci } 1299e5c31af7Sopenharmony_ci 1300e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_INT: 1301e5c31af7Sopenharmony_ci { 1302e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint32>(data, getRandom<GLValue::Uint>(rnd, min.ui, max.ui)); 1303e5c31af7Sopenharmony_ci break; 1304e5c31af7Sopenharmony_ci } 1305e5c31af7Sopenharmony_ci 1306e5c31af7Sopenharmony_ci case Array::INPUTTYPE_HALF: 1307e5c31af7Sopenharmony_ci { 1308e5c31af7Sopenharmony_ci alignmentSafeAssignment<deFloat16>(data, getRandom<GLValue::Half>(rnd, min.h, max.h).getValue()); 1309e5c31af7Sopenharmony_ci break; 1310e5c31af7Sopenharmony_ci } 1311e5c31af7Sopenharmony_ci 1312e5c31af7Sopenharmony_ci default: 1313e5c31af7Sopenharmony_ci DE_ASSERT(false); 1314e5c31af7Sopenharmony_ci break; 1315e5c31af7Sopenharmony_ci } 1316e5c31af7Sopenharmony_ci} 1317e5c31af7Sopenharmony_ci 1318e5c31af7Sopenharmony_cichar* RandomArrayGenerator::generateArray (int seed, GLValue min, GLValue max, int count, int componentCount, int stride, Array::InputType type) 1319e5c31af7Sopenharmony_ci{ 1320e5c31af7Sopenharmony_ci char* data = NULL; 1321e5c31af7Sopenharmony_ci 1322e5c31af7Sopenharmony_ci deRandom rnd; 1323e5c31af7Sopenharmony_ci deRandom_init(&rnd, seed); 1324e5c31af7Sopenharmony_ci 1325e5c31af7Sopenharmony_ci if (stride == 0) 1326e5c31af7Sopenharmony_ci stride = componentCount * Array::inputTypeSize(type); 1327e5c31af7Sopenharmony_ci 1328e5c31af7Sopenharmony_ci data = new char[stride * count]; 1329e5c31af7Sopenharmony_ci 1330e5c31af7Sopenharmony_ci for (int vertexNdx = 0; vertexNdx < count; vertexNdx++) 1331e5c31af7Sopenharmony_ci { 1332e5c31af7Sopenharmony_ci for (int componentNdx = 0; componentNdx < componentCount; componentNdx++) 1333e5c31af7Sopenharmony_ci { 1334e5c31af7Sopenharmony_ci setData(&(data[vertexNdx * stride + Array::inputTypeSize(type) * componentNdx]), type, rnd, min, max); 1335e5c31af7Sopenharmony_ci } 1336e5c31af7Sopenharmony_ci } 1337e5c31af7Sopenharmony_ci 1338e5c31af7Sopenharmony_ci return data; 1339e5c31af7Sopenharmony_ci} 1340e5c31af7Sopenharmony_ci 1341e5c31af7Sopenharmony_cichar* RandomArrayGenerator::generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize) 1342e5c31af7Sopenharmony_ci{ 1343e5c31af7Sopenharmony_ci char* data = DE_NULL; 1344e5c31af7Sopenharmony_ci 1345e5c31af7Sopenharmony_ci switch (type) 1346e5c31af7Sopenharmony_ci { 1347e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FLOAT: 1348e5c31af7Sopenharmony_ci data = createQuads<GLValue::Float>(seed, count, componentCount, offset, stride, primitive, min.fl, max.fl, gridSize); 1349e5c31af7Sopenharmony_ci break; 1350e5c31af7Sopenharmony_ci 1351e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FIXED: 1352e5c31af7Sopenharmony_ci data = createQuads<GLValue::Fixed>(seed, count, componentCount, offset, stride, primitive, min.fi, max.fi, gridSize); 1353e5c31af7Sopenharmony_ci break; 1354e5c31af7Sopenharmony_ci 1355e5c31af7Sopenharmony_ci case Array::INPUTTYPE_DOUBLE: 1356e5c31af7Sopenharmony_ci data = createQuads<GLValue::Double>(seed, count, componentCount, offset, stride, primitive, min.d, max.d, gridSize); 1357e5c31af7Sopenharmony_ci break; 1358e5c31af7Sopenharmony_ci 1359e5c31af7Sopenharmony_ci case Array::INPUTTYPE_BYTE: 1360e5c31af7Sopenharmony_ci data = createQuads<GLValue::Byte>(seed, count, componentCount, offset, stride, primitive, min.b, max.b, gridSize); 1361e5c31af7Sopenharmony_ci break; 1362e5c31af7Sopenharmony_ci 1363e5c31af7Sopenharmony_ci case Array::INPUTTYPE_SHORT: 1364e5c31af7Sopenharmony_ci data = createQuads<GLValue::Short>(seed, count, componentCount, offset, stride, primitive, min.s, max.s, gridSize); 1365e5c31af7Sopenharmony_ci break; 1366e5c31af7Sopenharmony_ci 1367e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_BYTE: 1368e5c31af7Sopenharmony_ci data = createQuads<GLValue::Ubyte>(seed, count, componentCount, offset, stride, primitive, min.ub, max.ub, gridSize); 1369e5c31af7Sopenharmony_ci break; 1370e5c31af7Sopenharmony_ci 1371e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_SHORT: 1372e5c31af7Sopenharmony_ci data = createQuads<GLValue::Ushort>(seed, count, componentCount, offset, stride, primitive, min.us, max.us, gridSize); 1373e5c31af7Sopenharmony_ci break; 1374e5c31af7Sopenharmony_ci 1375e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_INT: 1376e5c31af7Sopenharmony_ci data = createQuads<GLValue::Uint>(seed, count, componentCount, offset, stride, primitive, min.ui, max.ui, gridSize); 1377e5c31af7Sopenharmony_ci break; 1378e5c31af7Sopenharmony_ci 1379e5c31af7Sopenharmony_ci case Array::INPUTTYPE_INT: 1380e5c31af7Sopenharmony_ci data = createQuads<GLValue::Int>(seed, count, componentCount, offset, stride, primitive, min.i, max.i, gridSize); 1381e5c31af7Sopenharmony_ci break; 1382e5c31af7Sopenharmony_ci 1383e5c31af7Sopenharmony_ci case Array::INPUTTYPE_HALF: 1384e5c31af7Sopenharmony_ci data = createQuads<GLValue::Half>(seed, count, componentCount, offset, stride, primitive, min.h, max.h, gridSize); 1385e5c31af7Sopenharmony_ci break; 1386e5c31af7Sopenharmony_ci 1387e5c31af7Sopenharmony_ci case Array::INPUTTYPE_INT_2_10_10_10: 1388e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10: 1389e5c31af7Sopenharmony_ci data = createQuadsPacked(seed, count, componentCount, offset, stride, primitive); 1390e5c31af7Sopenharmony_ci break; 1391e5c31af7Sopenharmony_ci 1392e5c31af7Sopenharmony_ci default: 1393e5c31af7Sopenharmony_ci DE_ASSERT(false); 1394e5c31af7Sopenharmony_ci break; 1395e5c31af7Sopenharmony_ci } 1396e5c31af7Sopenharmony_ci 1397e5c31af7Sopenharmony_ci return data; 1398e5c31af7Sopenharmony_ci} 1399e5c31af7Sopenharmony_ci 1400e5c31af7Sopenharmony_cichar* RandomArrayGenerator::createQuadsPacked (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive) 1401e5c31af7Sopenharmony_ci{ 1402e5c31af7Sopenharmony_ci DE_ASSERT(componentCount == 4); 1403e5c31af7Sopenharmony_ci DE_UNREF(componentCount); 1404e5c31af7Sopenharmony_ci int quadStride = 0; 1405e5c31af7Sopenharmony_ci 1406e5c31af7Sopenharmony_ci if (stride == 0) 1407e5c31af7Sopenharmony_ci stride = sizeof(deUint32); 1408e5c31af7Sopenharmony_ci 1409e5c31af7Sopenharmony_ci switch (primitive) 1410e5c31af7Sopenharmony_ci { 1411e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 1412e5c31af7Sopenharmony_ci quadStride = stride * 6; 1413e5c31af7Sopenharmony_ci break; 1414e5c31af7Sopenharmony_ci 1415e5c31af7Sopenharmony_ci default: 1416e5c31af7Sopenharmony_ci DE_ASSERT(false); 1417e5c31af7Sopenharmony_ci break; 1418e5c31af7Sopenharmony_ci } 1419e5c31af7Sopenharmony_ci 1420e5c31af7Sopenharmony_ci char* const _data = new char[offset + quadStride * (count - 1) + stride * 5 + componentCount * Array::inputTypeSize(Array::INPUTTYPE_INT_2_10_10_10)]; // last element must be fully in the array 1421e5c31af7Sopenharmony_ci char* const resultData = _data + offset; 1422e5c31af7Sopenharmony_ci 1423e5c31af7Sopenharmony_ci const deUint32 max = 1024; 1424e5c31af7Sopenharmony_ci const deUint32 min = 10; 1425e5c31af7Sopenharmony_ci const deUint32 max2 = 4; 1426e5c31af7Sopenharmony_ci 1427e5c31af7Sopenharmony_ci deRandom rnd; 1428e5c31af7Sopenharmony_ci deRandom_init(&rnd, seed); 1429e5c31af7Sopenharmony_ci 1430e5c31af7Sopenharmony_ci switch (primitive) 1431e5c31af7Sopenharmony_ci { 1432e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 1433e5c31af7Sopenharmony_ci { 1434e5c31af7Sopenharmony_ci for (int quadNdx = 0; quadNdx < count; quadNdx++) 1435e5c31af7Sopenharmony_ci { 1436e5c31af7Sopenharmony_ci deUint32 x1 = min + deRandom_getUint32(&rnd) % (max - min); 1437e5c31af7Sopenharmony_ci deUint32 x2 = min + deRandom_getUint32(&rnd) % (max - x1); 1438e5c31af7Sopenharmony_ci 1439e5c31af7Sopenharmony_ci deUint32 y1 = min + deRandom_getUint32(&rnd) % (max - min); 1440e5c31af7Sopenharmony_ci deUint32 y2 = min + deRandom_getUint32(&rnd) % (max - y1); 1441e5c31af7Sopenharmony_ci 1442e5c31af7Sopenharmony_ci deUint32 z = min + deRandom_getUint32(&rnd) % (max - min); 1443e5c31af7Sopenharmony_ci deUint32 w = deRandom_getUint32(&rnd) % max2; 1444e5c31af7Sopenharmony_ci 1445e5c31af7Sopenharmony_ci deUint32 val1 = (w << 30) | (z << 20) | (y1 << 10) | x1; 1446e5c31af7Sopenharmony_ci deUint32 val2 = (w << 30) | (z << 20) | (y1 << 10) | x2; 1447e5c31af7Sopenharmony_ci deUint32 val3 = (w << 30) | (z << 20) | (y2 << 10) | x1; 1448e5c31af7Sopenharmony_ci 1449e5c31af7Sopenharmony_ci deUint32 val4 = (w << 30) | (z << 20) | (y2 << 10) | x1; 1450e5c31af7Sopenharmony_ci deUint32 val5 = (w << 30) | (z << 20) | (y1 << 10) | x2; 1451e5c31af7Sopenharmony_ci deUint32 val6 = (w << 30) | (z << 20) | (y2 << 10) | x2; 1452e5c31af7Sopenharmony_ci 1453e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 0]), val1); 1454e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 1]), val2); 1455e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 2]), val3); 1456e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 3]), val4); 1457e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 4]), val5); 1458e5c31af7Sopenharmony_ci alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 5]), val6); 1459e5c31af7Sopenharmony_ci } 1460e5c31af7Sopenharmony_ci 1461e5c31af7Sopenharmony_ci break; 1462e5c31af7Sopenharmony_ci } 1463e5c31af7Sopenharmony_ci 1464e5c31af7Sopenharmony_ci default: 1465e5c31af7Sopenharmony_ci DE_ASSERT(false); 1466e5c31af7Sopenharmony_ci break; 1467e5c31af7Sopenharmony_ci } 1468e5c31af7Sopenharmony_ci 1469e5c31af7Sopenharmony_ci return _data; 1470e5c31af7Sopenharmony_ci} 1471e5c31af7Sopenharmony_ci 1472e5c31af7Sopenharmony_citemplate<typename T> 1473e5c31af7Sopenharmony_ciT roundTo (const T& step, const T& value) 1474e5c31af7Sopenharmony_ci{ 1475e5c31af7Sopenharmony_ci return value - (value % step); 1476e5c31af7Sopenharmony_ci} 1477e5c31af7Sopenharmony_ci 1478e5c31af7Sopenharmony_citemplate<typename T> 1479e5c31af7Sopenharmony_cichar* RandomArrayGenerator::createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize) 1480e5c31af7Sopenharmony_ci{ 1481e5c31af7Sopenharmony_ci int componentStride = sizeof(T); 1482e5c31af7Sopenharmony_ci int quadStride = 0; 1483e5c31af7Sopenharmony_ci 1484e5c31af7Sopenharmony_ci if (stride == 0) 1485e5c31af7Sopenharmony_ci stride = componentCount * componentStride; 1486e5c31af7Sopenharmony_ci 1487e5c31af7Sopenharmony_ci DE_ASSERT(stride >= componentCount * componentStride); 1488e5c31af7Sopenharmony_ci 1489e5c31af7Sopenharmony_ci switch (primitive) 1490e5c31af7Sopenharmony_ci { 1491e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 1492e5c31af7Sopenharmony_ci quadStride = stride * 6; 1493e5c31af7Sopenharmony_ci break; 1494e5c31af7Sopenharmony_ci 1495e5c31af7Sopenharmony_ci default: 1496e5c31af7Sopenharmony_ci DE_ASSERT(false); 1497e5c31af7Sopenharmony_ci break; 1498e5c31af7Sopenharmony_ci } 1499e5c31af7Sopenharmony_ci 1500e5c31af7Sopenharmony_ci char* resultData = new char[offset + quadStride * count]; 1501e5c31af7Sopenharmony_ci char* _data = resultData; 1502e5c31af7Sopenharmony_ci resultData = resultData + offset; 1503e5c31af7Sopenharmony_ci 1504e5c31af7Sopenharmony_ci deRandom rnd; 1505e5c31af7Sopenharmony_ci deRandom_init(&rnd, seed); 1506e5c31af7Sopenharmony_ci 1507e5c31af7Sopenharmony_ci switch (primitive) 1508e5c31af7Sopenharmony_ci { 1509e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 1510e5c31af7Sopenharmony_ci { 1511e5c31af7Sopenharmony_ci const T minQuadSize = T::fromFloat(deFloatAbs(max.template to<float>() - min.template to<float>()) * gridSize); 1512e5c31af7Sopenharmony_ci const T minDiff = minValue<T>() > minQuadSize 1513e5c31af7Sopenharmony_ci ? minValue<T>() 1514e5c31af7Sopenharmony_ci : minQuadSize; 1515e5c31af7Sopenharmony_ci const T maxRounded = roundTo(minDiff, max); 1516e5c31af7Sopenharmony_ci 1517e5c31af7Sopenharmony_ci for (int quadNdx = 0; quadNdx < count; ++quadNdx) 1518e5c31af7Sopenharmony_ci { 1519e5c31af7Sopenharmony_ci T x1, x2; 1520e5c31af7Sopenharmony_ci T y1, y2; 1521e5c31af7Sopenharmony_ci T z, w; 1522e5c31af7Sopenharmony_ci 1523e5c31af7Sopenharmony_ci x1 = roundTo(minDiff, getRandom<T>(rnd, min, maxRounded - minDiff)); 1524e5c31af7Sopenharmony_ci x2 = roundTo(minDiff, getRandom<T>(rnd, x1 + minDiff, maxRounded)); 1525e5c31af7Sopenharmony_ci 1526e5c31af7Sopenharmony_ci y1 = roundTo(minDiff, getRandom<T>(rnd, min, maxRounded - minDiff)); 1527e5c31af7Sopenharmony_ci y2 = roundTo(minDiff, getRandom<T>(rnd, y1 + minDiff, maxRounded)); 1528e5c31af7Sopenharmony_ci 1529e5c31af7Sopenharmony_ci // Make sure the rounding doesn't drop the result below the original range of the random function. 1530e5c31af7Sopenharmony_ci if (x2 < x1 + minDiff) x2 = x1 + minDiff; 1531e5c31af7Sopenharmony_ci if (y2 < y1 + minDiff) y2 = y1 + minDiff; 1532e5c31af7Sopenharmony_ci 1533e5c31af7Sopenharmony_ci z = (componentCount > 2) ? roundTo(minDiff, (getRandom<T>(rnd, min, max))) : (T::create(0)); 1534e5c31af7Sopenharmony_ci w = (componentCount > 3) ? roundTo(minDiff, (getRandom<T>(rnd, min, max))) : (T::create(1)); 1535e5c31af7Sopenharmony_ci 1536e5c31af7Sopenharmony_ci // Make sure the quad is not too thin. 1537e5c31af7Sopenharmony_ci DE_ASSERT((deFloatAbs(x2.template to<float>() - x1.template to<float>()) >= minDiff.template to<float>() * 0.8f) && 1538e5c31af7Sopenharmony_ci (deFloatAbs(y2.template to<float>() - y1.template to<float>()) >= minDiff.template to<float>() * 0.8f)); 1539e5c31af7Sopenharmony_ci 1540e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride]), x1); 1541e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + componentStride]), y1); 1542e5c31af7Sopenharmony_ci 1543e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride]), x2); 1544e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride + componentStride]), y1); 1545e5c31af7Sopenharmony_ci 1546e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 2]), x1); 1547e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 2 + componentStride]), y2); 1548e5c31af7Sopenharmony_ci 1549e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 3]), x1); 1550e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 3 + componentStride]), y2); 1551e5c31af7Sopenharmony_ci 1552e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 4]), x2); 1553e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 4 + componentStride]), y1); 1554e5c31af7Sopenharmony_ci 1555e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 5]), x2); 1556e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 5 + componentStride]), y2); 1557e5c31af7Sopenharmony_ci 1558e5c31af7Sopenharmony_ci if (componentCount > 2) 1559e5c31af7Sopenharmony_ci { 1560e5c31af7Sopenharmony_ci for (int i = 0; i < 6; i++) 1561e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * i + componentStride * 2]), z); 1562e5c31af7Sopenharmony_ci } 1563e5c31af7Sopenharmony_ci 1564e5c31af7Sopenharmony_ci if (componentCount > 3) 1565e5c31af7Sopenharmony_ci { 1566e5c31af7Sopenharmony_ci for (int i = 0; i < 6; i++) 1567e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * i + componentStride * 3]), w); 1568e5c31af7Sopenharmony_ci } 1569e5c31af7Sopenharmony_ci } 1570e5c31af7Sopenharmony_ci 1571e5c31af7Sopenharmony_ci break; 1572e5c31af7Sopenharmony_ci } 1573e5c31af7Sopenharmony_ci 1574e5c31af7Sopenharmony_ci default: 1575e5c31af7Sopenharmony_ci DE_ASSERT(false); 1576e5c31af7Sopenharmony_ci break; 1577e5c31af7Sopenharmony_ci } 1578e5c31af7Sopenharmony_ci 1579e5c31af7Sopenharmony_ci return _data; 1580e5c31af7Sopenharmony_ci} 1581e5c31af7Sopenharmony_ci 1582e5c31af7Sopenharmony_cichar* RandomArrayGenerator::generatePerQuad (int seed, int count, int componentCount, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max) 1583e5c31af7Sopenharmony_ci{ 1584e5c31af7Sopenharmony_ci char* data = DE_NULL; 1585e5c31af7Sopenharmony_ci 1586e5c31af7Sopenharmony_ci switch (type) 1587e5c31af7Sopenharmony_ci { 1588e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FLOAT: 1589e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Float>(seed, count, componentCount, stride, primitive, min.fl, max.fl); 1590e5c31af7Sopenharmony_ci break; 1591e5c31af7Sopenharmony_ci 1592e5c31af7Sopenharmony_ci case Array::INPUTTYPE_FIXED: 1593e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Fixed>(seed, count, componentCount, stride, primitive, min.fi, max.fi); 1594e5c31af7Sopenharmony_ci break; 1595e5c31af7Sopenharmony_ci 1596e5c31af7Sopenharmony_ci case Array::INPUTTYPE_DOUBLE: 1597e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Double>(seed, count, componentCount, stride, primitive, min.d, max.d); 1598e5c31af7Sopenharmony_ci break; 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci case Array::INPUTTYPE_BYTE: 1601e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Byte>(seed, count, componentCount, stride, primitive, min.b, max.b); 1602e5c31af7Sopenharmony_ci break; 1603e5c31af7Sopenharmony_ci 1604e5c31af7Sopenharmony_ci case Array::INPUTTYPE_SHORT: 1605e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Short>(seed, count, componentCount, stride, primitive, min.s, max.s); 1606e5c31af7Sopenharmony_ci break; 1607e5c31af7Sopenharmony_ci 1608e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_BYTE: 1609e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Ubyte>(seed, count, componentCount, stride, primitive, min.ub, max.ub); 1610e5c31af7Sopenharmony_ci break; 1611e5c31af7Sopenharmony_ci 1612e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_SHORT: 1613e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Ushort>(seed, count, componentCount, stride, primitive, min.us, max.us); 1614e5c31af7Sopenharmony_ci break; 1615e5c31af7Sopenharmony_ci 1616e5c31af7Sopenharmony_ci case Array::INPUTTYPE_UNSIGNED_INT: 1617e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Uint>(seed, count, componentCount, stride, primitive, min.ui, max.ui); 1618e5c31af7Sopenharmony_ci break; 1619e5c31af7Sopenharmony_ci 1620e5c31af7Sopenharmony_ci case Array::INPUTTYPE_INT: 1621e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Int>(seed, count, componentCount, stride, primitive, min.i, max.i); 1622e5c31af7Sopenharmony_ci break; 1623e5c31af7Sopenharmony_ci 1624e5c31af7Sopenharmony_ci case Array::INPUTTYPE_HALF: 1625e5c31af7Sopenharmony_ci data = createPerQuads<GLValue::Half>(seed, count, componentCount, stride, primitive, min.h, max.h); 1626e5c31af7Sopenharmony_ci break; 1627e5c31af7Sopenharmony_ci 1628e5c31af7Sopenharmony_ci default: 1629e5c31af7Sopenharmony_ci DE_ASSERT(false); 1630e5c31af7Sopenharmony_ci break; 1631e5c31af7Sopenharmony_ci } 1632e5c31af7Sopenharmony_ci 1633e5c31af7Sopenharmony_ci return data; 1634e5c31af7Sopenharmony_ci} 1635e5c31af7Sopenharmony_ci 1636e5c31af7Sopenharmony_citemplate<typename T> 1637e5c31af7Sopenharmony_cichar* RandomArrayGenerator::createPerQuads (int seed, int count, int componentCount, int stride, Array::Primitive primitive, T min, T max) 1638e5c31af7Sopenharmony_ci{ 1639e5c31af7Sopenharmony_ci deRandom rnd; 1640e5c31af7Sopenharmony_ci deRandom_init(&rnd, seed); 1641e5c31af7Sopenharmony_ci 1642e5c31af7Sopenharmony_ci int componentStride = sizeof(T); 1643e5c31af7Sopenharmony_ci 1644e5c31af7Sopenharmony_ci if (stride == 0) 1645e5c31af7Sopenharmony_ci stride = componentStride * componentCount; 1646e5c31af7Sopenharmony_ci 1647e5c31af7Sopenharmony_ci int quadStride = 0; 1648e5c31af7Sopenharmony_ci 1649e5c31af7Sopenharmony_ci switch (primitive) 1650e5c31af7Sopenharmony_ci { 1651e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 1652e5c31af7Sopenharmony_ci quadStride = stride * 6; 1653e5c31af7Sopenharmony_ci break; 1654e5c31af7Sopenharmony_ci 1655e5c31af7Sopenharmony_ci default: 1656e5c31af7Sopenharmony_ci DE_ASSERT(false); 1657e5c31af7Sopenharmony_ci break; 1658e5c31af7Sopenharmony_ci } 1659e5c31af7Sopenharmony_ci 1660e5c31af7Sopenharmony_ci char* data = new char[count * quadStride]; 1661e5c31af7Sopenharmony_ci 1662e5c31af7Sopenharmony_ci for (int quadNdx = 0; quadNdx < count; quadNdx++) 1663e5c31af7Sopenharmony_ci { 1664e5c31af7Sopenharmony_ci for (int componentNdx = 0; componentNdx < componentCount; componentNdx++) 1665e5c31af7Sopenharmony_ci { 1666e5c31af7Sopenharmony_ci T val = getRandom<T>(rnd, min, max); 1667e5c31af7Sopenharmony_ci 1668e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 0 + componentStride * componentNdx, val); 1669e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 1 + componentStride * componentNdx, val); 1670e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 2 + componentStride * componentNdx, val); 1671e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 3 + componentStride * componentNdx, val); 1672e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 4 + componentStride * componentNdx, val); 1673e5c31af7Sopenharmony_ci alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 5 + componentStride * componentNdx, val); 1674e5c31af7Sopenharmony_ci } 1675e5c31af7Sopenharmony_ci } 1676e5c31af7Sopenharmony_ci 1677e5c31af7Sopenharmony_ci return data; 1678e5c31af7Sopenharmony_ci} 1679e5c31af7Sopenharmony_ci 1680e5c31af7Sopenharmony_ci// VertexArrayTest 1681e5c31af7Sopenharmony_ci 1682e5c31af7Sopenharmony_ciVertexArrayTest::VertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name ,const char* desc) 1683e5c31af7Sopenharmony_ci : TestCase (testCtx, name, desc) 1684e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 1685e5c31af7Sopenharmony_ci , m_refBuffers (DE_NULL) 1686e5c31af7Sopenharmony_ci , m_refContext (DE_NULL) 1687e5c31af7Sopenharmony_ci , m_glesContext (DE_NULL) 1688e5c31af7Sopenharmony_ci , m_glArrayPack (DE_NULL) 1689e5c31af7Sopenharmony_ci , m_rrArrayPack (DE_NULL) 1690e5c31af7Sopenharmony_ci , m_isOk (false) 1691e5c31af7Sopenharmony_ci , m_maxDiffRed (deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits)))) 1692e5c31af7Sopenharmony_ci , m_maxDiffGreen (deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits)))) 1693e5c31af7Sopenharmony_ci , m_maxDiffBlue (deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().blueBits)))) 1694e5c31af7Sopenharmony_ci{ 1695e5c31af7Sopenharmony_ci} 1696e5c31af7Sopenharmony_ci 1697e5c31af7Sopenharmony_ciVertexArrayTest::~VertexArrayTest (void) 1698e5c31af7Sopenharmony_ci{ 1699e5c31af7Sopenharmony_ci deinit(); 1700e5c31af7Sopenharmony_ci} 1701e5c31af7Sopenharmony_ci 1702e5c31af7Sopenharmony_civoid VertexArrayTest::init (void) 1703e5c31af7Sopenharmony_ci{ 1704e5c31af7Sopenharmony_ci const int renderTargetWidth = de::min(512, m_renderCtx.getRenderTarget().getWidth()); 1705e5c31af7Sopenharmony_ci const int renderTargetHeight = de::min(512, m_renderCtx.getRenderTarget().getHeight()); 1706e5c31af7Sopenharmony_ci sglr::ReferenceContextLimits limits (m_renderCtx); 1707e5c31af7Sopenharmony_ci 1708e5c31af7Sopenharmony_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)); 1709e5c31af7Sopenharmony_ci 1710e5c31af7Sopenharmony_ci m_refBuffers = new sglr::ReferenceContextBuffers(m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, renderTargetWidth, renderTargetHeight); 1711e5c31af7Sopenharmony_ci m_refContext = new sglr::ReferenceContext(limits, m_refBuffers->getColorbuffer(), m_refBuffers->getDepthbuffer(), m_refBuffers->getStencilbuffer()); 1712e5c31af7Sopenharmony_ci 1713e5c31af7Sopenharmony_ci m_glArrayPack = new ContextArrayPack(m_renderCtx, *m_glesContext); 1714e5c31af7Sopenharmony_ci m_rrArrayPack = new ContextArrayPack(m_renderCtx, *m_refContext); 1715e5c31af7Sopenharmony_ci} 1716e5c31af7Sopenharmony_ci 1717e5c31af7Sopenharmony_civoid VertexArrayTest::deinit (void) 1718e5c31af7Sopenharmony_ci{ 1719e5c31af7Sopenharmony_ci delete m_glArrayPack; 1720e5c31af7Sopenharmony_ci delete m_rrArrayPack; 1721e5c31af7Sopenharmony_ci delete m_refBuffers; 1722e5c31af7Sopenharmony_ci delete m_refContext; 1723e5c31af7Sopenharmony_ci delete m_glesContext; 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_ci m_glArrayPack = DE_NULL; 1726e5c31af7Sopenharmony_ci m_rrArrayPack = DE_NULL; 1727e5c31af7Sopenharmony_ci m_refBuffers = DE_NULL; 1728e5c31af7Sopenharmony_ci m_refContext = DE_NULL; 1729e5c31af7Sopenharmony_ci m_glesContext = DE_NULL; 1730e5c31af7Sopenharmony_ci} 1731e5c31af7Sopenharmony_ci 1732e5c31af7Sopenharmony_civoid VertexArrayTest::compare (void) 1733e5c31af7Sopenharmony_ci{ 1734e5c31af7Sopenharmony_ci const tcu::Surface& ref = m_rrArrayPack->getSurface(); 1735e5c31af7Sopenharmony_ci const tcu::Surface& screen = m_glArrayPack->getSurface(); 1736e5c31af7Sopenharmony_ci 1737e5c31af7Sopenharmony_ci if (m_renderCtx.getRenderTarget().getNumSamples() > 1) 1738e5c31af7Sopenharmony_ci { 1739e5c31af7Sopenharmony_ci // \todo [mika] Improve compare when using multisampling 1740e5c31af7Sopenharmony_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; 1741e5c31af7Sopenharmony_ci m_isOk = tcu::fuzzyCompare(m_testCtx.getLog(), "Compare Results", "Compare Results", ref.getAccess(), screen.getAccess(), 1.5f, tcu::COMPARE_LOG_RESULT); 1742e5c31af7Sopenharmony_ci } 1743e5c31af7Sopenharmony_ci else 1744e5c31af7Sopenharmony_ci { 1745e5c31af7Sopenharmony_ci tcu::RGBA threshold (m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue, 255); 1746e5c31af7Sopenharmony_ci tcu::Surface error (ref.getWidth(), ref.getHeight()); 1747e5c31af7Sopenharmony_ci 1748e5c31af7Sopenharmony_ci m_isOk = true; 1749e5c31af7Sopenharmony_ci 1750e5c31af7Sopenharmony_ci for (int y = 0; y < ref.getHeight(); y++) 1751e5c31af7Sopenharmony_ci { 1752e5c31af7Sopenharmony_ci for (int x = 0; x < ref.getWidth(); x++) 1753e5c31af7Sopenharmony_ci { 1754e5c31af7Sopenharmony_ci tcu::RGBA refPixel = ref.getPixel(x, y); 1755e5c31af7Sopenharmony_ci tcu::RGBA screenPixel = screen.getPixel(x, y); 1756e5c31af7Sopenharmony_ci bool isOkPixel = false; 1757e5c31af7Sopenharmony_ci 1758e5c31af7Sopenharmony_ci if (y == 0 || y + 1 == ref.getHeight() || x == 0 || x + 1 == ref.getWidth()) 1759e5c31af7Sopenharmony_ci { 1760e5c31af7Sopenharmony_ci // Don't check borders since the pixel neighborhood is undefined 1761e5c31af7Sopenharmony_ci error.setPixel(x, y, tcu::RGBA(screenPixel.getRed(), (screenPixel.getGreen() + 255) / 2, screenPixel.getBlue(), 255)); 1762e5c31af7Sopenharmony_ci continue; 1763e5c31af7Sopenharmony_ci } 1764e5c31af7Sopenharmony_ci 1765e5c31af7Sopenharmony_ci // Don't do comparisons for this pixel if it belongs to a one-pixel-thin part (i.e. it doesn't have similar-color neighbors in both x and y directions) in both result and reference. 1766e5c31af7Sopenharmony_ci // This fixes some false negatives. 1767e5c31af7Sopenharmony_ci bool refThin = (!tcu::compareThreshold(refPixel, ref.getPixel(x-1, y ), threshold) && !tcu::compareThreshold(refPixel, ref.getPixel(x+1, y ), threshold)) || 1768e5c31af7Sopenharmony_ci (!tcu::compareThreshold(refPixel, ref.getPixel(x , y-1), threshold) && !tcu::compareThreshold(refPixel, ref.getPixel(x , y+1), threshold)); 1769e5c31af7Sopenharmony_ci bool screenThin = (!tcu::compareThreshold(screenPixel, screen.getPixel(x-1, y ), threshold) && !tcu::compareThreshold(screenPixel, screen.getPixel(x+1, y ), threshold)) || 1770e5c31af7Sopenharmony_ci (!tcu::compareThreshold(screenPixel, screen.getPixel(x , y-1), threshold) && !tcu::compareThreshold(screenPixel, screen.getPixel(x , y+1), threshold)); 1771e5c31af7Sopenharmony_ci 1772e5c31af7Sopenharmony_ci if (refThin && screenThin) 1773e5c31af7Sopenharmony_ci isOkPixel = true; 1774e5c31af7Sopenharmony_ci else 1775e5c31af7Sopenharmony_ci { 1776e5c31af7Sopenharmony_ci for (int dy = -1; dy < 2 && !isOkPixel; dy++) 1777e5c31af7Sopenharmony_ci { 1778e5c31af7Sopenharmony_ci for (int dx = -1; dx < 2 && !isOkPixel; dx++) 1779e5c31af7Sopenharmony_ci { 1780e5c31af7Sopenharmony_ci // Check reference pixel against screen pixel 1781e5c31af7Sopenharmony_ci { 1782e5c31af7Sopenharmony_ci tcu::RGBA screenCmpPixel = screen.getPixel(x+dx, y+dy); 1783e5c31af7Sopenharmony_ci deUint8 r = (deUint8)deAbs32(refPixel.getRed() - screenCmpPixel.getRed()); 1784e5c31af7Sopenharmony_ci deUint8 g = (deUint8)deAbs32(refPixel.getGreen() - screenCmpPixel.getGreen()); 1785e5c31af7Sopenharmony_ci deUint8 b = (deUint8)deAbs32(refPixel.getBlue() - screenCmpPixel.getBlue()); 1786e5c31af7Sopenharmony_ci 1787e5c31af7Sopenharmony_ci if (r <= m_maxDiffRed && g <= m_maxDiffGreen && b <= m_maxDiffBlue) 1788e5c31af7Sopenharmony_ci isOkPixel = true; 1789e5c31af7Sopenharmony_ci } 1790e5c31af7Sopenharmony_ci 1791e5c31af7Sopenharmony_ci // Check screen pixels against reference pixel 1792e5c31af7Sopenharmony_ci { 1793e5c31af7Sopenharmony_ci tcu::RGBA refCmpPixel = ref.getPixel(x+dx, y+dy); 1794e5c31af7Sopenharmony_ci deUint8 r = (deUint8)deAbs32(refCmpPixel.getRed() - screenPixel.getRed()); 1795e5c31af7Sopenharmony_ci deUint8 g = (deUint8)deAbs32(refCmpPixel.getGreen() - screenPixel.getGreen()); 1796e5c31af7Sopenharmony_ci deUint8 b = (deUint8)deAbs32(refCmpPixel.getBlue() - screenPixel.getBlue()); 1797e5c31af7Sopenharmony_ci 1798e5c31af7Sopenharmony_ci if (r <= m_maxDiffRed && g <= m_maxDiffGreen && b <= m_maxDiffBlue) 1799e5c31af7Sopenharmony_ci isOkPixel = true; 1800e5c31af7Sopenharmony_ci } 1801e5c31af7Sopenharmony_ci } 1802e5c31af7Sopenharmony_ci } 1803e5c31af7Sopenharmony_ci } 1804e5c31af7Sopenharmony_ci 1805e5c31af7Sopenharmony_ci if (isOkPixel) 1806e5c31af7Sopenharmony_ci error.setPixel(x, y, tcu::RGBA(screen.getPixel(x, y).getRed(), (screen.getPixel(x, y).getGreen() + 255) / 2, screen.getPixel(x, y).getBlue(), 255)); 1807e5c31af7Sopenharmony_ci else 1808e5c31af7Sopenharmony_ci { 1809e5c31af7Sopenharmony_ci error.setPixel(x, y, tcu::RGBA(255, 0, 0, 255)); 1810e5c31af7Sopenharmony_ci m_isOk = false; 1811e5c31af7Sopenharmony_ci } 1812e5c31af7Sopenharmony_ci } 1813e5c31af7Sopenharmony_ci } 1814e5c31af7Sopenharmony_ci 1815e5c31af7Sopenharmony_ci tcu::TestLog& log = m_testCtx.getLog(); 1816e5c31af7Sopenharmony_ci if (!m_isOk) 1817e5c31af7Sopenharmony_ci { 1818e5c31af7Sopenharmony_ci log << TestLog::Message << "Image comparison failed, threshold = (" << m_maxDiffRed << ", " << m_maxDiffGreen << ", " << m_maxDiffBlue << ")" << TestLog::EndMessage; 1819e5c31af7Sopenharmony_ci log << TestLog::ImageSet("Compare result", "Result of rendering") 1820e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", screen) 1821e5c31af7Sopenharmony_ci << TestLog::Image("Reference", "Reference", ref) 1822e5c31af7Sopenharmony_ci << TestLog::Image("ErrorMask", "Error mask", error) 1823e5c31af7Sopenharmony_ci << TestLog::EndImageSet; 1824e5c31af7Sopenharmony_ci } 1825e5c31af7Sopenharmony_ci else 1826e5c31af7Sopenharmony_ci { 1827e5c31af7Sopenharmony_ci log << TestLog::ImageSet("Compare result", "Result of rendering") 1828e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", screen) 1829e5c31af7Sopenharmony_ci << TestLog::EndImageSet; 1830e5c31af7Sopenharmony_ci } 1831e5c31af7Sopenharmony_ci } 1832e5c31af7Sopenharmony_ci} 1833e5c31af7Sopenharmony_ci 1834e5c31af7Sopenharmony_ci// MultiVertexArrayTest 1835e5c31af7Sopenharmony_ci 1836e5c31af7Sopenharmony_ciMultiVertexArrayTest::Spec::ArraySpec::ArraySpec(Array::InputType inputType_, Array::OutputType outputType_, Array::Storage storage_, Array::Usage usage_, int componentCount_, int offset_, int stride_, bool normalize_, GLValue min_, GLValue max_) 1837e5c31af7Sopenharmony_ci : inputType (inputType_) 1838e5c31af7Sopenharmony_ci , outputType (outputType_) 1839e5c31af7Sopenharmony_ci , storage (storage_) 1840e5c31af7Sopenharmony_ci , usage (usage_) 1841e5c31af7Sopenharmony_ci , componentCount(componentCount_) 1842e5c31af7Sopenharmony_ci , offset (offset_) 1843e5c31af7Sopenharmony_ci , stride (stride_) 1844e5c31af7Sopenharmony_ci , normalize (normalize_) 1845e5c31af7Sopenharmony_ci , min (min_) 1846e5c31af7Sopenharmony_ci , max (max_) 1847e5c31af7Sopenharmony_ci{ 1848e5c31af7Sopenharmony_ci} 1849e5c31af7Sopenharmony_ci 1850e5c31af7Sopenharmony_cistd::string MultiVertexArrayTest::Spec::getName (void) const 1851e5c31af7Sopenharmony_ci{ 1852e5c31af7Sopenharmony_ci std::stringstream name; 1853e5c31af7Sopenharmony_ci 1854e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < arrays.size(); ++ndx) 1855e5c31af7Sopenharmony_ci { 1856e5c31af7Sopenharmony_ci const ArraySpec& array = arrays[ndx]; 1857e5c31af7Sopenharmony_ci 1858e5c31af7Sopenharmony_ci if (arrays.size() > 1) 1859e5c31af7Sopenharmony_ci name << "array" << ndx << "_"; 1860e5c31af7Sopenharmony_ci 1861e5c31af7Sopenharmony_ci name 1862e5c31af7Sopenharmony_ci << Array::storageToString(array.storage) << "_" 1863e5c31af7Sopenharmony_ci << array.offset << "_" 1864e5c31af7Sopenharmony_ci << array.stride << "_" 1865e5c31af7Sopenharmony_ci << Array::inputTypeToString((Array::InputType)array.inputType); 1866e5c31af7Sopenharmony_ci if (array.inputType != Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 && array.inputType != Array::INPUTTYPE_INT_2_10_10_10) 1867e5c31af7Sopenharmony_ci name << array.componentCount; 1868e5c31af7Sopenharmony_ci name 1869e5c31af7Sopenharmony_ci << "_" 1870e5c31af7Sopenharmony_ci << (array.normalize ? "normalized_" : "") 1871e5c31af7Sopenharmony_ci << Array::outputTypeToString(array.outputType) << "_" 1872e5c31af7Sopenharmony_ci << Array::usageTypeToString(array.usage) << "_"; 1873e5c31af7Sopenharmony_ci } 1874e5c31af7Sopenharmony_ci 1875e5c31af7Sopenharmony_ci if (first) 1876e5c31af7Sopenharmony_ci name << "first" << first << "_"; 1877e5c31af7Sopenharmony_ci 1878e5c31af7Sopenharmony_ci switch (primitive) 1879e5c31af7Sopenharmony_ci { 1880e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 1881e5c31af7Sopenharmony_ci name << "quads_"; 1882e5c31af7Sopenharmony_ci break; 1883e5c31af7Sopenharmony_ci case Array::PRIMITIVE_POINTS: 1884e5c31af7Sopenharmony_ci name << "points_"; 1885e5c31af7Sopenharmony_ci break; 1886e5c31af7Sopenharmony_ci 1887e5c31af7Sopenharmony_ci default: 1888e5c31af7Sopenharmony_ci DE_ASSERT(false); 1889e5c31af7Sopenharmony_ci break; 1890e5c31af7Sopenharmony_ci } 1891e5c31af7Sopenharmony_ci 1892e5c31af7Sopenharmony_ci name << drawCount; 1893e5c31af7Sopenharmony_ci 1894e5c31af7Sopenharmony_ci return name.str(); 1895e5c31af7Sopenharmony_ci} 1896e5c31af7Sopenharmony_ci 1897e5c31af7Sopenharmony_cistd::string MultiVertexArrayTest::Spec::getDesc (void) const 1898e5c31af7Sopenharmony_ci{ 1899e5c31af7Sopenharmony_ci std::stringstream desc; 1900e5c31af7Sopenharmony_ci 1901e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < arrays.size(); ++ndx) 1902e5c31af7Sopenharmony_ci { 1903e5c31af7Sopenharmony_ci const ArraySpec& array = arrays[ndx]; 1904e5c31af7Sopenharmony_ci 1905e5c31af7Sopenharmony_ci desc 1906e5c31af7Sopenharmony_ci << "Array " << ndx << ": " 1907e5c31af7Sopenharmony_ci << "Storage in " << Array::storageToString(array.storage) << ", " 1908e5c31af7Sopenharmony_ci << "stride " << array.stride << ", " 1909e5c31af7Sopenharmony_ci << "input datatype " << Array::inputTypeToString((Array::InputType)array.inputType) << ", " 1910e5c31af7Sopenharmony_ci << "input component count " << array.componentCount << ", " 1911e5c31af7Sopenharmony_ci << (array.normalize ? "normalized, " : "") 1912e5c31af7Sopenharmony_ci << "used as " << Array::outputTypeToString(array.outputType) << ", "; 1913e5c31af7Sopenharmony_ci } 1914e5c31af7Sopenharmony_ci 1915e5c31af7Sopenharmony_ci desc 1916e5c31af7Sopenharmony_ci << "drawArrays(), " 1917e5c31af7Sopenharmony_ci << "first " << first << ", " 1918e5c31af7Sopenharmony_ci << drawCount; 1919e5c31af7Sopenharmony_ci 1920e5c31af7Sopenharmony_ci switch (primitive) 1921e5c31af7Sopenharmony_ci { 1922e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 1923e5c31af7Sopenharmony_ci desc << "quads "; 1924e5c31af7Sopenharmony_ci break; 1925e5c31af7Sopenharmony_ci case Array::PRIMITIVE_POINTS: 1926e5c31af7Sopenharmony_ci desc << "points"; 1927e5c31af7Sopenharmony_ci break; 1928e5c31af7Sopenharmony_ci 1929e5c31af7Sopenharmony_ci default: 1930e5c31af7Sopenharmony_ci DE_ASSERT(false); 1931e5c31af7Sopenharmony_ci break; 1932e5c31af7Sopenharmony_ci } 1933e5c31af7Sopenharmony_ci 1934e5c31af7Sopenharmony_ci 1935e5c31af7Sopenharmony_ci return desc.str(); 1936e5c31af7Sopenharmony_ci} 1937e5c31af7Sopenharmony_ci 1938e5c31af7Sopenharmony_ciMultiVertexArrayTest::MultiVertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const Spec& spec, const char* name, const char* desc) 1939e5c31af7Sopenharmony_ci : VertexArrayTest (testCtx, renderCtx, name, desc) 1940e5c31af7Sopenharmony_ci , m_spec (spec) 1941e5c31af7Sopenharmony_ci , m_iteration (0) 1942e5c31af7Sopenharmony_ci{ 1943e5c31af7Sopenharmony_ci} 1944e5c31af7Sopenharmony_ci 1945e5c31af7Sopenharmony_ciMultiVertexArrayTest::~MultiVertexArrayTest (void) 1946e5c31af7Sopenharmony_ci{ 1947e5c31af7Sopenharmony_ci} 1948e5c31af7Sopenharmony_ci 1949e5c31af7Sopenharmony_ciMultiVertexArrayTest::IterateResult MultiVertexArrayTest::iterate (void) 1950e5c31af7Sopenharmony_ci{ 1951e5c31af7Sopenharmony_ci if (m_iteration == 0) 1952e5c31af7Sopenharmony_ci { 1953e5c31af7Sopenharmony_ci const size_t primitiveSize = (m_spec.primitive == Array::PRIMITIVE_TRIANGLES) ? (6) : (1); // in non-indexed draw Triangles means rectangles 1954e5c31af7Sopenharmony_ci float coordScale = 1.0f; 1955e5c31af7Sopenharmony_ci float colorScale = 1.0f; 1956e5c31af7Sopenharmony_ci const bool useVao = m_renderCtx.getType().getProfile() == glu::PROFILE_CORE; 1957e5c31af7Sopenharmony_ci 1958e5c31af7Sopenharmony_ci // Log info 1959e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << m_spec.getDesc() << TestLog::EndMessage; 1960e5c31af7Sopenharmony_ci 1961e5c31af7Sopenharmony_ci // Color and Coord scale 1962e5c31af7Sopenharmony_ci { 1963e5c31af7Sopenharmony_ci // First array is always position 1964e5c31af7Sopenharmony_ci { 1965e5c31af7Sopenharmony_ci Spec::ArraySpec arraySpec = m_spec.arrays[0]; 1966e5c31af7Sopenharmony_ci if (arraySpec.inputType == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10) 1967e5c31af7Sopenharmony_ci { 1968e5c31af7Sopenharmony_ci if (arraySpec.normalize) 1969e5c31af7Sopenharmony_ci coordScale = 1.0f; 1970e5c31af7Sopenharmony_ci else 1971e5c31af7Sopenharmony_ci coordScale = 1.0 / 1024.0; 1972e5c31af7Sopenharmony_ci } 1973e5c31af7Sopenharmony_ci else if (arraySpec.inputType == Array::INPUTTYPE_INT_2_10_10_10) 1974e5c31af7Sopenharmony_ci { 1975e5c31af7Sopenharmony_ci if (arraySpec.normalize) 1976e5c31af7Sopenharmony_ci coordScale = 1.0f; 1977e5c31af7Sopenharmony_ci else 1978e5c31af7Sopenharmony_ci coordScale = 1.0 / 512.0; 1979e5c31af7Sopenharmony_ci } 1980e5c31af7Sopenharmony_ci else 1981e5c31af7Sopenharmony_ci coordScale = (arraySpec.normalize && !inputTypeIsFloatType(arraySpec.inputType) ? 1.0f : float(0.9 / double(arraySpec.max.toFloat()))); 1982e5c31af7Sopenharmony_ci 1983e5c31af7Sopenharmony_ci if (arraySpec.outputType == Array::OUTPUTTYPE_VEC3 || arraySpec.outputType == Array::OUTPUTTYPE_VEC4 1984e5c31af7Sopenharmony_ci || arraySpec.outputType == Array::OUTPUTTYPE_IVEC3 || arraySpec.outputType == Array::OUTPUTTYPE_IVEC4 1985e5c31af7Sopenharmony_ci || arraySpec.outputType == Array::OUTPUTTYPE_UVEC3 || arraySpec.outputType == Array::OUTPUTTYPE_UVEC4) 1986e5c31af7Sopenharmony_ci coordScale = coordScale * 0.5f; 1987e5c31af7Sopenharmony_ci } 1988e5c31af7Sopenharmony_ci 1989e5c31af7Sopenharmony_ci // And other arrays are color-like 1990e5c31af7Sopenharmony_ci for (int arrayNdx = 1; arrayNdx < (int)m_spec.arrays.size(); arrayNdx++) 1991e5c31af7Sopenharmony_ci { 1992e5c31af7Sopenharmony_ci Spec::ArraySpec arraySpec = m_spec.arrays[arrayNdx]; 1993e5c31af7Sopenharmony_ci 1994e5c31af7Sopenharmony_ci colorScale *= (arraySpec.normalize && !inputTypeIsFloatType(arraySpec.inputType) ? 1.0f : float(1.0 / double(arraySpec.max.toFloat()))); 1995e5c31af7Sopenharmony_ci if (arraySpec.outputType == Array::OUTPUTTYPE_VEC4) 1996e5c31af7Sopenharmony_ci colorScale *= (arraySpec.normalize && !inputTypeIsFloatType(arraySpec.inputType) ? 1.0f : float(1.0 / double(arraySpec.max.toFloat()))); 1997e5c31af7Sopenharmony_ci } 1998e5c31af7Sopenharmony_ci } 1999e5c31af7Sopenharmony_ci 2000e5c31af7Sopenharmony_ci // Data 2001e5c31af7Sopenharmony_ci for (int arrayNdx = 0; arrayNdx < (int)m_spec.arrays.size(); arrayNdx++) 2002e5c31af7Sopenharmony_ci { 2003e5c31af7Sopenharmony_ci Spec::ArraySpec arraySpec = m_spec.arrays[arrayNdx]; 2004e5c31af7Sopenharmony_ci const int seed = int(arraySpec.inputType) + 10 * int(arraySpec.outputType) + 100 * int(arraySpec.storage) + 1000 * int(m_spec.primitive) + 10000 * int(arraySpec.usage) + int(m_spec.drawCount) + 12 * int(arraySpec.componentCount) + int(arraySpec.stride) + int(arraySpec.normalize); 2005e5c31af7Sopenharmony_ci const char* data = DE_NULL; 2006e5c31af7Sopenharmony_ci const size_t stride = (arraySpec.stride == 0) ? (arraySpec.componentCount * Array::inputTypeSize(arraySpec.inputType)) : (arraySpec.stride); 2007e5c31af7Sopenharmony_ci const size_t bufferSize = arraySpec.offset + stride * (m_spec.drawCount * primitiveSize - 1) + arraySpec.componentCount * Array::inputTypeSize(arraySpec.inputType); 2008e5c31af7Sopenharmony_ci // Snap values to at least 3x3 grid 2009e5c31af7Sopenharmony_ci const float gridSize = 3.0f / (float)(de::min(m_renderCtx.getRenderTarget().getWidth(), m_renderCtx.getRenderTarget().getHeight()) - 1); 2010e5c31af7Sopenharmony_ci 2011e5c31af7Sopenharmony_ci switch (m_spec.primitive) 2012e5c31af7Sopenharmony_ci { 2013e5c31af7Sopenharmony_ci // case Array::PRIMITIVE_POINTS: 2014e5c31af7Sopenharmony_ci // data = RandomArrayGenerator::generateArray(seed, arraySpec.min, arraySpec.max, arraySpec.count, arraySpec.componentCount, arraySpec.stride, arraySpec.inputType); 2015e5c31af7Sopenharmony_ci // break; 2016e5c31af7Sopenharmony_ci case Array::PRIMITIVE_TRIANGLES: 2017e5c31af7Sopenharmony_ci if (arrayNdx == 0) 2018e5c31af7Sopenharmony_ci { 2019e5c31af7Sopenharmony_ci data = RandomArrayGenerator::generateQuads(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.offset, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max, gridSize); 2020e5c31af7Sopenharmony_ci } 2021e5c31af7Sopenharmony_ci else 2022e5c31af7Sopenharmony_ci { 2023e5c31af7Sopenharmony_ci DE_ASSERT(arraySpec.offset == 0); // \note [jarkko] it just hasn't been implemented 2024e5c31af7Sopenharmony_ci data = RandomArrayGenerator::generatePerQuad(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max); 2025e5c31af7Sopenharmony_ci } 2026e5c31af7Sopenharmony_ci break; 2027e5c31af7Sopenharmony_ci 2028e5c31af7Sopenharmony_ci default: 2029e5c31af7Sopenharmony_ci DE_ASSERT(false); 2030e5c31af7Sopenharmony_ci break; 2031e5c31af7Sopenharmony_ci } 2032e5c31af7Sopenharmony_ci 2033e5c31af7Sopenharmony_ci m_glArrayPack->newArray(arraySpec.storage); 2034e5c31af7Sopenharmony_ci m_rrArrayPack->newArray(arraySpec.storage); 2035e5c31af7Sopenharmony_ci 2036e5c31af7Sopenharmony_ci m_glArrayPack->getArray(arrayNdx)->data(Array::TARGET_ARRAY, (int)bufferSize, data, arraySpec.usage); 2037e5c31af7Sopenharmony_ci m_rrArrayPack->getArray(arrayNdx)->data(Array::TARGET_ARRAY, (int)bufferSize, data, arraySpec.usage); 2038e5c31af7Sopenharmony_ci 2039e5c31af7Sopenharmony_ci m_glArrayPack->getArray(arrayNdx)->bind(arrayNdx, arraySpec.offset, arraySpec.componentCount, arraySpec.inputType, arraySpec.outputType, arraySpec.normalize, arraySpec.stride); 2040e5c31af7Sopenharmony_ci m_rrArrayPack->getArray(arrayNdx)->bind(arrayNdx, arraySpec.offset, arraySpec.componentCount, arraySpec.inputType, arraySpec.outputType, arraySpec.normalize, arraySpec.stride); 2041e5c31af7Sopenharmony_ci 2042e5c31af7Sopenharmony_ci delete [] data; 2043e5c31af7Sopenharmony_ci } 2044e5c31af7Sopenharmony_ci 2045e5c31af7Sopenharmony_ci try 2046e5c31af7Sopenharmony_ci { 2047e5c31af7Sopenharmony_ci m_glArrayPack->render(m_spec.primitive, m_spec.first, m_spec.drawCount * (int)primitiveSize, useVao, coordScale, colorScale); 2048e5c31af7Sopenharmony_ci m_testCtx.touchWatchdog(); 2049e5c31af7Sopenharmony_ci m_rrArrayPack->render(m_spec.primitive, m_spec.first, m_spec.drawCount * (int)primitiveSize, useVao, coordScale, colorScale); 2050e5c31af7Sopenharmony_ci } 2051e5c31af7Sopenharmony_ci catch (glu::Error& err) 2052e5c31af7Sopenharmony_ci { 2053e5c31af7Sopenharmony_ci // GL Errors are ok if the mode is not properly aligned 2054e5c31af7Sopenharmony_ci 2055e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "Got error: " << err.what() << TestLog::EndMessage; 2056e5c31af7Sopenharmony_ci 2057e5c31af7Sopenharmony_ci if (isUnalignedBufferOffsetTest()) 2058e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers."); 2059e5c31af7Sopenharmony_ci else if (isUnalignedBufferStrideTest()) 2060e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride."); 2061e5c31af7Sopenharmony_ci else 2062e5c31af7Sopenharmony_ci throw; 2063e5c31af7Sopenharmony_ci 2064e5c31af7Sopenharmony_ci return STOP; 2065e5c31af7Sopenharmony_ci } 2066e5c31af7Sopenharmony_ci 2067e5c31af7Sopenharmony_ci m_iteration++; 2068e5c31af7Sopenharmony_ci return CONTINUE; 2069e5c31af7Sopenharmony_ci } 2070e5c31af7Sopenharmony_ci else if (m_iteration == 1) 2071e5c31af7Sopenharmony_ci { 2072e5c31af7Sopenharmony_ci compare(); 2073e5c31af7Sopenharmony_ci 2074e5c31af7Sopenharmony_ci if (m_isOk) 2075e5c31af7Sopenharmony_ci { 2076e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2077e5c31af7Sopenharmony_ci } 2078e5c31af7Sopenharmony_ci else 2079e5c31af7Sopenharmony_ci { 2080e5c31af7Sopenharmony_ci if (isUnalignedBufferOffsetTest()) 2081e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers."); 2082e5c31af7Sopenharmony_ci else if (isUnalignedBufferStrideTest()) 2083e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride."); 2084e5c31af7Sopenharmony_ci else 2085e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed."); 2086e5c31af7Sopenharmony_ci } 2087e5c31af7Sopenharmony_ci 2088e5c31af7Sopenharmony_ci m_iteration++; 2089e5c31af7Sopenharmony_ci return STOP; 2090e5c31af7Sopenharmony_ci } 2091e5c31af7Sopenharmony_ci else 2092e5c31af7Sopenharmony_ci { 2093e5c31af7Sopenharmony_ci DE_ASSERT(false); 2094e5c31af7Sopenharmony_ci return STOP; 2095e5c31af7Sopenharmony_ci } 2096e5c31af7Sopenharmony_ci} 2097e5c31af7Sopenharmony_ci 2098e5c31af7Sopenharmony_cibool MultiVertexArrayTest::isUnalignedBufferOffsetTest (void) const 2099e5c31af7Sopenharmony_ci{ 2100e5c31af7Sopenharmony_ci // Buffer offsets should be data type size aligned 2101e5c31af7Sopenharmony_ci for (size_t i = 0; i < m_spec.arrays.size(); ++i) 2102e5c31af7Sopenharmony_ci { 2103e5c31af7Sopenharmony_ci if (m_spec.arrays[i].storage == Array::STORAGE_BUFFER) 2104e5c31af7Sopenharmony_ci { 2105e5c31af7Sopenharmony_ci const bool inputTypePacked = m_spec.arrays[i].inputType == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_spec.arrays[i].inputType == Array::INPUTTYPE_INT_2_10_10_10; 2106e5c31af7Sopenharmony_ci 2107e5c31af7Sopenharmony_ci int dataTypeSize = Array::inputTypeSize(m_spec.arrays[i].inputType); 2108e5c31af7Sopenharmony_ci if (inputTypePacked) 2109e5c31af7Sopenharmony_ci dataTypeSize = 4; 2110e5c31af7Sopenharmony_ci 2111e5c31af7Sopenharmony_ci if (m_spec.arrays[i].offset % dataTypeSize != 0) 2112e5c31af7Sopenharmony_ci return true; 2113e5c31af7Sopenharmony_ci } 2114e5c31af7Sopenharmony_ci } 2115e5c31af7Sopenharmony_ci 2116e5c31af7Sopenharmony_ci return false; 2117e5c31af7Sopenharmony_ci} 2118e5c31af7Sopenharmony_ci 2119e5c31af7Sopenharmony_cibool MultiVertexArrayTest::isUnalignedBufferStrideTest (void) const 2120e5c31af7Sopenharmony_ci{ 2121e5c31af7Sopenharmony_ci // Buffer strides should be data type size aligned 2122e5c31af7Sopenharmony_ci for (size_t i = 0; i < m_spec.arrays.size(); ++i) 2123e5c31af7Sopenharmony_ci { 2124e5c31af7Sopenharmony_ci if (m_spec.arrays[i].storage == Array::STORAGE_BUFFER) 2125e5c31af7Sopenharmony_ci { 2126e5c31af7Sopenharmony_ci const bool inputTypePacked = m_spec.arrays[i].inputType == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_spec.arrays[i].inputType == Array::INPUTTYPE_INT_2_10_10_10; 2127e5c31af7Sopenharmony_ci 2128e5c31af7Sopenharmony_ci int dataTypeSize = Array::inputTypeSize(m_spec.arrays[i].inputType); 2129e5c31af7Sopenharmony_ci if (inputTypePacked) 2130e5c31af7Sopenharmony_ci dataTypeSize = 4; 2131e5c31af7Sopenharmony_ci 2132e5c31af7Sopenharmony_ci if (m_spec.arrays[i].stride % dataTypeSize != 0) 2133e5c31af7Sopenharmony_ci return true; 2134e5c31af7Sopenharmony_ci } 2135e5c31af7Sopenharmony_ci } 2136e5c31af7Sopenharmony_ci 2137e5c31af7Sopenharmony_ci return false; 2138e5c31af7Sopenharmony_ci} 2139e5c31af7Sopenharmony_ci 2140e5c31af7Sopenharmony_ci} // gls 2141e5c31af7Sopenharmony_ci} // deqp 2142