1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.1 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 glProgramUniform*() tests. 22e5c31af7Sopenharmony_ci * 23e5c31af7Sopenharmony_ci * \todo [2013-02-26 nuutti] Much duplication between ES2&3 uniform api 24e5c31af7Sopenharmony_ci * tests and this. Utilities to glshared? 25e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "es31fProgramUniformTests.hpp" 28e5c31af7Sopenharmony_ci#include "gluCallLogWrapper.hpp" 29e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 30e5c31af7Sopenharmony_ci#include "gluVarType.hpp" 31e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 32e5c31af7Sopenharmony_ci#include "gluTextureUtil.hpp" 33e5c31af7Sopenharmony_ci#include "gluTexture.hpp" 34e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp" 35e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 36e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 37e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 38e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 39e5c31af7Sopenharmony_ci#include "deRandom.hpp" 40e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 41e5c31af7Sopenharmony_ci#include "deString.h" 42e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp" 43e5c31af7Sopenharmony_ci#include "deMemory.h" 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 46e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ci#include <set> 49e5c31af7Sopenharmony_ci#include <cstring> 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_ciusing namespace glw; 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_cinamespace deqp 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_cinamespace gles31 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_cinamespace Functional 58e5c31af7Sopenharmony_ci{ 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ciusing std::vector; 61e5c31af7Sopenharmony_ciusing std::string; 62e5c31af7Sopenharmony_ciusing tcu::TestLog; 63e5c31af7Sopenharmony_ciusing tcu::ScopedLogSection; 64e5c31af7Sopenharmony_ciusing glu::ShaderProgram; 65e5c31af7Sopenharmony_ciusing glu::StructType; 66e5c31af7Sopenharmony_ciusing de::Random; 67e5c31af7Sopenharmony_ciusing de::SharedPtr; 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_citypedef bool (* dataTypePredicate)(glu::DataType); 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_cienum 72e5c31af7Sopenharmony_ci{ 73e5c31af7Sopenharmony_ci MAX_RENDER_WIDTH = 32, 74e5c31af7Sopenharmony_ci MAX_RENDER_HEIGHT = 32, 75e5c31af7Sopenharmony_ci MAX_NUM_SAMPLER_UNIFORMS = 16 76e5c31af7Sopenharmony_ci}; 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_cistatic const glu::DataType s_testDataTypes[] = 79e5c31af7Sopenharmony_ci{ 80e5c31af7Sopenharmony_ci glu::TYPE_FLOAT, 81e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_VEC2, 82e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_VEC3, 83e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_VEC4, 84e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT2, 85e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT2X3, 86e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT2X4, 87e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT3X2, 88e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT3, 89e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT3X4, 90e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT4X2, 91e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT4X3, 92e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT4, 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci glu::TYPE_INT, 95e5c31af7Sopenharmony_ci glu::TYPE_INT_VEC2, 96e5c31af7Sopenharmony_ci glu::TYPE_INT_VEC3, 97e5c31af7Sopenharmony_ci glu::TYPE_INT_VEC4, 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci glu::TYPE_UINT, 100e5c31af7Sopenharmony_ci glu::TYPE_UINT_VEC2, 101e5c31af7Sopenharmony_ci glu::TYPE_UINT_VEC3, 102e5c31af7Sopenharmony_ci glu::TYPE_UINT_VEC4, 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci glu::TYPE_BOOL, 105e5c31af7Sopenharmony_ci glu::TYPE_BOOL_VEC2, 106e5c31af7Sopenharmony_ci glu::TYPE_BOOL_VEC3, 107e5c31af7Sopenharmony_ci glu::TYPE_BOOL_VEC4, 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci glu::TYPE_SAMPLER_2D, 110e5c31af7Sopenharmony_ci glu::TYPE_SAMPLER_CUBE 111e5c31af7Sopenharmony_ci // \note We don't test all sampler types here. 112e5c31af7Sopenharmony_ci}; 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_cistatic inline int getGLInt (const glw::Functions& funcs, const deUint32 name) 115e5c31af7Sopenharmony_ci{ 116e5c31af7Sopenharmony_ci int val = -1; 117e5c31af7Sopenharmony_ci funcs.getIntegerv(name, &val); 118e5c31af7Sopenharmony_ci return val; 119e5c31af7Sopenharmony_ci} 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_cistatic inline tcu::Vec4 vec4FromPtr (const float* const ptr) 122e5c31af7Sopenharmony_ci{ 123e5c31af7Sopenharmony_ci tcu::Vec4 result; 124e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 125e5c31af7Sopenharmony_ci result[i] = ptr[i]; 126e5c31af7Sopenharmony_ci return result; 127e5c31af7Sopenharmony_ci} 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_cistatic inline string beforeLast (const string& str, const char c) 130e5c31af7Sopenharmony_ci{ 131e5c31af7Sopenharmony_ci return str.substr(0, str.find_last_of(c)); 132e5c31af7Sopenharmony_ci} 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_cistatic inline void fillWithColor (const tcu::PixelBufferAccess& access, const tcu::Vec4& color) 135e5c31af7Sopenharmony_ci{ 136e5c31af7Sopenharmony_ci for (int z = 0; z < access.getDepth(); z++) 137e5c31af7Sopenharmony_ci for (int y = 0; y < access.getHeight(); y++) 138e5c31af7Sopenharmony_ci for (int x = 0; x < access.getWidth(); x++) 139e5c31af7Sopenharmony_ci access.setPixel(color, x, y, z); 140e5c31af7Sopenharmony_ci} 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_cistatic inline int getSamplerNumLookupDimensions (const glu::DataType type) 143e5c31af7Sopenharmony_ci{ 144e5c31af7Sopenharmony_ci switch (type) 145e5c31af7Sopenharmony_ci { 146e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D: 147e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_2D: 148e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_2D: 149e5c31af7Sopenharmony_ci return 2; 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_3D: 152e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_3D: 153e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_3D: 154e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D_SHADOW: 155e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D_ARRAY: 156e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_2D_ARRAY: 157e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_2D_ARRAY: 158e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_CUBE: 159e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_CUBE: 160e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_CUBE: 161e5c31af7Sopenharmony_ci return 3; 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_CUBE_SHADOW: 164e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW: 165e5c31af7Sopenharmony_ci return 4; 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci default: 168e5c31af7Sopenharmony_ci DE_ASSERT(false); 169e5c31af7Sopenharmony_ci return 0; 170e5c31af7Sopenharmony_ci } 171e5c31af7Sopenharmony_ci} 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_cistatic inline glu::DataType getSamplerLookupReturnType (const glu::DataType type) 174e5c31af7Sopenharmony_ci{ 175e5c31af7Sopenharmony_ci switch (type) 176e5c31af7Sopenharmony_ci { 177e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D: 178e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_CUBE: 179e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D_ARRAY: 180e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_3D: 181e5c31af7Sopenharmony_ci return glu::TYPE_FLOAT_VEC4; 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_2D: 184e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_CUBE: 185e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_2D_ARRAY: 186e5c31af7Sopenharmony_ci case glu::TYPE_UINT_SAMPLER_3D: 187e5c31af7Sopenharmony_ci return glu::TYPE_UINT_VEC4; 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_2D: 190e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_CUBE: 191e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_2D_ARRAY: 192e5c31af7Sopenharmony_ci case glu::TYPE_INT_SAMPLER_3D: 193e5c31af7Sopenharmony_ci return glu::TYPE_INT_VEC4; 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D_SHADOW: 196e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_CUBE_SHADOW: 197e5c31af7Sopenharmony_ci case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW: 198e5c31af7Sopenharmony_ci return glu::TYPE_FLOAT; 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci default: 201e5c31af7Sopenharmony_ci DE_ASSERT(false); 202e5c31af7Sopenharmony_ci return glu::TYPE_LAST; 203e5c31af7Sopenharmony_ci } 204e5c31af7Sopenharmony_ci} 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_citemplate<glu::DataType T> 207e5c31af7Sopenharmony_cistatic bool dataTypeEquals (const glu::DataType t) 208e5c31af7Sopenharmony_ci{ 209e5c31af7Sopenharmony_ci return t == T; 210e5c31af7Sopenharmony_ci} 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_citemplate<int N> 213e5c31af7Sopenharmony_cistatic bool dataTypeIsMatrixWithNRows (const glu::DataType t) 214e5c31af7Sopenharmony_ci{ 215e5c31af7Sopenharmony_ci return glu::isDataTypeMatrix(t) && glu::getDataTypeMatrixNumRows(t) == N; 216e5c31af7Sopenharmony_ci} 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_cistatic bool typeContainsMatchingBasicType (const glu::VarType& type, const dataTypePredicate predicate) 219e5c31af7Sopenharmony_ci{ 220e5c31af7Sopenharmony_ci if (type.isBasicType()) 221e5c31af7Sopenharmony_ci return predicate(type.getBasicType()); 222e5c31af7Sopenharmony_ci else if (type.isArrayType()) 223e5c31af7Sopenharmony_ci return typeContainsMatchingBasicType(type.getElementType(), predicate); 224e5c31af7Sopenharmony_ci else 225e5c31af7Sopenharmony_ci { 226e5c31af7Sopenharmony_ci DE_ASSERT(type.isStructType()); 227e5c31af7Sopenharmony_ci const StructType& structType = *type.getStructPtr(); 228e5c31af7Sopenharmony_ci for (int i = 0; i < structType.getNumMembers(); i++) 229e5c31af7Sopenharmony_ci if (typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate)) 230e5c31af7Sopenharmony_ci return true; 231e5c31af7Sopenharmony_ci return false; 232e5c31af7Sopenharmony_ci } 233e5c31af7Sopenharmony_ci} 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_cistatic void getDistinctSamplerTypes (vector<glu::DataType>& dst, const glu::VarType& type) 236e5c31af7Sopenharmony_ci{ 237e5c31af7Sopenharmony_ci if (type.isBasicType()) 238e5c31af7Sopenharmony_ci { 239e5c31af7Sopenharmony_ci const glu::DataType basicType = type.getBasicType(); 240e5c31af7Sopenharmony_ci if (glu::isDataTypeSampler(basicType) && std::find(dst.begin(), dst.end(), basicType) == dst.end()) 241e5c31af7Sopenharmony_ci dst.push_back(basicType); 242e5c31af7Sopenharmony_ci } 243e5c31af7Sopenharmony_ci else if (type.isArrayType()) 244e5c31af7Sopenharmony_ci getDistinctSamplerTypes(dst, type.getElementType()); 245e5c31af7Sopenharmony_ci else 246e5c31af7Sopenharmony_ci { 247e5c31af7Sopenharmony_ci DE_ASSERT(type.isStructType()); 248e5c31af7Sopenharmony_ci const StructType& structType = *type.getStructPtr(); 249e5c31af7Sopenharmony_ci for (int i = 0; i < structType.getNumMembers(); i++) 250e5c31af7Sopenharmony_ci getDistinctSamplerTypes(dst, structType.getMember(i).getType()); 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci} 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_cistatic int getNumSamplersInType (const glu::VarType& type) 255e5c31af7Sopenharmony_ci{ 256e5c31af7Sopenharmony_ci if (type.isBasicType()) 257e5c31af7Sopenharmony_ci return glu::isDataTypeSampler(type.getBasicType()) ? 1 : 0; 258e5c31af7Sopenharmony_ci else if (type.isArrayType()) 259e5c31af7Sopenharmony_ci return getNumSamplersInType(type.getElementType()) * type.getArraySize(); 260e5c31af7Sopenharmony_ci else 261e5c31af7Sopenharmony_ci { 262e5c31af7Sopenharmony_ci DE_ASSERT(type.isStructType()); 263e5c31af7Sopenharmony_ci const StructType& structType = *type.getStructPtr(); 264e5c31af7Sopenharmony_ci int sum = 0; 265e5c31af7Sopenharmony_ci for (int i = 0; i < structType.getNumMembers(); i++) 266e5c31af7Sopenharmony_ci sum += getNumSamplersInType(structType.getMember(i).getType()); 267e5c31af7Sopenharmony_ci return sum; 268e5c31af7Sopenharmony_ci } 269e5c31af7Sopenharmony_ci} 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_cinamespace 272e5c31af7Sopenharmony_ci{ 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_cistruct VarValue 275e5c31af7Sopenharmony_ci{ 276e5c31af7Sopenharmony_ci glu::DataType type; 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci union 279e5c31af7Sopenharmony_ci { 280e5c31af7Sopenharmony_ci float floatV[4*4]; // At most mat4. \note Matrices here are column-major. 281e5c31af7Sopenharmony_ci deInt32 intV[4]; 282e5c31af7Sopenharmony_ci deUint32 uintV[4]; 283e5c31af7Sopenharmony_ci bool boolV[4]; 284e5c31af7Sopenharmony_ci struct 285e5c31af7Sopenharmony_ci { 286e5c31af7Sopenharmony_ci int unit; 287e5c31af7Sopenharmony_ci union 288e5c31af7Sopenharmony_ci { 289e5c31af7Sopenharmony_ci float floatV[4]; 290e5c31af7Sopenharmony_ci deInt32 intV[4]; 291e5c31af7Sopenharmony_ci deUint32 uintV[4]; 292e5c31af7Sopenharmony_ci } fillColor; 293e5c31af7Sopenharmony_ci } samplerV; 294e5c31af7Sopenharmony_ci } val; 295e5c31af7Sopenharmony_ci}; 296e5c31af7Sopenharmony_ci 297e5c31af7Sopenharmony_cienum CaseShaderType 298e5c31af7Sopenharmony_ci{ 299e5c31af7Sopenharmony_ci CASESHADERTYPE_VERTEX = 0, 300e5c31af7Sopenharmony_ci CASESHADERTYPE_FRAGMENT, 301e5c31af7Sopenharmony_ci CASESHADERTYPE_BOTH, 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci CASESHADERTYPE_LAST 304e5c31af7Sopenharmony_ci}; 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_cistruct Uniform 307e5c31af7Sopenharmony_ci{ 308e5c31af7Sopenharmony_ci string name; 309e5c31af7Sopenharmony_ci glu::VarType type; 310e5c31af7Sopenharmony_ci 311e5c31af7Sopenharmony_ci Uniform (const char* const name_, const glu::VarType& type_) : name(name_), type(type_) {} 312e5c31af7Sopenharmony_ci}; 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci// A set of uniforms, along with related struct types. 315e5c31af7Sopenharmony_ciclass UniformCollection 316e5c31af7Sopenharmony_ci{ 317e5c31af7Sopenharmony_cipublic: 318e5c31af7Sopenharmony_ci int getNumUniforms (void) const { return (int)m_uniforms.size(); } 319e5c31af7Sopenharmony_ci int getNumStructTypes (void) const { return (int)m_structTypes.size(); } 320e5c31af7Sopenharmony_ci Uniform& getUniform (const int ndx) { return m_uniforms[ndx]; } 321e5c31af7Sopenharmony_ci const Uniform& getUniform (const int ndx) const { return m_uniforms[ndx]; } 322e5c31af7Sopenharmony_ci const StructType* getStructType (const int ndx) const { return m_structTypes[ndx]; } 323e5c31af7Sopenharmony_ci void addUniform (const Uniform& uniform) { m_uniforms.push_back(uniform); } 324e5c31af7Sopenharmony_ci void addStructType (const StructType* const type) { m_structTypes.push_back(type); } 325e5c31af7Sopenharmony_ci 326e5c31af7Sopenharmony_ci UniformCollection (void) {} 327e5c31af7Sopenharmony_ci ~UniformCollection (void) 328e5c31af7Sopenharmony_ci { 329e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_structTypes.size(); i++) 330e5c31af7Sopenharmony_ci delete m_structTypes[i]; 331e5c31af7Sopenharmony_ci } 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_ci // Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one. 334e5c31af7Sopenharmony_ci // \note receiver takes ownership of the struct types. 335e5c31af7Sopenharmony_ci void moveContents (UniformCollection& receiver) 336e5c31af7Sopenharmony_ci { 337e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_uniforms.size(); i++) 338e5c31af7Sopenharmony_ci receiver.addUniform(m_uniforms[i]); 339e5c31af7Sopenharmony_ci m_uniforms.clear(); 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_structTypes.size(); i++) 342e5c31af7Sopenharmony_ci receiver.addStructType(m_structTypes[i]); 343e5c31af7Sopenharmony_ci m_structTypes.clear(); 344e5c31af7Sopenharmony_ci } 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci bool containsMatchingBasicType (const dataTypePredicate predicate) const 347e5c31af7Sopenharmony_ci { 348e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_uniforms.size(); i++) 349e5c31af7Sopenharmony_ci if (typeContainsMatchingBasicType(m_uniforms[i].type, predicate)) 350e5c31af7Sopenharmony_ci return true; 351e5c31af7Sopenharmony_ci return false; 352e5c31af7Sopenharmony_ci } 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_ci vector<glu::DataType> getSamplerTypes (void) const 355e5c31af7Sopenharmony_ci { 356e5c31af7Sopenharmony_ci vector<glu::DataType> samplerTypes; 357e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_uniforms.size(); i++) 358e5c31af7Sopenharmony_ci getDistinctSamplerTypes(samplerTypes, m_uniforms[i].type); 359e5c31af7Sopenharmony_ci return samplerTypes; 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci bool containsSeveralSamplerTypes (void) const 363e5c31af7Sopenharmony_ci { 364e5c31af7Sopenharmony_ci return getSamplerTypes().size() > 1; 365e5c31af7Sopenharmony_ci } 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci int getNumSamplers (void) const 368e5c31af7Sopenharmony_ci { 369e5c31af7Sopenharmony_ci int sum = 0; 370e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_uniforms.size(); i++) 371e5c31af7Sopenharmony_ci sum += getNumSamplersInType(m_uniforms[i].type); 372e5c31af7Sopenharmony_ci return sum; 373e5c31af7Sopenharmony_ci } 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci static UniformCollection* basic (const glu::DataType type, const char* const nameSuffix = "") 376e5c31af7Sopenharmony_ci { 377e5c31af7Sopenharmony_ci UniformCollection* const res = new UniformCollection; 378e5c31af7Sopenharmony_ci const glu::Precision prec = glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP; 379e5c31af7Sopenharmony_ci res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(type, prec))); 380e5c31af7Sopenharmony_ci return res; 381e5c31af7Sopenharmony_ci } 382e5c31af7Sopenharmony_ci 383e5c31af7Sopenharmony_ci static UniformCollection* basicArray (const glu::DataType type, const char* const nameSuffix = "") 384e5c31af7Sopenharmony_ci { 385e5c31af7Sopenharmony_ci UniformCollection* const res = new UniformCollection; 386e5c31af7Sopenharmony_ci const glu::Precision prec = glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP; 387e5c31af7Sopenharmony_ci res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(glu::VarType(type, prec), 3))); 388e5c31af7Sopenharmony_ci return res; 389e5c31af7Sopenharmony_ci } 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_ci static UniformCollection* basicStruct (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "") 392e5c31af7Sopenharmony_ci { 393e5c31af7Sopenharmony_ci UniformCollection* const res = new UniformCollection; 394e5c31af7Sopenharmony_ci const glu::Precision prec0 = glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP; 395e5c31af7Sopenharmony_ci const glu::Precision prec1 = glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP; 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci StructType* const structType = new StructType((string("structType") + nameSuffix).c_str()); 398e5c31af7Sopenharmony_ci structType->addMember("m0", glu::VarType(type0, prec0)); 399e5c31af7Sopenharmony_ci structType->addMember("m1", glu::VarType(type1, prec1)); 400e5c31af7Sopenharmony_ci if (containsArrays) 401e5c31af7Sopenharmony_ci { 402e5c31af7Sopenharmony_ci structType->addMember("m2", glu::VarType(glu::VarType(type0, prec0), 3)); 403e5c31af7Sopenharmony_ci structType->addMember("m3", glu::VarType(glu::VarType(type1, prec1), 3)); 404e5c31af7Sopenharmony_ci } 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci res->addStructType(structType); 407e5c31af7Sopenharmony_ci res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType))); 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ci return res; 410e5c31af7Sopenharmony_ci } 411e5c31af7Sopenharmony_ci 412e5c31af7Sopenharmony_ci static UniformCollection* structInArray (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "") 413e5c31af7Sopenharmony_ci { 414e5c31af7Sopenharmony_ci UniformCollection* const res = basicStruct(type0, type1, containsArrays, nameSuffix); 415e5c31af7Sopenharmony_ci res->getUniform(0).type = glu::VarType(res->getUniform(0).type, 3); 416e5c31af7Sopenharmony_ci return res; 417e5c31af7Sopenharmony_ci } 418e5c31af7Sopenharmony_ci 419e5c31af7Sopenharmony_ci static UniformCollection* nestedArraysStructs (const glu::DataType type0, const glu::DataType type1, const char* const nameSuffix = "") 420e5c31af7Sopenharmony_ci { 421e5c31af7Sopenharmony_ci UniformCollection* const res = new UniformCollection; 422e5c31af7Sopenharmony_ci const glu::Precision prec0 = glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP; 423e5c31af7Sopenharmony_ci const glu::Precision prec1 = glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP; 424e5c31af7Sopenharmony_ci StructType* const structType = new StructType((string("structType") + nameSuffix).c_str()); 425e5c31af7Sopenharmony_ci StructType* const subStructType = new StructType((string("subStructType") + nameSuffix).c_str()); 426e5c31af7Sopenharmony_ci StructType* const subSubStructType = new StructType((string("subSubStructType") + nameSuffix).c_str()); 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci subSubStructType->addMember("mss0", glu::VarType(type0, prec0)); 429e5c31af7Sopenharmony_ci subSubStructType->addMember("mss1", glu::VarType(type1, prec1)); 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci subStructType->addMember("ms0", glu::VarType(type1, prec1)); 432e5c31af7Sopenharmony_ci subStructType->addMember("ms1", glu::VarType(glu::VarType(type0, prec0), 2)); 433e5c31af7Sopenharmony_ci subStructType->addMember("ms2", glu::VarType(glu::VarType(subSubStructType), 2)); 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci structType->addMember("m0", glu::VarType(type0, prec0)); 436e5c31af7Sopenharmony_ci structType->addMember("m1", glu::VarType(subStructType)); 437e5c31af7Sopenharmony_ci structType->addMember("m2", glu::VarType(type1, prec1)); 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_ci res->addStructType(subSubStructType); 440e5c31af7Sopenharmony_ci res->addStructType(subStructType); 441e5c31af7Sopenharmony_ci res->addStructType(structType); 442e5c31af7Sopenharmony_ci 443e5c31af7Sopenharmony_ci res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType))); 444e5c31af7Sopenharmony_ci 445e5c31af7Sopenharmony_ci return res; 446e5c31af7Sopenharmony_ci } 447e5c31af7Sopenharmony_ci 448e5c31af7Sopenharmony_ci static UniformCollection* multipleBasic (const char* const nameSuffix = "") 449e5c31af7Sopenharmony_ci { 450e5c31af7Sopenharmony_ci static const glu::DataType types[] = { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_UINT_VEC4, glu::TYPE_FLOAT_MAT3, glu::TYPE_BOOL_VEC2 }; 451e5c31af7Sopenharmony_ci UniformCollection* const res = new UniformCollection; 452e5c31af7Sopenharmony_ci 453e5c31af7Sopenharmony_ci for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++) 454e5c31af7Sopenharmony_ci { 455e5c31af7Sopenharmony_ci UniformCollection* const sub = basic(types[i], ("_" + de::toString(i) + nameSuffix).c_str()); 456e5c31af7Sopenharmony_ci sub->moveContents(*res); 457e5c31af7Sopenharmony_ci delete sub; 458e5c31af7Sopenharmony_ci } 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_ci return res; 461e5c31af7Sopenharmony_ci } 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci static UniformCollection* multipleBasicArray (const char* const nameSuffix = "") 464e5c31af7Sopenharmony_ci { 465e5c31af7Sopenharmony_ci static const glu::DataType types[] = { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_BOOL_VEC2 }; 466e5c31af7Sopenharmony_ci UniformCollection* const res = new UniformCollection; 467e5c31af7Sopenharmony_ci 468e5c31af7Sopenharmony_ci for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++) 469e5c31af7Sopenharmony_ci { 470e5c31af7Sopenharmony_ci UniformCollection* const sub = basicArray(types[i], ("_" + de::toString(i) + nameSuffix).c_str()); 471e5c31af7Sopenharmony_ci sub->moveContents(*res); 472e5c31af7Sopenharmony_ci delete sub; 473e5c31af7Sopenharmony_ci } 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_ci return res; 476e5c31af7Sopenharmony_ci } 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_ci static UniformCollection* multipleNestedArraysStructs (const char* const nameSuffix = "") 479e5c31af7Sopenharmony_ci { 480e5c31af7Sopenharmony_ci static const glu::DataType types0[] = { glu::TYPE_FLOAT, glu::TYPE_INT, glu::TYPE_BOOL_VEC4 }; 481e5c31af7Sopenharmony_ci static const glu::DataType types1[] = { glu::TYPE_FLOAT_VEC4, glu::TYPE_INT_VEC4, glu::TYPE_BOOL }; 482e5c31af7Sopenharmony_ci UniformCollection* const res = new UniformCollection; 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types0) == DE_LENGTH_OF_ARRAY(types1)); 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci for (int i = 0; i < DE_LENGTH_OF_ARRAY(types0); i++) 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci UniformCollection* const sub = nestedArraysStructs(types0[i], types1[i], ("_" + de::toString(i) + nameSuffix).c_str()); 489e5c31af7Sopenharmony_ci sub->moveContents(*res); 490e5c31af7Sopenharmony_ci delete sub; 491e5c31af7Sopenharmony_ci } 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci return res; 494e5c31af7Sopenharmony_ci } 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ciprivate: 497e5c31af7Sopenharmony_ci // \note Copying these would be cumbersome, since deep-copying both m_uniforms and m_structTypes 498e5c31af7Sopenharmony_ci // would mean that we'd need to update pointers from uniforms to point to the new structTypes. 499e5c31af7Sopenharmony_ci // When the same UniformCollection is needed in several places, a SharedPtr is used instead. 500e5c31af7Sopenharmony_ci UniformCollection (const UniformCollection&); // Not allowed. 501e5c31af7Sopenharmony_ci UniformCollection& operator= (const UniformCollection&); // Not allowed. 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci vector<Uniform> m_uniforms; 504e5c31af7Sopenharmony_ci vector<const StructType*> m_structTypes; 505e5c31af7Sopenharmony_ci}; 506e5c31af7Sopenharmony_ci 507e5c31af7Sopenharmony_ci} // anonymous 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_cistatic VarValue getSamplerFillValue (const VarValue& sampler) 510e5c31af7Sopenharmony_ci{ 511e5c31af7Sopenharmony_ci DE_ASSERT(glu::isDataTypeSampler(sampler.type)); 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci VarValue result; 514e5c31af7Sopenharmony_ci result.type = getSamplerLookupReturnType(sampler.type); 515e5c31af7Sopenharmony_ci 516e5c31af7Sopenharmony_ci switch (result.type) 517e5c31af7Sopenharmony_ci { 518e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_VEC4: 519e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 520e5c31af7Sopenharmony_ci result.val.floatV[i] = sampler.val.samplerV.fillColor.floatV[i]; 521e5c31af7Sopenharmony_ci break; 522e5c31af7Sopenharmony_ci case glu::TYPE_UINT_VEC4: 523e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 524e5c31af7Sopenharmony_ci result.val.uintV[i] = sampler.val.samplerV.fillColor.uintV[i]; 525e5c31af7Sopenharmony_ci break; 526e5c31af7Sopenharmony_ci case glu::TYPE_INT_VEC4: 527e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 528e5c31af7Sopenharmony_ci result.val.intV[i] = sampler.val.samplerV.fillColor.intV[i]; 529e5c31af7Sopenharmony_ci break; 530e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT: 531e5c31af7Sopenharmony_ci result.val.floatV[0] = sampler.val.samplerV.fillColor.floatV[0]; 532e5c31af7Sopenharmony_ci break; 533e5c31af7Sopenharmony_ci default: 534e5c31af7Sopenharmony_ci DE_ASSERT(false); 535e5c31af7Sopenharmony_ci } 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_ci return result; 538e5c31af7Sopenharmony_ci} 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_cistatic VarValue getSamplerUnitValue (const VarValue& sampler) 541e5c31af7Sopenharmony_ci{ 542e5c31af7Sopenharmony_ci DE_ASSERT(glu::isDataTypeSampler(sampler.type)); 543e5c31af7Sopenharmony_ci 544e5c31af7Sopenharmony_ci VarValue result; 545e5c31af7Sopenharmony_ci result.type = glu::TYPE_INT; 546e5c31af7Sopenharmony_ci result.val.intV[0] = sampler.val.samplerV.unit; 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci return result; 549e5c31af7Sopenharmony_ci} 550e5c31af7Sopenharmony_ci 551e5c31af7Sopenharmony_cistatic glu::DataType getDataTypeTransposedMatrix (const glu::DataType original) 552e5c31af7Sopenharmony_ci{ 553e5c31af7Sopenharmony_ci return glu::getDataTypeMatrix(glu::getDataTypeMatrixNumRows(original), glu::getDataTypeMatrixNumColumns(original)); 554e5c31af7Sopenharmony_ci} 555e5c31af7Sopenharmony_ci 556e5c31af7Sopenharmony_cistatic VarValue getTransposeMatrix (const VarValue& original) 557e5c31af7Sopenharmony_ci{ 558e5c31af7Sopenharmony_ci DE_ASSERT(glu::isDataTypeMatrix(original.type)); 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci const int rows = glu::getDataTypeMatrixNumRows(original.type); 561e5c31af7Sopenharmony_ci const int cols = glu::getDataTypeMatrixNumColumns(original.type); 562e5c31af7Sopenharmony_ci VarValue result; 563e5c31af7Sopenharmony_ci result.type = getDataTypeTransposedMatrix(original.type); 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ci for (int i = 0; i < rows; i++) 566e5c31af7Sopenharmony_ci for (int j = 0; j < cols; j++) 567e5c31af7Sopenharmony_ci result.val.floatV[i*cols + j] = original.val.floatV[j*rows + i]; 568e5c31af7Sopenharmony_ci 569e5c31af7Sopenharmony_ci return result; 570e5c31af7Sopenharmony_ci} 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_cistatic string shaderVarValueStr (const VarValue& value) 573e5c31af7Sopenharmony_ci{ 574e5c31af7Sopenharmony_ci const int numElems = glu::getDataTypeScalarSize(value.type); 575e5c31af7Sopenharmony_ci std::ostringstream result; 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ci if (numElems > 1) 578e5c31af7Sopenharmony_ci result << glu::getDataTypeName(value.type) << "("; 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci for (int i = 0; i < numElems; i++) 581e5c31af7Sopenharmony_ci { 582e5c31af7Sopenharmony_ci if (i > 0) 583e5c31af7Sopenharmony_ci result << ", "; 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type)) 586e5c31af7Sopenharmony_ci result << de::floatToString(value.val.floatV[i], 2); 587e5c31af7Sopenharmony_ci else if (glu::isDataTypeIntOrIVec((value.type))) 588e5c31af7Sopenharmony_ci result << de::toString(value.val.intV[i]); 589e5c31af7Sopenharmony_ci else if (glu::isDataTypeUintOrUVec((value.type))) 590e5c31af7Sopenharmony_ci result << de::toString(value.val.uintV[i]) << "u"; 591e5c31af7Sopenharmony_ci else if (glu::isDataTypeBoolOrBVec((value.type))) 592e5c31af7Sopenharmony_ci result << (value.val.boolV[i] ? "true" : "false"); 593e5c31af7Sopenharmony_ci else if (glu::isDataTypeSampler((value.type))) 594e5c31af7Sopenharmony_ci result << shaderVarValueStr(getSamplerFillValue(value)); 595e5c31af7Sopenharmony_ci else 596e5c31af7Sopenharmony_ci DE_ASSERT(false); 597e5c31af7Sopenharmony_ci } 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_ci if (numElems > 1) 600e5c31af7Sopenharmony_ci result << ")"; 601e5c31af7Sopenharmony_ci 602e5c31af7Sopenharmony_ci return result.str(); 603e5c31af7Sopenharmony_ci} 604e5c31af7Sopenharmony_ci 605e5c31af7Sopenharmony_cistatic string apiVarValueStr (const VarValue& value) 606e5c31af7Sopenharmony_ci{ 607e5c31af7Sopenharmony_ci const int numElems = glu::getDataTypeScalarSize(value.type); 608e5c31af7Sopenharmony_ci std::ostringstream result; 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ci if (numElems > 1) 611e5c31af7Sopenharmony_ci result << "("; 612e5c31af7Sopenharmony_ci 613e5c31af7Sopenharmony_ci for (int i = 0; i < numElems; i++) 614e5c31af7Sopenharmony_ci { 615e5c31af7Sopenharmony_ci if (i > 0) 616e5c31af7Sopenharmony_ci result << ", "; 617e5c31af7Sopenharmony_ci 618e5c31af7Sopenharmony_ci if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type)) 619e5c31af7Sopenharmony_ci result << de::floatToString(value.val.floatV[i], 2); 620e5c31af7Sopenharmony_ci else if (glu::isDataTypeIntOrIVec((value.type))) 621e5c31af7Sopenharmony_ci result << de::toString(value.val.intV[i]); 622e5c31af7Sopenharmony_ci else if (glu::isDataTypeUintOrUVec((value.type))) 623e5c31af7Sopenharmony_ci result << de::toString(value.val.uintV[i]); 624e5c31af7Sopenharmony_ci else if (glu::isDataTypeBoolOrBVec((value.type))) 625e5c31af7Sopenharmony_ci result << (value.val.boolV[i] ? "true" : "false"); 626e5c31af7Sopenharmony_ci else if (glu::isDataTypeSampler((value.type))) 627e5c31af7Sopenharmony_ci result << value.val.samplerV.unit; 628e5c31af7Sopenharmony_ci else 629e5c31af7Sopenharmony_ci DE_ASSERT(false); 630e5c31af7Sopenharmony_ci } 631e5c31af7Sopenharmony_ci 632e5c31af7Sopenharmony_ci if (numElems > 1) 633e5c31af7Sopenharmony_ci result << ")"; 634e5c31af7Sopenharmony_ci 635e5c31af7Sopenharmony_ci return result.str(); 636e5c31af7Sopenharmony_ci} 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_cistatic VarValue generateRandomVarValue (const glu::DataType type, Random& rnd, int samplerUnit = -1 /* Used if type is a sampler type. \note Samplers' unit numbers are not randomized. */) 639e5c31af7Sopenharmony_ci{ 640e5c31af7Sopenharmony_ci const int numElems = glu::getDataTypeScalarSize(type); 641e5c31af7Sopenharmony_ci VarValue result; 642e5c31af7Sopenharmony_ci result.type = type; 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci DE_ASSERT((samplerUnit >= 0) == (glu::isDataTypeSampler(type))); 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type)) 647e5c31af7Sopenharmony_ci { 648e5c31af7Sopenharmony_ci for (int i = 0; i < numElems; i++) 649e5c31af7Sopenharmony_ci result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f); 650e5c31af7Sopenharmony_ci } 651e5c31af7Sopenharmony_ci else if (glu::isDataTypeIntOrIVec(type)) 652e5c31af7Sopenharmony_ci { 653e5c31af7Sopenharmony_ci for (int i = 0; i < numElems; i++) 654e5c31af7Sopenharmony_ci result.val.intV[i] = rnd.getInt(-10, 10); 655e5c31af7Sopenharmony_ci } 656e5c31af7Sopenharmony_ci else if (glu::isDataTypeUintOrUVec(type)) 657e5c31af7Sopenharmony_ci { 658e5c31af7Sopenharmony_ci for (int i = 0; i < numElems; i++) 659e5c31af7Sopenharmony_ci result.val.uintV[i] = (deUint32)rnd.getInt(0, 10); 660e5c31af7Sopenharmony_ci } 661e5c31af7Sopenharmony_ci else if (glu::isDataTypeBoolOrBVec(type)) 662e5c31af7Sopenharmony_ci { 663e5c31af7Sopenharmony_ci for (int i = 0; i < numElems; i++) 664e5c31af7Sopenharmony_ci result.val.boolV[i] = rnd.getBool(); 665e5c31af7Sopenharmony_ci } 666e5c31af7Sopenharmony_ci else if (glu::isDataTypeSampler(type)) 667e5c31af7Sopenharmony_ci { 668e5c31af7Sopenharmony_ci const glu::DataType texResultType = getSamplerLookupReturnType(type); 669e5c31af7Sopenharmony_ci const glu::DataType texResultScalarType = glu::getDataTypeScalarType(texResultType); 670e5c31af7Sopenharmony_ci const int texResultNumDims = glu::getDataTypeScalarSize(texResultType); 671e5c31af7Sopenharmony_ci 672e5c31af7Sopenharmony_ci result.val.samplerV.unit = samplerUnit; 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_ci for (int i = 0; i < texResultNumDims; i++) 675e5c31af7Sopenharmony_ci { 676e5c31af7Sopenharmony_ci switch (texResultScalarType) 677e5c31af7Sopenharmony_ci { 678e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT: result.val.samplerV.fillColor.floatV[i] = rnd.getFloat(0.0f, 1.0f); break; 679e5c31af7Sopenharmony_ci case glu::TYPE_INT: result.val.samplerV.fillColor.intV[i] = rnd.getInt(-10, 10); break; 680e5c31af7Sopenharmony_ci case glu::TYPE_UINT: result.val.samplerV.fillColor.uintV[i] = (deUint32)rnd.getInt(0, 10); break; 681e5c31af7Sopenharmony_ci default: 682e5c31af7Sopenharmony_ci DE_ASSERT(false); 683e5c31af7Sopenharmony_ci } 684e5c31af7Sopenharmony_ci } 685e5c31af7Sopenharmony_ci } 686e5c31af7Sopenharmony_ci else 687e5c31af7Sopenharmony_ci DE_ASSERT(false); 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ci return result; 690e5c31af7Sopenharmony_ci} 691e5c31af7Sopenharmony_ci 692e5c31af7Sopenharmony_cistatic bool apiVarValueEquals (const VarValue& a, const VarValue& b) 693e5c31af7Sopenharmony_ci{ 694e5c31af7Sopenharmony_ci const int size = glu::getDataTypeScalarSize(a.type); 695e5c31af7Sopenharmony_ci const float floatThreshold = 0.05f; 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ci DE_ASSERT(a.type == b.type); 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci if (glu::isDataTypeFloatOrVec(a.type) || glu::isDataTypeMatrix(a.type)) 700e5c31af7Sopenharmony_ci { 701e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 702e5c31af7Sopenharmony_ci if (de::abs(a.val.floatV[i] - b.val.floatV[i]) >= floatThreshold) 703e5c31af7Sopenharmony_ci return false; 704e5c31af7Sopenharmony_ci } 705e5c31af7Sopenharmony_ci else if (glu::isDataTypeIntOrIVec(a.type)) 706e5c31af7Sopenharmony_ci { 707e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 708e5c31af7Sopenharmony_ci if (a.val.intV[i] != b.val.intV[i]) 709e5c31af7Sopenharmony_ci return false; 710e5c31af7Sopenharmony_ci } 711e5c31af7Sopenharmony_ci else if (glu::isDataTypeUintOrUVec(a.type)) 712e5c31af7Sopenharmony_ci { 713e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 714e5c31af7Sopenharmony_ci if (a.val.uintV[i] != b.val.uintV[i]) 715e5c31af7Sopenharmony_ci return false; 716e5c31af7Sopenharmony_ci } 717e5c31af7Sopenharmony_ci else if (glu::isDataTypeBoolOrBVec(a.type)) 718e5c31af7Sopenharmony_ci { 719e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 720e5c31af7Sopenharmony_ci if (a.val.boolV[i] != b.val.boolV[i]) 721e5c31af7Sopenharmony_ci return false; 722e5c31af7Sopenharmony_ci } 723e5c31af7Sopenharmony_ci else if (glu::isDataTypeSampler(a.type)) 724e5c31af7Sopenharmony_ci { 725e5c31af7Sopenharmony_ci if (a.val.samplerV.unit != b.val.samplerV.unit) 726e5c31af7Sopenharmony_ci return false; 727e5c31af7Sopenharmony_ci } 728e5c31af7Sopenharmony_ci else 729e5c31af7Sopenharmony_ci DE_ASSERT(false); 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ci return true; 732e5c31af7Sopenharmony_ci} 733e5c31af7Sopenharmony_ci 734e5c31af7Sopenharmony_cistatic VarValue getRandomBoolRepresentation (const VarValue& boolValue, const glu::DataType targetScalarType, Random& rnd) 735e5c31af7Sopenharmony_ci{ 736e5c31af7Sopenharmony_ci DE_ASSERT(glu::isDataTypeBoolOrBVec(boolValue.type)); 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ci const int size = glu::getDataTypeScalarSize(boolValue.type); 739e5c31af7Sopenharmony_ci const glu::DataType targetType = size == 1 ? targetScalarType : glu::getDataTypeVector(targetScalarType, size); 740e5c31af7Sopenharmony_ci VarValue result; 741e5c31af7Sopenharmony_ci result.type = targetType; 742e5c31af7Sopenharmony_ci 743e5c31af7Sopenharmony_ci switch (targetScalarType) 744e5c31af7Sopenharmony_ci { 745e5c31af7Sopenharmony_ci case glu::TYPE_INT: 746e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 747e5c31af7Sopenharmony_ci { 748e5c31af7Sopenharmony_ci if (boolValue.val.boolV[i]) 749e5c31af7Sopenharmony_ci { 750e5c31af7Sopenharmony_ci result.val.intV[i] = rnd.getInt(-10, 10); 751e5c31af7Sopenharmony_ci if (result.val.intV[i] == 0) 752e5c31af7Sopenharmony_ci result.val.intV[i] = 1; 753e5c31af7Sopenharmony_ci } 754e5c31af7Sopenharmony_ci else 755e5c31af7Sopenharmony_ci result.val.intV[i] = 0; 756e5c31af7Sopenharmony_ci } 757e5c31af7Sopenharmony_ci break; 758e5c31af7Sopenharmony_ci 759e5c31af7Sopenharmony_ci case glu::TYPE_UINT: 760e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 761e5c31af7Sopenharmony_ci { 762e5c31af7Sopenharmony_ci if (boolValue.val.boolV[i]) 763e5c31af7Sopenharmony_ci result.val.uintV[i] = rnd.getInt(1, 10); 764e5c31af7Sopenharmony_ci else 765e5c31af7Sopenharmony_ci result.val.uintV[i] = 0; 766e5c31af7Sopenharmony_ci } 767e5c31af7Sopenharmony_ci break; 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT: 770e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 771e5c31af7Sopenharmony_ci { 772e5c31af7Sopenharmony_ci if (boolValue.val.boolV[i]) 773e5c31af7Sopenharmony_ci { 774e5c31af7Sopenharmony_ci result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f); 775e5c31af7Sopenharmony_ci if (result.val.floatV[i] == 0.0f) 776e5c31af7Sopenharmony_ci result.val.floatV[i] = 1.0f; 777e5c31af7Sopenharmony_ci } 778e5c31af7Sopenharmony_ci else 779e5c31af7Sopenharmony_ci result.val.floatV[i] = 0; 780e5c31af7Sopenharmony_ci } 781e5c31af7Sopenharmony_ci break; 782e5c31af7Sopenharmony_ci 783e5c31af7Sopenharmony_ci default: 784e5c31af7Sopenharmony_ci DE_ASSERT(false); 785e5c31af7Sopenharmony_ci } 786e5c31af7Sopenharmony_ci 787e5c31af7Sopenharmony_ci return result; 788e5c31af7Sopenharmony_ci} 789e5c31af7Sopenharmony_ci 790e5c31af7Sopenharmony_cistatic const char* getCaseShaderTypeName (const CaseShaderType type) 791e5c31af7Sopenharmony_ci{ 792e5c31af7Sopenharmony_ci switch (type) 793e5c31af7Sopenharmony_ci { 794e5c31af7Sopenharmony_ci case CASESHADERTYPE_VERTEX: return "vertex"; 795e5c31af7Sopenharmony_ci case CASESHADERTYPE_FRAGMENT: return "fragment"; 796e5c31af7Sopenharmony_ci case CASESHADERTYPE_BOTH: return "both"; 797e5c31af7Sopenharmony_ci default: 798e5c31af7Sopenharmony_ci DE_ASSERT(false); 799e5c31af7Sopenharmony_ci return DE_NULL; 800e5c31af7Sopenharmony_ci } 801e5c31af7Sopenharmony_ci} 802e5c31af7Sopenharmony_ci 803e5c31af7Sopenharmony_ciclass UniformCase : public TestCase, protected glu::CallLogWrapper 804e5c31af7Sopenharmony_ci{ 805e5c31af7Sopenharmony_cipublic: 806e5c31af7Sopenharmony_ci enum Feature 807e5c31af7Sopenharmony_ci { 808e5c31af7Sopenharmony_ci // ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices. 809e5c31af7Sopenharmony_ci FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX = 1<<0, 810e5c31af7Sopenharmony_ci 811e5c31af7Sopenharmony_ci // UNIFORMFUNC_VALUE: use pass-by-value versions of uniform assignment funcs, e.g. glProgramUniform1f(), where possible. If not given, use pass-by-pointer versions. 812e5c31af7Sopenharmony_ci FEATURE_UNIFORMFUNC_VALUE = 1<<1, 813e5c31af7Sopenharmony_ci 814e5c31af7Sopenharmony_ci // MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major. 815e5c31af7Sopenharmony_ci FEATURE_MATRIXMODE_ROWMAJOR = 1<<2, 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci // ARRAYASSIGN: how basic-type arrays are assigned with glProgramUniform*(). If none given, assign each element of an array separately. 818e5c31af7Sopenharmony_ci FEATURE_ARRAYASSIGN_FULL = 1<<3, //!< Assign all elements of an array with one glProgramUniform*(). 819e5c31af7Sopenharmony_ci FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO = 1<<4, //!< Assign two elements per one glProgramUniform*(). 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ci // UNIFORMUSAGE_EVERY_OTHER: use about half of the uniforms. If not given, use all uniforms (except that some array indices may be omitted according to ARRAYUSAGE). 822e5c31af7Sopenharmony_ci FEATURE_UNIFORMUSAGE_EVERY_OTHER = 1<<5, 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci // BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float. 825e5c31af7Sopenharmony_ci FEATURE_BOOLEANAPITYPE_INT = 1<<6, 826e5c31af7Sopenharmony_ci FEATURE_BOOLEANAPITYPE_UINT = 1<<7, 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci // ARRAY_FIRST_ELEM_NAME_NO_INDEX: in certain API functions, when referring to the first element of an array, use just the array name without [0] at the end. 829e5c31af7Sopenharmony_ci FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX = 1<<8 830e5c31af7Sopenharmony_ci }; 831e5c31af7Sopenharmony_ci 832e5c31af7Sopenharmony_ci UniformCase (Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 features); 833e5c31af7Sopenharmony_ci virtual ~UniformCase (void); 834e5c31af7Sopenharmony_ci 835e5c31af7Sopenharmony_ci virtual void init (void); 836e5c31af7Sopenharmony_ci virtual void deinit (void); 837e5c31af7Sopenharmony_ci 838e5c31af7Sopenharmony_ci IterateResult iterate (void); 839e5c31af7Sopenharmony_ci 840e5c31af7Sopenharmony_ciprotected: 841e5c31af7Sopenharmony_ci // A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d). 842e5c31af7Sopenharmony_ci struct BasicUniform 843e5c31af7Sopenharmony_ci { 844e5c31af7Sopenharmony_ci string name; 845e5c31af7Sopenharmony_ci glu::DataType type; 846e5c31af7Sopenharmony_ci bool isUsedInShader; 847e5c31af7Sopenharmony_ci VarValue finalValue; //!< The value we ultimately want to set for this uniform. 848e5c31af7Sopenharmony_ci 849e5c31af7Sopenharmony_ci string rootName; //!< If this is a member of a basic-typed array, rootName is the name of that array with "[0]" appended. Otherwise it equals name. 850e5c31af7Sopenharmony_ci int elemNdx; //!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1. 851e5c31af7Sopenharmony_ci int rootSize; //!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1. 852e5c31af7Sopenharmony_ci 853e5c31af7Sopenharmony_ci BasicUniform (const char* const name_, 854e5c31af7Sopenharmony_ci const glu::DataType type_, 855e5c31af7Sopenharmony_ci const bool isUsedInShader_, 856e5c31af7Sopenharmony_ci const VarValue& finalValue_, 857e5c31af7Sopenharmony_ci const char* const rootName_ = DE_NULL, 858e5c31af7Sopenharmony_ci const int elemNdx_ = -1, 859e5c31af7Sopenharmony_ci const int rootSize_ = 1) 860e5c31af7Sopenharmony_ci : name (name_) 861e5c31af7Sopenharmony_ci , type (type_) 862e5c31af7Sopenharmony_ci , isUsedInShader (isUsedInShader_) 863e5c31af7Sopenharmony_ci , finalValue (finalValue_) 864e5c31af7Sopenharmony_ci , rootName (rootName_ == DE_NULL ? name_ : rootName_) 865e5c31af7Sopenharmony_ci , elemNdx (elemNdx_) 866e5c31af7Sopenharmony_ci , rootSize (rootSize_) 867e5c31af7Sopenharmony_ci { 868e5c31af7Sopenharmony_ci } 869e5c31af7Sopenharmony_ci 870e5c31af7Sopenharmony_ci static vector<BasicUniform>::const_iterator findWithName (const vector<BasicUniform>& vec, const char* const name) 871e5c31af7Sopenharmony_ci { 872e5c31af7Sopenharmony_ci for (vector<BasicUniform>::const_iterator it = vec.begin(); it != vec.end(); it++) 873e5c31af7Sopenharmony_ci { 874e5c31af7Sopenharmony_ci if (it->name == name) 875e5c31af7Sopenharmony_ci return it; 876e5c31af7Sopenharmony_ci } 877e5c31af7Sopenharmony_ci return vec.end(); 878e5c31af7Sopenharmony_ci } 879e5c31af7Sopenharmony_ci }; 880e5c31af7Sopenharmony_ci 881e5c31af7Sopenharmony_ci // Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniformsiv(). 882e5c31af7Sopenharmony_ci struct BasicUniformReportRef 883e5c31af7Sopenharmony_ci { 884e5c31af7Sopenharmony_ci string name; 885e5c31af7Sopenharmony_ci // \note minSize and maxSize are for arrays and can be distinct since implementations are allowed, but not required, to trim the inactive end indices of arrays. 886e5c31af7Sopenharmony_ci int minSize; 887e5c31af7Sopenharmony_ci int maxSize; 888e5c31af7Sopenharmony_ci glu::DataType type; 889e5c31af7Sopenharmony_ci bool isUsedInShader; 890e5c31af7Sopenharmony_ci 891e5c31af7Sopenharmony_ci BasicUniformReportRef (const char* const name_, const int minS, const int maxS, const glu::DataType type_, const bool used) 892e5c31af7Sopenharmony_ci : name(name_), minSize(minS), maxSize(maxS), type(type_), isUsedInShader(used) { DE_ASSERT(minSize <= maxSize); } 893e5c31af7Sopenharmony_ci BasicUniformReportRef (const char* const name_, const glu::DataType type_, const bool used) 894e5c31af7Sopenharmony_ci : name(name_), minSize(1), maxSize(1), type(type_), isUsedInShader(used) {} 895e5c31af7Sopenharmony_ci }; 896e5c31af7Sopenharmony_ci 897e5c31af7Sopenharmony_ci // Get uniform values with glGetUniform*() and put to valuesDst. Uniforms that get -1 from glGetUniformLocation() get glu::TYPE_INVALID. 898e5c31af7Sopenharmony_ci bool getUniforms (vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, deUint32 programGL); 899e5c31af7Sopenharmony_ci // Assign the basicUniforms[].finalValue values for uniforms. \note rnd parameter is for booleans (true can be any nonzero value). 900e5c31af7Sopenharmony_ci void assignUniforms (const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd); 901e5c31af7Sopenharmony_ci // Compare the uniform values given in values (obtained with glGetUniform*()) with the basicUniform.finalValue values. 902e5c31af7Sopenharmony_ci bool compareUniformValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms); 903e5c31af7Sopenharmony_ci // Render and check that all pixels are green (i.e. all uniform comparisons passed). 904e5c31af7Sopenharmony_ci bool renderTest (const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd); 905e5c31af7Sopenharmony_ci 906e5c31af7Sopenharmony_ci virtual bool test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd) = 0; 907e5c31af7Sopenharmony_ci 908e5c31af7Sopenharmony_ci const deUint32 m_features; 909e5c31af7Sopenharmony_ci const SharedPtr<const UniformCollection> m_uniformCollection; 910e5c31af7Sopenharmony_ci 911e5c31af7Sopenharmony_ciprivate: 912e5c31af7Sopenharmony_ci // Generates the basic uniforms, based on the uniform with name varName and type varType, in the same manner as are expected 913e5c31af7Sopenharmony_ci // to be returned by glGetActiveUniform(), e.g. generates a name like var[0] for arrays, and recursively generates struct member names. 914e5c31af7Sopenharmony_ci void generateBasicUniforms (vector<BasicUniform>& basicUniformsDst, 915e5c31af7Sopenharmony_ci vector<BasicUniformReportRef>& basicUniformReportsDst, 916e5c31af7Sopenharmony_ci const glu::VarType& varType, 917e5c31af7Sopenharmony_ci const char* varName, 918e5c31af7Sopenharmony_ci bool isParentActive, 919e5c31af7Sopenharmony_ci int& samplerUnitCounter, 920e5c31af7Sopenharmony_ci Random& rnd) const; 921e5c31af7Sopenharmony_ci 922e5c31af7Sopenharmony_ci void writeUniformDefinitions (std::ostringstream& dst) const; 923e5c31af7Sopenharmony_ci void writeUniformCompareExpr (std::ostringstream& dst, const BasicUniform& uniform) const; 924e5c31af7Sopenharmony_ci void writeUniformComparisons (std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* variableName) const; 925e5c31af7Sopenharmony_ci 926e5c31af7Sopenharmony_ci string generateVertexSource (const vector<BasicUniform>& basicUniforms) const; 927e5c31af7Sopenharmony_ci string generateFragmentSource (const vector<BasicUniform>& basicUniforms) const; 928e5c31af7Sopenharmony_ci 929e5c31af7Sopenharmony_ci void setupTexture (const VarValue& value); 930e5c31af7Sopenharmony_ci 931e5c31af7Sopenharmony_ci const CaseShaderType m_caseShaderType; 932e5c31af7Sopenharmony_ci 933e5c31af7Sopenharmony_ci vector<glu::Texture2D*> m_textures2d; 934e5c31af7Sopenharmony_ci vector<glu::TextureCube*> m_texturesCube; 935e5c31af7Sopenharmony_ci vector<deUint32> m_filledTextureUnits; 936e5c31af7Sopenharmony_ci}; 937e5c31af7Sopenharmony_ci 938e5c31af7Sopenharmony_ciUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 features) 939e5c31af7Sopenharmony_ci : TestCase (context, name, description) 940e5c31af7Sopenharmony_ci , CallLogWrapper (context.getRenderContext().getFunctions(), m_testCtx.getLog()) 941e5c31af7Sopenharmony_ci , m_features (features) 942e5c31af7Sopenharmony_ci , m_uniformCollection (uniformCollection) 943e5c31af7Sopenharmony_ci , m_caseShaderType (caseShaderType) 944e5c31af7Sopenharmony_ci{ 945e5c31af7Sopenharmony_ci} 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_civoid UniformCase::init (void) 948e5c31af7Sopenharmony_ci{ 949e5c31af7Sopenharmony_ci { 950e5c31af7Sopenharmony_ci const glw::Functions& funcs = m_context.getRenderContext().getFunctions(); 951e5c31af7Sopenharmony_ci const int numSamplerUniforms = m_uniformCollection->getNumSamplers(); 952e5c31af7Sopenharmony_ci const int vertexTexUnitsRequired = m_caseShaderType != CASESHADERTYPE_FRAGMENT ? numSamplerUniforms : 0; 953e5c31af7Sopenharmony_ci const int fragmentTexUnitsRequired = m_caseShaderType != CASESHADERTYPE_VERTEX ? numSamplerUniforms : 0; 954e5c31af7Sopenharmony_ci const int combinedTexUnitsRequired = vertexTexUnitsRequired + fragmentTexUnitsRequired; 955e5c31af7Sopenharmony_ci const int vertexTexUnitsSupported = getGLInt(funcs, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); 956e5c31af7Sopenharmony_ci const int fragmentTexUnitsSupported = getGLInt(funcs, GL_MAX_TEXTURE_IMAGE_UNITS); 957e5c31af7Sopenharmony_ci const int combinedTexUnitsSupported = getGLInt(funcs, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); 958e5c31af7Sopenharmony_ci 959e5c31af7Sopenharmony_ci DE_ASSERT(numSamplerUniforms <= MAX_NUM_SAMPLER_UNIFORMS); 960e5c31af7Sopenharmony_ci 961e5c31af7Sopenharmony_ci if (vertexTexUnitsRequired > vertexTexUnitsSupported) 962e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(de::toString(vertexTexUnitsRequired) + " vertex texture units required, " + de::toString(vertexTexUnitsSupported) + " supported"); 963e5c31af7Sopenharmony_ci if (fragmentTexUnitsRequired > fragmentTexUnitsSupported) 964e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(de::toString(fragmentTexUnitsRequired) + " fragment texture units required, " + de::toString(fragmentTexUnitsSupported) + " supported"); 965e5c31af7Sopenharmony_ci if (combinedTexUnitsRequired > combinedTexUnitsSupported) 966e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(de::toString(combinedTexUnitsRequired) + " combined texture units required, " + de::toString(combinedTexUnitsSupported) + " supported"); 967e5c31af7Sopenharmony_ci } 968e5c31af7Sopenharmony_ci 969e5c31af7Sopenharmony_ci enableLogging(true); 970e5c31af7Sopenharmony_ci} 971e5c31af7Sopenharmony_ci 972e5c31af7Sopenharmony_civoid UniformCase::deinit (void) 973e5c31af7Sopenharmony_ci{ 974e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_textures2d.size(); i++) 975e5c31af7Sopenharmony_ci delete m_textures2d[i]; 976e5c31af7Sopenharmony_ci m_textures2d.clear(); 977e5c31af7Sopenharmony_ci 978e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_texturesCube.size(); i++) 979e5c31af7Sopenharmony_ci delete m_texturesCube[i]; 980e5c31af7Sopenharmony_ci m_texturesCube.clear(); 981e5c31af7Sopenharmony_ci 982e5c31af7Sopenharmony_ci m_filledTextureUnits.clear(); 983e5c31af7Sopenharmony_ci} 984e5c31af7Sopenharmony_ci 985e5c31af7Sopenharmony_ciUniformCase::~UniformCase (void) 986e5c31af7Sopenharmony_ci{ 987e5c31af7Sopenharmony_ci UniformCase::deinit(); 988e5c31af7Sopenharmony_ci} 989e5c31af7Sopenharmony_ci 990e5c31af7Sopenharmony_civoid UniformCase::generateBasicUniforms (vector<BasicUniform>& basicUniformsDst, vector<BasicUniformReportRef>& basicUniformReportsDst, const glu::VarType& varType, const char* const varName, const bool isParentActive, int& samplerUnitCounter, Random& rnd) const 991e5c31af7Sopenharmony_ci{ 992e5c31af7Sopenharmony_ci if (varType.isBasicType()) 993e5c31af7Sopenharmony_ci { 994e5c31af7Sopenharmony_ci const bool isActive = isParentActive && (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true); 995e5c31af7Sopenharmony_ci const glu::DataType type = varType.getBasicType(); 996e5c31af7Sopenharmony_ci const VarValue value = glu::isDataTypeSampler(type) ? generateRandomVarValue(type, rnd, samplerUnitCounter++) 997e5c31af7Sopenharmony_ci : generateRandomVarValue(varType.getBasicType(), rnd); 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci basicUniformsDst.push_back(BasicUniform(varName, varType.getBasicType(), isActive, value)); 1000e5c31af7Sopenharmony_ci basicUniformReportsDst.push_back(BasicUniformReportRef(varName, varType.getBasicType(), isActive)); 1001e5c31af7Sopenharmony_ci } 1002e5c31af7Sopenharmony_ci else if (varType.isArrayType()) 1003e5c31af7Sopenharmony_ci { 1004e5c31af7Sopenharmony_ci const int size = varType.getArraySize(); 1005e5c31af7Sopenharmony_ci const string arrayRootName = string("") + varName + "[0]"; 1006e5c31af7Sopenharmony_ci vector<bool> isElemActive; 1007e5c31af7Sopenharmony_ci 1008e5c31af7Sopenharmony_ci for (int elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++) 1009e5c31af7Sopenharmony_ci { 1010e5c31af7Sopenharmony_ci const string indexedName = string("") + varName + "[" + de::toString(elemNdx) + "]"; 1011e5c31af7Sopenharmony_ci const bool isCurElemActive = isParentActive && 1012e5c31af7Sopenharmony_ci (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true) && 1013e5c31af7Sopenharmony_ci (m_features & FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX ? elemNdx == size/2 : true); 1014e5c31af7Sopenharmony_ci 1015e5c31af7Sopenharmony_ci isElemActive.push_back(isCurElemActive); 1016e5c31af7Sopenharmony_ci 1017e5c31af7Sopenharmony_ci if (varType.getElementType().isBasicType()) 1018e5c31af7Sopenharmony_ci { 1019e5c31af7Sopenharmony_ci // \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays. 1020e5c31af7Sopenharmony_ci const glu::DataType elemBasicType = varType.getElementType().getBasicType(); 1021e5c31af7Sopenharmony_ci const VarValue value = glu::isDataTypeSampler(elemBasicType) ? generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++) 1022e5c31af7Sopenharmony_ci : generateRandomVarValue(elemBasicType, rnd); 1023e5c31af7Sopenharmony_ci 1024e5c31af7Sopenharmony_ci basicUniformsDst.push_back(BasicUniform(indexedName.c_str(), elemBasicType, isCurElemActive, value, arrayRootName.c_str(), elemNdx, size)); 1025e5c31af7Sopenharmony_ci } 1026e5c31af7Sopenharmony_ci else 1027e5c31af7Sopenharmony_ci generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName.c_str(), isCurElemActive, samplerUnitCounter, rnd); 1028e5c31af7Sopenharmony_ci } 1029e5c31af7Sopenharmony_ci 1030e5c31af7Sopenharmony_ci if (varType.getElementType().isBasicType()) 1031e5c31af7Sopenharmony_ci { 1032e5c31af7Sopenharmony_ci int minSize; 1033e5c31af7Sopenharmony_ci for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize-1]; minSize--); 1034e5c31af7Sopenharmony_ci 1035e5c31af7Sopenharmony_ci basicUniformReportsDst.push_back(BasicUniformReportRef(arrayRootName.c_str(), minSize, size, varType.getElementType().getBasicType(), isParentActive && minSize > 0)); 1036e5c31af7Sopenharmony_ci } 1037e5c31af7Sopenharmony_ci } 1038e5c31af7Sopenharmony_ci else 1039e5c31af7Sopenharmony_ci { 1040e5c31af7Sopenharmony_ci DE_ASSERT(varType.isStructType()); 1041e5c31af7Sopenharmony_ci 1042e5c31af7Sopenharmony_ci const StructType& structType = *varType.getStructPtr(); 1043e5c31af7Sopenharmony_ci 1044e5c31af7Sopenharmony_ci for (int i = 0; i < structType.getNumMembers(); i++) 1045e5c31af7Sopenharmony_ci { 1046e5c31af7Sopenharmony_ci const glu::StructMember& member = structType.getMember(i); 1047e5c31af7Sopenharmony_ci const string memberFullName = string("") + varName + "." + member.getName(); 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName.c_str(), isParentActive, samplerUnitCounter, rnd); 1050e5c31af7Sopenharmony_ci } 1051e5c31af7Sopenharmony_ci } 1052e5c31af7Sopenharmony_ci} 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_civoid UniformCase::writeUniformDefinitions (std::ostringstream& dst) const 1055e5c31af7Sopenharmony_ci{ 1056e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_uniformCollection->getNumStructTypes(); i++) 1057e5c31af7Sopenharmony_ci dst << glu::declare(m_uniformCollection->getStructType(i)) << ";\n"; 1058e5c31af7Sopenharmony_ci 1059e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++) 1060e5c31af7Sopenharmony_ci dst << "uniform " << glu::declare(m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str()) << ";\n"; 1061e5c31af7Sopenharmony_ci 1062e5c31af7Sopenharmony_ci dst << "\n"; 1063e5c31af7Sopenharmony_ci 1064e5c31af7Sopenharmony_ci { 1065e5c31af7Sopenharmony_ci static const struct 1066e5c31af7Sopenharmony_ci { 1067e5c31af7Sopenharmony_ci dataTypePredicate requiringTypes[2]; 1068e5c31af7Sopenharmony_ci const char* definition; 1069e5c31af7Sopenharmony_ci } compareFuncs[] = 1070e5c31af7Sopenharmony_ci { 1071e5c31af7Sopenharmony_ci { { glu::isDataTypeFloatOrVec, glu::isDataTypeMatrix }, "mediump float compare_float (mediump float a, mediump float b) { return abs(a - b) < 0.05 ? 1.0 : 0.0; }" }, 1072e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_VEC2>, dataTypeIsMatrixWithNRows<2> }, "mediump float compare_vec2 (mediump vec2 a, mediump vec2 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y); }" }, 1073e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_VEC3>, dataTypeIsMatrixWithNRows<3> }, "mediump float compare_vec3 (mediump vec3 a, mediump vec3 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z); }" }, 1074e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_VEC4>, dataTypeIsMatrixWithNRows<4> }, "mediump float compare_vec4 (mediump vec4 a, mediump vec4 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z)*compare_float(a.w, b.w); }" }, 1075e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT2>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat2 (mediump mat2 a, mediump mat2 b) { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1]); }" }, 1076e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT2X3>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat2x3 (mediump mat2x3 a, mediump mat2x3 b){ return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1]); }" }, 1077e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT2X4>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat2x4 (mediump mat2x4 a, mediump mat2x4 b){ return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1]); }" }, 1078e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT3X2>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat3x2 (mediump mat3x2 a, mediump mat3x2 b){ return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2]); }" }, 1079e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT3>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat3 (mediump mat3 a, mediump mat3 b) { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2]); }" }, 1080e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT3X4>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat3x4 (mediump mat3x4 a, mediump mat3x4 b){ return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2]); }" }, 1081e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT4X2>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat4x2 (mediump mat4x2 a, mediump mat4x2 b){ return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2])*compare_vec2(a[3], b[3]); }" }, 1082e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT4X3>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat4x3 (mediump mat4x3 a, mediump mat4x3 b){ return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2])*compare_vec3(a[3], b[3]); }" }, 1083e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_FLOAT_MAT4>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_mat4 (mediump mat4 a, mediump mat4 b) { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2])*compare_vec4(a[3], b[3]); }" }, 1084e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_INT>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_int (mediump int a, mediump int b) { return a == b ? 1.0 : 0.0; }" }, 1085e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_INT_VEC2>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_ivec2 (mediump ivec2 a, mediump ivec2 b) { return a == b ? 1.0 : 0.0; }" }, 1086e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_INT_VEC3>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_ivec3 (mediump ivec3 a, mediump ivec3 b) { return a == b ? 1.0 : 0.0; }" }, 1087e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_INT_VEC4>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_ivec4 (mediump ivec4 a, mediump ivec4 b) { return a == b ? 1.0 : 0.0; }" }, 1088e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_UINT>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_uint (mediump uint a, mediump uint b) { return a == b ? 1.0 : 0.0; }" }, 1089e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_UINT_VEC2>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_uvec2 (mediump uvec2 a, mediump uvec2 b) { return a == b ? 1.0 : 0.0; }" }, 1090e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_UINT_VEC3>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_uvec3 (mediump uvec3 a, mediump uvec3 b) { return a == b ? 1.0 : 0.0; }" }, 1091e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_UINT_VEC4>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_uvec4 (mediump uvec4 a, mediump uvec4 b) { return a == b ? 1.0 : 0.0; }" }, 1092e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_BOOL>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_bool (bool a, bool b) { return a == b ? 1.0 : 0.0; }" }, 1093e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_BOOL_VEC2>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_bvec2 (bvec2 a, bvec2 b) { return a == b ? 1.0 : 0.0; }" }, 1094e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_BOOL_VEC3>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_bvec3 (bvec3 a, bvec3 b) { return a == b ? 1.0 : 0.0; }" }, 1095e5c31af7Sopenharmony_ci { { dataTypeEquals<glu::TYPE_BOOL_VEC4>, dataTypeEquals<glu::TYPE_INVALID> }, "mediump float compare_bvec4 (bvec4 a, bvec4 b) { return a == b ? 1.0 : 0.0; }" } 1096e5c31af7Sopenharmony_ci }; 1097e5c31af7Sopenharmony_ci 1098e5c31af7Sopenharmony_ci const vector<glu::DataType> samplerTypes = m_uniformCollection->getSamplerTypes(); 1099e5c31af7Sopenharmony_ci 1100e5c31af7Sopenharmony_ci for (int compFuncNdx = 0; compFuncNdx < DE_LENGTH_OF_ARRAY(compareFuncs); compFuncNdx++) 1101e5c31af7Sopenharmony_ci { 1102e5c31af7Sopenharmony_ci const dataTypePredicate (&typeReq)[2] = compareFuncs[compFuncNdx].requiringTypes; 1103e5c31af7Sopenharmony_ci bool containsTypeSampler = false; 1104e5c31af7Sopenharmony_ci 1105e5c31af7Sopenharmony_ci for (int i = 0; i < (int)samplerTypes.size(); i++) 1106e5c31af7Sopenharmony_ci { 1107e5c31af7Sopenharmony_ci if (glu::isDataTypeSampler(samplerTypes[i])) 1108e5c31af7Sopenharmony_ci { 1109e5c31af7Sopenharmony_ci const glu::DataType retType = getSamplerLookupReturnType(samplerTypes[i]); 1110e5c31af7Sopenharmony_ci if (typeReq[0](retType) || typeReq[1](retType)) 1111e5c31af7Sopenharmony_ci { 1112e5c31af7Sopenharmony_ci containsTypeSampler = true; 1113e5c31af7Sopenharmony_ci break; 1114e5c31af7Sopenharmony_ci } 1115e5c31af7Sopenharmony_ci } 1116e5c31af7Sopenharmony_ci } 1117e5c31af7Sopenharmony_ci 1118e5c31af7Sopenharmony_ci if (containsTypeSampler || m_uniformCollection->containsMatchingBasicType(typeReq[0]) || m_uniformCollection->containsMatchingBasicType(typeReq[1])) 1119e5c31af7Sopenharmony_ci dst << compareFuncs[compFuncNdx].definition << "\n"; 1120e5c31af7Sopenharmony_ci } 1121e5c31af7Sopenharmony_ci } 1122e5c31af7Sopenharmony_ci} 1123e5c31af7Sopenharmony_ci 1124e5c31af7Sopenharmony_civoid UniformCase::writeUniformCompareExpr (std::ostringstream& dst, const BasicUniform& uniform) const 1125e5c31af7Sopenharmony_ci{ 1126e5c31af7Sopenharmony_ci if (glu::isDataTypeSampler(uniform.type)) 1127e5c31af7Sopenharmony_ci dst << "compare_" << glu::getDataTypeName(getSamplerLookupReturnType(uniform.type)) << "(texture(" << uniform.name << ", vec" << getSamplerNumLookupDimensions(uniform.type) << "(0.0))"; 1128e5c31af7Sopenharmony_ci else 1129e5c31af7Sopenharmony_ci dst << "compare_" << glu::getDataTypeName(uniform.type) << "(" << uniform.name; 1130e5c31af7Sopenharmony_ci 1131e5c31af7Sopenharmony_ci dst << ", " << shaderVarValueStr(uniform.finalValue) << ")"; 1132e5c31af7Sopenharmony_ci} 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_civoid UniformCase::writeUniformComparisons (std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* const variableName) const 1135e5c31af7Sopenharmony_ci{ 1136e5c31af7Sopenharmony_ci for (int i = 0; i < (int)basicUniforms.size(); i++) 1137e5c31af7Sopenharmony_ci { 1138e5c31af7Sopenharmony_ci const BasicUniform& unif = basicUniforms[i]; 1139e5c31af7Sopenharmony_ci 1140e5c31af7Sopenharmony_ci if (unif.isUsedInShader) 1141e5c31af7Sopenharmony_ci { 1142e5c31af7Sopenharmony_ci dst << "\t" << variableName << " *= "; 1143e5c31af7Sopenharmony_ci writeUniformCompareExpr(dst, basicUniforms[i]); 1144e5c31af7Sopenharmony_ci dst << ";\n"; 1145e5c31af7Sopenharmony_ci } 1146e5c31af7Sopenharmony_ci else 1147e5c31af7Sopenharmony_ci dst << "\t// UNUSED: " << basicUniforms[i].name << "\n"; 1148e5c31af7Sopenharmony_ci } 1149e5c31af7Sopenharmony_ci} 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_cistring UniformCase::generateVertexSource (const vector<BasicUniform>& basicUniforms) const 1152e5c31af7Sopenharmony_ci{ 1153e5c31af7Sopenharmony_ci const bool isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX || m_caseShaderType == CASESHADERTYPE_BOTH; 1154e5c31af7Sopenharmony_ci std::ostringstream result; 1155e5c31af7Sopenharmony_ci 1156e5c31af7Sopenharmony_ci result << "#version 310 es\n" 1157e5c31af7Sopenharmony_ci "in highp vec4 a_position;\n" 1158e5c31af7Sopenharmony_ci "out mediump float v_vtxOut;\n" 1159e5c31af7Sopenharmony_ci "\n"; 1160e5c31af7Sopenharmony_ci 1161e5c31af7Sopenharmony_ci if (isVertexCase) 1162e5c31af7Sopenharmony_ci writeUniformDefinitions(result); 1163e5c31af7Sopenharmony_ci 1164e5c31af7Sopenharmony_ci result << "\n" 1165e5c31af7Sopenharmony_ci "void main (void)\n" 1166e5c31af7Sopenharmony_ci "{\n" 1167e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 1168e5c31af7Sopenharmony_ci " v_vtxOut = 1.0;\n"; 1169e5c31af7Sopenharmony_ci 1170e5c31af7Sopenharmony_ci if (isVertexCase) 1171e5c31af7Sopenharmony_ci writeUniformComparisons(result, basicUniforms, "v_vtxOut"); 1172e5c31af7Sopenharmony_ci 1173e5c31af7Sopenharmony_ci result << "}\n"; 1174e5c31af7Sopenharmony_ci 1175e5c31af7Sopenharmony_ci return result.str(); 1176e5c31af7Sopenharmony_ci} 1177e5c31af7Sopenharmony_ci 1178e5c31af7Sopenharmony_cistring UniformCase::generateFragmentSource (const vector<BasicUniform>& basicUniforms) const 1179e5c31af7Sopenharmony_ci{ 1180e5c31af7Sopenharmony_ci const bool isFragmentCase = m_caseShaderType == CASESHADERTYPE_FRAGMENT || m_caseShaderType == CASESHADERTYPE_BOTH; 1181e5c31af7Sopenharmony_ci std::ostringstream result; 1182e5c31af7Sopenharmony_ci 1183e5c31af7Sopenharmony_ci result << "#version 310 es\n" 1184e5c31af7Sopenharmony_ci "in mediump float v_vtxOut;\n" 1185e5c31af7Sopenharmony_ci "\n"; 1186e5c31af7Sopenharmony_ci 1187e5c31af7Sopenharmony_ci if (isFragmentCase) 1188e5c31af7Sopenharmony_ci writeUniformDefinitions(result); 1189e5c31af7Sopenharmony_ci 1190e5c31af7Sopenharmony_ci result << "\n" 1191e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" 1192e5c31af7Sopenharmony_ci "\n" 1193e5c31af7Sopenharmony_ci "void main (void)\n" 1194e5c31af7Sopenharmony_ci "{\n" 1195e5c31af7Sopenharmony_ci " mediump float result = v_vtxOut;\n"; 1196e5c31af7Sopenharmony_ci 1197e5c31af7Sopenharmony_ci if (isFragmentCase) 1198e5c31af7Sopenharmony_ci writeUniformComparisons(result, basicUniforms, "result"); 1199e5c31af7Sopenharmony_ci 1200e5c31af7Sopenharmony_ci result << " dEQP_FragColor = vec4(1.0-result, result, 0.0, 1.0);\n" 1201e5c31af7Sopenharmony_ci "}\n"; 1202e5c31af7Sopenharmony_ci 1203e5c31af7Sopenharmony_ci return result.str(); 1204e5c31af7Sopenharmony_ci} 1205e5c31af7Sopenharmony_ci 1206e5c31af7Sopenharmony_civoid UniformCase::setupTexture (const VarValue& value) 1207e5c31af7Sopenharmony_ci{ 1208e5c31af7Sopenharmony_ci // \note No handling for samplers other than 2D or cube. 1209e5c31af7Sopenharmony_ci 1210e5c31af7Sopenharmony_ci enableLogging(false); 1211e5c31af7Sopenharmony_ci 1212e5c31af7Sopenharmony_ci DE_ASSERT(getSamplerLookupReturnType(value.type) == glu::TYPE_FLOAT_VEC4); 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci const int width = 32; 1215e5c31af7Sopenharmony_ci const int height = 32; 1216e5c31af7Sopenharmony_ci const tcu::Vec4 color = vec4FromPtr(&value.val.samplerV.fillColor.floatV[0]); 1217e5c31af7Sopenharmony_ci 1218e5c31af7Sopenharmony_ci if (value.type == glu::TYPE_SAMPLER_2D) 1219e5c31af7Sopenharmony_ci { 1220e5c31af7Sopenharmony_ci glu::Texture2D* texture = new glu::Texture2D(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width, height); 1221e5c31af7Sopenharmony_ci tcu::Texture2D& refTexture = texture->getRefTexture(); 1222e5c31af7Sopenharmony_ci m_textures2d.push_back(texture); 1223e5c31af7Sopenharmony_ci 1224e5c31af7Sopenharmony_ci refTexture.allocLevel(0); 1225e5c31af7Sopenharmony_ci fillWithColor(refTexture.getLevel(0), color); 1226e5c31af7Sopenharmony_ci 1227e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit)); 1228e5c31af7Sopenharmony_ci m_filledTextureUnits.push_back(value.val.samplerV.unit); 1229e5c31af7Sopenharmony_ci texture->upload(); 1230e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); 1231e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); 1232e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); 1233e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 1234e5c31af7Sopenharmony_ci } 1235e5c31af7Sopenharmony_ci else if (value.type == glu::TYPE_SAMPLER_CUBE) 1236e5c31af7Sopenharmony_ci { 1237e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(width == height); 1238e5c31af7Sopenharmony_ci glu::TextureCube* texture = new glu::TextureCube(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width); 1239e5c31af7Sopenharmony_ci tcu::TextureCube& refTexture = texture->getRefTexture(); 1240e5c31af7Sopenharmony_ci m_texturesCube.push_back(texture); 1241e5c31af7Sopenharmony_ci 1242e5c31af7Sopenharmony_ci for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++) 1243e5c31af7Sopenharmony_ci { 1244e5c31af7Sopenharmony_ci refTexture.allocLevel((tcu::CubeFace)face, 0); 1245e5c31af7Sopenharmony_ci fillWithColor(refTexture.getLevelFace(0, (tcu::CubeFace)face), color); 1246e5c31af7Sopenharmony_ci } 1247e5c31af7Sopenharmony_ci 1248e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit)); 1249e5c31af7Sopenharmony_ci m_filledTextureUnits.push_back(value.val.samplerV.unit); 1250e5c31af7Sopenharmony_ci texture->upload(); 1251e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); 1252e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); 1253e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); 1254e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 1255e5c31af7Sopenharmony_ci 1256e5c31af7Sopenharmony_ci } 1257e5c31af7Sopenharmony_ci else 1258e5c31af7Sopenharmony_ci DE_ASSERT(false); 1259e5c31af7Sopenharmony_ci 1260e5c31af7Sopenharmony_ci enableLogging(true); 1261e5c31af7Sopenharmony_ci} 1262e5c31af7Sopenharmony_ci 1263e5c31af7Sopenharmony_cibool UniformCase::getUniforms (vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, const deUint32 programGL) 1264e5c31af7Sopenharmony_ci{ 1265e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1266e5c31af7Sopenharmony_ci bool success = true; 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++) 1269e5c31af7Sopenharmony_ci { 1270e5c31af7Sopenharmony_ci const BasicUniform& uniform = basicUniforms[unifNdx]; 1271e5c31af7Sopenharmony_ci const string queryName = m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name; 1272e5c31af7Sopenharmony_ci const int location = glGetUniformLocation(programGL, queryName.c_str()); 1273e5c31af7Sopenharmony_ci const int size = glu::getDataTypeScalarSize(uniform.type); 1274e5c31af7Sopenharmony_ci VarValue value; 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_ci deMemset(&value, 0xcd, sizeof(value)); // Initialize to known garbage. 1277e5c31af7Sopenharmony_ci 1278e5c31af7Sopenharmony_ci if (location == -1) 1279e5c31af7Sopenharmony_ci { 1280e5c31af7Sopenharmony_ci value.type = glu::TYPE_INVALID; 1281e5c31af7Sopenharmony_ci valuesDst.push_back(value); 1282e5c31af7Sopenharmony_ci if (uniform.isUsedInShader) 1283e5c31af7Sopenharmony_ci { 1284e5c31af7Sopenharmony_ci log << TestLog::Message << "// FAILURE: " << uniform.name << " was used in shader, but has location -1" << TestLog::EndMessage; 1285e5c31af7Sopenharmony_ci success = false; 1286e5c31af7Sopenharmony_ci } 1287e5c31af7Sopenharmony_ci continue; 1288e5c31af7Sopenharmony_ci } 1289e5c31af7Sopenharmony_ci 1290e5c31af7Sopenharmony_ci value.type = uniform.type; 1291e5c31af7Sopenharmony_ci 1292e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(GLint) == sizeof(value.val.intV[0])); 1293e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(value.val.uintV[0])); 1294e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(value.val.floatV[0])); 1295e5c31af7Sopenharmony_ci 1296e5c31af7Sopenharmony_ci if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type)) 1297e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0])); 1298e5c31af7Sopenharmony_ci else if (glu::isDataTypeIntOrIVec(uniform.type)) 1299e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0])); 1300e5c31af7Sopenharmony_ci else if (glu::isDataTypeUintOrUVec(uniform.type)) 1301e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0])); 1302e5c31af7Sopenharmony_ci else if (glu::isDataTypeBoolOrBVec(uniform.type)) 1303e5c31af7Sopenharmony_ci { 1304e5c31af7Sopenharmony_ci if (m_features & FEATURE_BOOLEANAPITYPE_INT) 1305e5c31af7Sopenharmony_ci { 1306e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0])); 1307e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 1308e5c31af7Sopenharmony_ci value.val.boolV[i] = value.val.intV[i] != 0; 1309e5c31af7Sopenharmony_ci } 1310e5c31af7Sopenharmony_ci else if (m_features & FEATURE_BOOLEANAPITYPE_UINT) 1311e5c31af7Sopenharmony_ci { 1312e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0])); 1313e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 1314e5c31af7Sopenharmony_ci value.val.boolV[i] = value.val.uintV[i] != 0; 1315e5c31af7Sopenharmony_ci } 1316e5c31af7Sopenharmony_ci else // Default: use float. 1317e5c31af7Sopenharmony_ci { 1318e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0])); 1319e5c31af7Sopenharmony_ci for (int i = 0; i < size; i++) 1320e5c31af7Sopenharmony_ci value.val.boolV[i] = value.val.floatV[i] != 0.0f; 1321e5c31af7Sopenharmony_ci } 1322e5c31af7Sopenharmony_ci } 1323e5c31af7Sopenharmony_ci else if (glu::isDataTypeSampler(uniform.type)) 1324e5c31af7Sopenharmony_ci { 1325e5c31af7Sopenharmony_ci GLint unit = -1; 1326e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glGetUniformiv(programGL, location, &unit)); 1327e5c31af7Sopenharmony_ci value.val.samplerV.unit = unit; 1328e5c31af7Sopenharmony_ci } 1329e5c31af7Sopenharmony_ci else 1330e5c31af7Sopenharmony_ci DE_ASSERT(false); 1331e5c31af7Sopenharmony_ci 1332e5c31af7Sopenharmony_ci valuesDst.push_back(value); 1333e5c31af7Sopenharmony_ci 1334e5c31af7Sopenharmony_ci log << TestLog::Message << "// Got " << uniform.name << " value " << apiVarValueStr(value) << TestLog::EndMessage; 1335e5c31af7Sopenharmony_ci } 1336e5c31af7Sopenharmony_ci 1337e5c31af7Sopenharmony_ci return success; 1338e5c31af7Sopenharmony_ci} 1339e5c31af7Sopenharmony_ci 1340e5c31af7Sopenharmony_civoid UniformCase::assignUniforms (const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd) 1341e5c31af7Sopenharmony_ci{ 1342e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1343e5c31af7Sopenharmony_ci const bool transpose = (m_features & FEATURE_MATRIXMODE_ROWMAJOR) != 0; 1344e5c31af7Sopenharmony_ci const GLboolean transposeGL = transpose ? GL_TRUE : GL_FALSE; 1345e5c31af7Sopenharmony_ci const glu::DataType boolApiType = m_features & FEATURE_BOOLEANAPITYPE_INT ? glu::TYPE_INT 1346e5c31af7Sopenharmony_ci : m_features & FEATURE_BOOLEANAPITYPE_UINT ? glu::TYPE_UINT 1347e5c31af7Sopenharmony_ci : glu::TYPE_FLOAT; 1348e5c31af7Sopenharmony_ci 1349e5c31af7Sopenharmony_ci for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++) 1350e5c31af7Sopenharmony_ci { 1351e5c31af7Sopenharmony_ci const BasicUniform& uniform = basicUniforms[unifNdx]; 1352e5c31af7Sopenharmony_ci const bool isArrayMember = uniform.elemNdx >= 0; 1353e5c31af7Sopenharmony_ci const string queryName = m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name; 1354e5c31af7Sopenharmony_ci const int numValuesToAssign = !isArrayMember ? 1 1355e5c31af7Sopenharmony_ci : m_features & FEATURE_ARRAYASSIGN_FULL ? (uniform.elemNdx == 0 ? uniform.rootSize : 0) 1356e5c31af7Sopenharmony_ci : m_features & FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO ? (uniform.elemNdx % 2 == 0 ? 2 : 0) 1357e5c31af7Sopenharmony_ci : /* Default: assign array elements separately */ 1; 1358e5c31af7Sopenharmony_ci 1359e5c31af7Sopenharmony_ci DE_ASSERT(numValuesToAssign >= 0); 1360e5c31af7Sopenharmony_ci DE_ASSERT(numValuesToAssign == 1 || isArrayMember); 1361e5c31af7Sopenharmony_ci 1362e5c31af7Sopenharmony_ci if (numValuesToAssign == 0) 1363e5c31af7Sopenharmony_ci { 1364e5c31af7Sopenharmony_ci log << TestLog::Message << "// Uniform " << uniform.name << " is covered by another glProgramUniform*v() call to the same array" << TestLog::EndMessage; 1365e5c31af7Sopenharmony_ci continue; 1366e5c31af7Sopenharmony_ci } 1367e5c31af7Sopenharmony_ci 1368e5c31af7Sopenharmony_ci const int location = glGetUniformLocation(programGL, queryName.c_str()); 1369e5c31af7Sopenharmony_ci const int typeSize = glu::getDataTypeScalarSize(uniform.type); 1370e5c31af7Sopenharmony_ci const bool assignByValue = m_features & FEATURE_UNIFORMFUNC_VALUE && !glu::isDataTypeMatrix(uniform.type) && numValuesToAssign == 1; 1371e5c31af7Sopenharmony_ci vector<VarValue> valuesToAssign; 1372e5c31af7Sopenharmony_ci 1373e5c31af7Sopenharmony_ci for (int i = 0; i < numValuesToAssign; i++) 1374e5c31af7Sopenharmony_ci { 1375e5c31af7Sopenharmony_ci const string curName = isArrayMember ? beforeLast(uniform.rootName, '[') + "[" + de::toString(uniform.elemNdx+i) + "]" : uniform.name; 1376e5c31af7Sopenharmony_ci VarValue unifValue; 1377e5c31af7Sopenharmony_ci 1378e5c31af7Sopenharmony_ci if (isArrayMember) 1379e5c31af7Sopenharmony_ci { 1380e5c31af7Sopenharmony_ci const vector<BasicUniform>::const_iterator elemUnif = BasicUniform::findWithName(basicUniforms, curName.c_str()); 1381e5c31af7Sopenharmony_ci if (elemUnif == basicUniforms.end()) 1382e5c31af7Sopenharmony_ci continue; 1383e5c31af7Sopenharmony_ci unifValue = elemUnif->finalValue; 1384e5c31af7Sopenharmony_ci } 1385e5c31af7Sopenharmony_ci else 1386e5c31af7Sopenharmony_ci unifValue = uniform.finalValue; 1387e5c31af7Sopenharmony_ci 1388e5c31af7Sopenharmony_ci const VarValue apiValue = glu::isDataTypeBoolOrBVec(unifValue.type) ? getRandomBoolRepresentation(unifValue, boolApiType, rnd) 1389e5c31af7Sopenharmony_ci : glu::isDataTypeSampler(unifValue.type) ? getSamplerUnitValue(unifValue) 1390e5c31af7Sopenharmony_ci : unifValue; 1391e5c31af7Sopenharmony_ci 1392e5c31af7Sopenharmony_ci valuesToAssign.push_back(glu::isDataTypeMatrix(apiValue.type) && transpose ? getTransposeMatrix(apiValue) : apiValue); 1393e5c31af7Sopenharmony_ci 1394e5c31af7Sopenharmony_ci if (glu::isDataTypeBoolOrBVec(uniform.type)) 1395e5c31af7Sopenharmony_ci log << TestLog::Message << "// Using type " << glu::getDataTypeName(boolApiType) << " to set boolean value " << apiVarValueStr(unifValue) << " for " << curName << TestLog::EndMessage; 1396e5c31af7Sopenharmony_ci else if (glu::isDataTypeSampler(uniform.type)) 1397e5c31af7Sopenharmony_ci log << TestLog::Message << "// Texture for the sampler uniform " << curName << " will be filled with color " << apiVarValueStr(getSamplerFillValue(uniform.finalValue)) << TestLog::EndMessage; 1398e5c31af7Sopenharmony_ci } 1399e5c31af7Sopenharmony_ci 1400e5c31af7Sopenharmony_ci DE_ASSERT(!valuesToAssign.empty()); 1401e5c31af7Sopenharmony_ci 1402e5c31af7Sopenharmony_ci if (glu::isDataTypeFloatOrVec(valuesToAssign[0].type)) 1403e5c31af7Sopenharmony_ci { 1404e5c31af7Sopenharmony_ci if (assignByValue) 1405e5c31af7Sopenharmony_ci { 1406e5c31af7Sopenharmony_ci const float* const ptr = &valuesToAssign[0].val.floatV[0]; 1407e5c31af7Sopenharmony_ci 1408e5c31af7Sopenharmony_ci switch (typeSize) 1409e5c31af7Sopenharmony_ci { 1410e5c31af7Sopenharmony_ci case 1: GLU_CHECK_CALL(glProgramUniform1f(programGL, location, ptr[0])); break; 1411e5c31af7Sopenharmony_ci case 2: GLU_CHECK_CALL(glProgramUniform2f(programGL, location, ptr[0], ptr[1])); break; 1412e5c31af7Sopenharmony_ci case 3: GLU_CHECK_CALL(glProgramUniform3f(programGL, location, ptr[0], ptr[1], ptr[2])); break; 1413e5c31af7Sopenharmony_ci case 4: GLU_CHECK_CALL(glProgramUniform4f(programGL, location, ptr[0], ptr[1], ptr[2], ptr[3])); break; 1414e5c31af7Sopenharmony_ci default: 1415e5c31af7Sopenharmony_ci DE_ASSERT(false); 1416e5c31af7Sopenharmony_ci } 1417e5c31af7Sopenharmony_ci } 1418e5c31af7Sopenharmony_ci else 1419e5c31af7Sopenharmony_ci { 1420e5c31af7Sopenharmony_ci vector<float> buffer(valuesToAssign.size() * typeSize); 1421e5c31af7Sopenharmony_ci for (int i = 0; i < (int)buffer.size(); i++) 1422e5c31af7Sopenharmony_ci buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize]; 1423e5c31af7Sopenharmony_ci 1424e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0])); 1425e5c31af7Sopenharmony_ci switch (typeSize) 1426e5c31af7Sopenharmony_ci { 1427e5c31af7Sopenharmony_ci case 1: GLU_CHECK_CALL(glProgramUniform1fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1428e5c31af7Sopenharmony_ci case 2: GLU_CHECK_CALL(glProgramUniform2fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1429e5c31af7Sopenharmony_ci case 3: GLU_CHECK_CALL(glProgramUniform3fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1430e5c31af7Sopenharmony_ci case 4: GLU_CHECK_CALL(glProgramUniform4fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1431e5c31af7Sopenharmony_ci default: 1432e5c31af7Sopenharmony_ci DE_ASSERT(false); 1433e5c31af7Sopenharmony_ci } 1434e5c31af7Sopenharmony_ci } 1435e5c31af7Sopenharmony_ci } 1436e5c31af7Sopenharmony_ci else if (glu::isDataTypeMatrix(valuesToAssign[0].type)) 1437e5c31af7Sopenharmony_ci { 1438e5c31af7Sopenharmony_ci DE_ASSERT(!assignByValue); 1439e5c31af7Sopenharmony_ci 1440e5c31af7Sopenharmony_ci vector<float> buffer(valuesToAssign.size() * typeSize); 1441e5c31af7Sopenharmony_ci for (int i = 0; i < (int)buffer.size(); i++) 1442e5c31af7Sopenharmony_ci buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize]; 1443e5c31af7Sopenharmony_ci 1444e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0])); 1445e5c31af7Sopenharmony_ci switch (uniform.type) 1446e5c31af7Sopenharmony_ci { 1447e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT2: GLU_CHECK_CALL(glProgramUniformMatrix2fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1448e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT3: GLU_CHECK_CALL(glProgramUniformMatrix3fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1449e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT4: GLU_CHECK_CALL(glProgramUniformMatrix4fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1450e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT2X3: GLU_CHECK_CALL(glProgramUniformMatrix2x3fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1451e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT2X4: GLU_CHECK_CALL(glProgramUniformMatrix2x4fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1452e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT3X2: GLU_CHECK_CALL(glProgramUniformMatrix3x2fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1453e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT3X4: GLU_CHECK_CALL(glProgramUniformMatrix3x4fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1454e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT4X2: GLU_CHECK_CALL(glProgramUniformMatrix4x2fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1455e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_MAT4X3: GLU_CHECK_CALL(glProgramUniformMatrix4x3fv (programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break; 1456e5c31af7Sopenharmony_ci default: 1457e5c31af7Sopenharmony_ci DE_ASSERT(false); 1458e5c31af7Sopenharmony_ci } 1459e5c31af7Sopenharmony_ci } 1460e5c31af7Sopenharmony_ci else if (glu::isDataTypeIntOrIVec(valuesToAssign[0].type)) 1461e5c31af7Sopenharmony_ci { 1462e5c31af7Sopenharmony_ci if (assignByValue) 1463e5c31af7Sopenharmony_ci { 1464e5c31af7Sopenharmony_ci const deInt32* const ptr = &valuesToAssign[0].val.intV[0]; 1465e5c31af7Sopenharmony_ci 1466e5c31af7Sopenharmony_ci switch (typeSize) 1467e5c31af7Sopenharmony_ci { 1468e5c31af7Sopenharmony_ci case 1: GLU_CHECK_CALL(glProgramUniform1i(programGL, location, ptr[0])); break; 1469e5c31af7Sopenharmony_ci case 2: GLU_CHECK_CALL(glProgramUniform2i(programGL, location, ptr[0], ptr[1])); break; 1470e5c31af7Sopenharmony_ci case 3: GLU_CHECK_CALL(glProgramUniform3i(programGL, location, ptr[0], ptr[1], ptr[2])); break; 1471e5c31af7Sopenharmony_ci case 4: GLU_CHECK_CALL(glProgramUniform4i(programGL, location, ptr[0], ptr[1], ptr[2], ptr[3])); break; 1472e5c31af7Sopenharmony_ci default: 1473e5c31af7Sopenharmony_ci DE_ASSERT(false); 1474e5c31af7Sopenharmony_ci } 1475e5c31af7Sopenharmony_ci } 1476e5c31af7Sopenharmony_ci else 1477e5c31af7Sopenharmony_ci { 1478e5c31af7Sopenharmony_ci vector<deInt32> buffer(valuesToAssign.size() * typeSize); 1479e5c31af7Sopenharmony_ci for (int i = 0; i < (int)buffer.size(); i++) 1480e5c31af7Sopenharmony_ci buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize]; 1481e5c31af7Sopenharmony_ci 1482e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(GLint) == sizeof(buffer[0])); 1483e5c31af7Sopenharmony_ci switch (typeSize) 1484e5c31af7Sopenharmony_ci { 1485e5c31af7Sopenharmony_ci case 1: GLU_CHECK_CALL(glProgramUniform1iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1486e5c31af7Sopenharmony_ci case 2: GLU_CHECK_CALL(glProgramUniform2iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1487e5c31af7Sopenharmony_ci case 3: GLU_CHECK_CALL(glProgramUniform3iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1488e5c31af7Sopenharmony_ci case 4: GLU_CHECK_CALL(glProgramUniform4iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1489e5c31af7Sopenharmony_ci default: 1490e5c31af7Sopenharmony_ci DE_ASSERT(false); 1491e5c31af7Sopenharmony_ci } 1492e5c31af7Sopenharmony_ci } 1493e5c31af7Sopenharmony_ci } 1494e5c31af7Sopenharmony_ci else if (glu::isDataTypeUintOrUVec(valuesToAssign[0].type)) 1495e5c31af7Sopenharmony_ci { 1496e5c31af7Sopenharmony_ci if (assignByValue) 1497e5c31af7Sopenharmony_ci { 1498e5c31af7Sopenharmony_ci const deUint32* const ptr = &valuesToAssign[0].val.uintV[0]; 1499e5c31af7Sopenharmony_ci 1500e5c31af7Sopenharmony_ci switch (typeSize) 1501e5c31af7Sopenharmony_ci { 1502e5c31af7Sopenharmony_ci case 1: GLU_CHECK_CALL(glProgramUniform1ui(programGL, location, ptr[0])); break; 1503e5c31af7Sopenharmony_ci case 2: GLU_CHECK_CALL(glProgramUniform2ui(programGL, location, ptr[0], ptr[1])); break; 1504e5c31af7Sopenharmony_ci case 3: GLU_CHECK_CALL(glProgramUniform3ui(programGL, location, ptr[0], ptr[1], ptr[2])); break; 1505e5c31af7Sopenharmony_ci case 4: GLU_CHECK_CALL(glProgramUniform4ui(programGL, location, ptr[0], ptr[1], ptr[2], ptr[3])); break; 1506e5c31af7Sopenharmony_ci default: 1507e5c31af7Sopenharmony_ci DE_ASSERT(false); 1508e5c31af7Sopenharmony_ci } 1509e5c31af7Sopenharmony_ci } 1510e5c31af7Sopenharmony_ci else 1511e5c31af7Sopenharmony_ci { 1512e5c31af7Sopenharmony_ci vector<deUint32> buffer(valuesToAssign.size() * typeSize); 1513e5c31af7Sopenharmony_ci for (int i = 0; i < (int)buffer.size(); i++) 1514e5c31af7Sopenharmony_ci buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize]; 1515e5c31af7Sopenharmony_ci 1516e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(buffer[0])); 1517e5c31af7Sopenharmony_ci switch (typeSize) 1518e5c31af7Sopenharmony_ci { 1519e5c31af7Sopenharmony_ci case 1: GLU_CHECK_CALL(glProgramUniform1uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1520e5c31af7Sopenharmony_ci case 2: GLU_CHECK_CALL(glProgramUniform2uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1521e5c31af7Sopenharmony_ci case 3: GLU_CHECK_CALL(glProgramUniform3uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1522e5c31af7Sopenharmony_ci case 4: GLU_CHECK_CALL(glProgramUniform4uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break; 1523e5c31af7Sopenharmony_ci default: 1524e5c31af7Sopenharmony_ci DE_ASSERT(false); 1525e5c31af7Sopenharmony_ci } 1526e5c31af7Sopenharmony_ci } 1527e5c31af7Sopenharmony_ci } 1528e5c31af7Sopenharmony_ci else if (glu::isDataTypeSampler(valuesToAssign[0].type)) 1529e5c31af7Sopenharmony_ci { 1530e5c31af7Sopenharmony_ci if (assignByValue) 1531e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glProgramUniform1i(programGL, location, uniform.finalValue.val.samplerV.unit)); 1532e5c31af7Sopenharmony_ci else 1533e5c31af7Sopenharmony_ci { 1534e5c31af7Sopenharmony_ci const GLint unit = uniform.finalValue.val.samplerV.unit; 1535e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glProgramUniform1iv(programGL, location, (GLsizei)valuesToAssign.size(), &unit)); 1536e5c31af7Sopenharmony_ci } 1537e5c31af7Sopenharmony_ci } 1538e5c31af7Sopenharmony_ci else 1539e5c31af7Sopenharmony_ci DE_ASSERT(false); 1540e5c31af7Sopenharmony_ci } 1541e5c31af7Sopenharmony_ci} 1542e5c31af7Sopenharmony_ci 1543e5c31af7Sopenharmony_cibool UniformCase::compareUniformValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms) 1544e5c31af7Sopenharmony_ci{ 1545e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1546e5c31af7Sopenharmony_ci bool success = true; 1547e5c31af7Sopenharmony_ci 1548e5c31af7Sopenharmony_ci for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++) 1549e5c31af7Sopenharmony_ci { 1550e5c31af7Sopenharmony_ci const BasicUniform& uniform = basicUniforms[unifNdx]; 1551e5c31af7Sopenharmony_ci const VarValue& unifValue = values[unifNdx]; 1552e5c31af7Sopenharmony_ci 1553e5c31af7Sopenharmony_ci log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage; 1554e5c31af7Sopenharmony_ci 1555e5c31af7Sopenharmony_ci if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1. 1556e5c31af7Sopenharmony_ci continue; 1557e5c31af7Sopenharmony_ci 1558e5c31af7Sopenharmony_ci if (!apiVarValueEquals(unifValue, uniform.finalValue)) 1559e5c31af7Sopenharmony_ci { 1560e5c31af7Sopenharmony_ci log << TestLog::Message << "// FAILURE: value obtained with glGetUniform*() for uniform " << uniform.name << " differs from value set with glProgramUniform*()" << TestLog::EndMessage; 1561e5c31af7Sopenharmony_ci success = false; 1562e5c31af7Sopenharmony_ci } 1563e5c31af7Sopenharmony_ci } 1564e5c31af7Sopenharmony_ci 1565e5c31af7Sopenharmony_ci return success; 1566e5c31af7Sopenharmony_ci} 1567e5c31af7Sopenharmony_ci 1568e5c31af7Sopenharmony_cibool UniformCase::renderTest (const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd) 1569e5c31af7Sopenharmony_ci{ 1570e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1571e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_context.getRenderTarget(); 1572e5c31af7Sopenharmony_ci const int viewportW = de::min<int>(renderTarget.getWidth(), MAX_RENDER_WIDTH); 1573e5c31af7Sopenharmony_ci const int viewportH = de::min<int>(renderTarget.getHeight(), MAX_RENDER_HEIGHT); 1574e5c31af7Sopenharmony_ci const int viewportX = rnd.getInt(0, renderTarget.getWidth() - viewportW); 1575e5c31af7Sopenharmony_ci const int viewportY = rnd.getInt(0, renderTarget.getHeight() - viewportH); 1576e5c31af7Sopenharmony_ci tcu::Surface renderedImg (viewportW, viewportH); 1577e5c31af7Sopenharmony_ci 1578e5c31af7Sopenharmony_ci // Assert that no two samplers of different types have the same texture unit - this is an error in GL. 1579e5c31af7Sopenharmony_ci for (int i = 0; i < (int)basicUniforms.size(); i++) 1580e5c31af7Sopenharmony_ci { 1581e5c31af7Sopenharmony_ci if (glu::isDataTypeSampler(basicUniforms[i].type)) 1582e5c31af7Sopenharmony_ci { 1583e5c31af7Sopenharmony_ci for (int j = 0; j < i; j++) 1584e5c31af7Sopenharmony_ci { 1585e5c31af7Sopenharmony_ci if (glu::isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type) 1586e5c31af7Sopenharmony_ci DE_ASSERT(basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit); 1587e5c31af7Sopenharmony_ci } 1588e5c31af7Sopenharmony_ci } 1589e5c31af7Sopenharmony_ci } 1590e5c31af7Sopenharmony_ci 1591e5c31af7Sopenharmony_ci for (int i = 0; i < (int)basicUniforms.size(); i++) 1592e5c31af7Sopenharmony_ci { 1593e5c31af7Sopenharmony_ci if (glu::isDataTypeSampler(basicUniforms[i].type) && std::find(m_filledTextureUnits.begin(), m_filledTextureUnits.end(), basicUniforms[i].finalValue.val.samplerV.unit) == m_filledTextureUnits.end()) 1594e5c31af7Sopenharmony_ci { 1595e5c31af7Sopenharmony_ci log << TestLog::Message << "// Filling texture at unit " << apiVarValueStr(basicUniforms[i].finalValue) << " with color " << shaderVarValueStr(basicUniforms[i].finalValue) << TestLog::EndMessage; 1596e5c31af7Sopenharmony_ci setupTexture(basicUniforms[i].finalValue); 1597e5c31af7Sopenharmony_ci } 1598e5c31af7Sopenharmony_ci } 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportW, viewportH)); 1601e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); 1602e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); 1603e5c31af7Sopenharmony_ci GLU_CHECK_CALL(glUseProgram(program.getProgram())); 1604e5c31af7Sopenharmony_ci 1605e5c31af7Sopenharmony_ci { 1606e5c31af7Sopenharmony_ci static const float position[] = 1607e5c31af7Sopenharmony_ci { 1608e5c31af7Sopenharmony_ci -1.0f, -1.0f, 0.0f, 1.0f, 1609e5c31af7Sopenharmony_ci -1.0f, +1.0f, 0.0f, 1.0f, 1610e5c31af7Sopenharmony_ci +1.0f, -1.0f, 0.0f, 1.0f, 1611e5c31af7Sopenharmony_ci +1.0f, +1.0f, 0.0f, 1.0f 1612e5c31af7Sopenharmony_ci }; 1613e5c31af7Sopenharmony_ci static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 }; 1614e5c31af7Sopenharmony_ci const glu::VertexArrayBinding binding = glu::va::Float("a_position", 4, 4, 0, &position[0]); 1615e5c31af7Sopenharmony_ci 1616e5c31af7Sopenharmony_ci glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &binding, glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0])); 1617e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess()); 1618e5c31af7Sopenharmony_ci } 1619e5c31af7Sopenharmony_ci 1620e5c31af7Sopenharmony_ci int numFailedPixels = 0; 1621e5c31af7Sopenharmony_ci for (int y = 0; y < renderedImg.getHeight(); y++) 1622e5c31af7Sopenharmony_ci { 1623e5c31af7Sopenharmony_ci for (int x = 0; x < renderedImg.getWidth(); x++) 1624e5c31af7Sopenharmony_ci { 1625e5c31af7Sopenharmony_ci if (renderedImg.getPixel(x, y) != tcu::RGBA::green()) 1626e5c31af7Sopenharmony_ci numFailedPixels += 1; 1627e5c31af7Sopenharmony_ci } 1628e5c31af7Sopenharmony_ci } 1629e5c31af7Sopenharmony_ci 1630e5c31af7Sopenharmony_ci if (numFailedPixels > 0) 1631e5c31af7Sopenharmony_ci { 1632e5c31af7Sopenharmony_ci log << TestLog::Image("RenderedImage", "Rendered image", renderedImg); 1633e5c31af7Sopenharmony_ci log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-green pixels" << TestLog::EndMessage; 1634e5c31af7Sopenharmony_ci return false; 1635e5c31af7Sopenharmony_ci } 1636e5c31af7Sopenharmony_ci else 1637e5c31af7Sopenharmony_ci { 1638e5c31af7Sopenharmony_ci log << TestLog::Message << "Success: got all-green pixels (all uniforms have correct values)" << TestLog::EndMessage; 1639e5c31af7Sopenharmony_ci return true; 1640e5c31af7Sopenharmony_ci } 1641e5c31af7Sopenharmony_ci} 1642e5c31af7Sopenharmony_ci 1643e5c31af7Sopenharmony_ciUniformCase::IterateResult UniformCase::iterate (void) 1644e5c31af7Sopenharmony_ci{ 1645e5c31af7Sopenharmony_ci Random rnd (deStringHash(getName()) ^ (deUint32)m_context.getTestContext().getCommandLine().getBaseSeed()); 1646e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1647e5c31af7Sopenharmony_ci vector<BasicUniform> basicUniforms; 1648e5c31af7Sopenharmony_ci vector<BasicUniformReportRef> basicUniformReportsRef; 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci { 1651e5c31af7Sopenharmony_ci int samplerUnitCounter = 0; 1652e5c31af7Sopenharmony_ci for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++) 1653e5c31af7Sopenharmony_ci generateBasicUniforms(basicUniforms, basicUniformReportsRef, m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str(), true, samplerUnitCounter, rnd); 1654e5c31af7Sopenharmony_ci } 1655e5c31af7Sopenharmony_ci 1656e5c31af7Sopenharmony_ci const string vertexSource = generateVertexSource(basicUniforms); 1657e5c31af7Sopenharmony_ci const string fragmentSource = generateFragmentSource(basicUniforms); 1658e5c31af7Sopenharmony_ci const ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource)); 1659e5c31af7Sopenharmony_ci 1660e5c31af7Sopenharmony_ci // An unused program that we'll give to glUseProgram before we actually need 1661e5c31af7Sopenharmony_ci // the real program above, to see if an implementation tries to use the 1662e5c31af7Sopenharmony_ci // currently active program for something inappropriate (instead of the 1663e5c31af7Sopenharmony_ci // program given as argument to, say, glProgramUniform*). 1664e5c31af7Sopenharmony_ci const ShaderProgram unusedProgram (m_context.getRenderContext(), glu::makeVtxFragSources("#version 310 es\n" 1665e5c31af7Sopenharmony_ci "void main (void) { gl_Position = vec4(1.0); }\n", 1666e5c31af7Sopenharmony_ci 1667e5c31af7Sopenharmony_ci "#version 310 es\n" 1668e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" 1669e5c31af7Sopenharmony_ci "void main (void) { dEQP_FragColor = vec4(0.0, 0.0, 1.0, 1.0); }\n")); 1670e5c31af7Sopenharmony_ci 1671e5c31af7Sopenharmony_ci log << program; 1672e5c31af7Sopenharmony_ci 1673e5c31af7Sopenharmony_ci if (!program.isOk()) 1674e5c31af7Sopenharmony_ci { 1675e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed"); 1676e5c31af7Sopenharmony_ci return STOP; 1677e5c31af7Sopenharmony_ci } 1678e5c31af7Sopenharmony_ci 1679e5c31af7Sopenharmony_ci if (!unusedProgram.isOk()) 1680e5c31af7Sopenharmony_ci { 1681e5c31af7Sopenharmony_ci log << unusedProgram; 1682e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of unused program failed"); 1683e5c31af7Sopenharmony_ci return STOP; 1684e5c31af7Sopenharmony_ci } 1685e5c31af7Sopenharmony_ci 1686e5c31af7Sopenharmony_ci log << TestLog::Message << "// Note: calling glUseProgram with a unused program (will only use the real program once it's needed for rendering)" << TestLog::EndMessage; 1687e5c31af7Sopenharmony_ci glUseProgram(unusedProgram.getProgram()); 1688e5c31af7Sopenharmony_ci 1689e5c31af7Sopenharmony_ci const bool success = test(basicUniforms, basicUniformReportsRef, program, rnd); 1690e5c31af7Sopenharmony_ci m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 1691e5c31af7Sopenharmony_ci success ? "Passed" : "Failed"); 1692e5c31af7Sopenharmony_ci 1693e5c31af7Sopenharmony_ci return STOP; 1694e5c31af7Sopenharmony_ci} 1695e5c31af7Sopenharmony_ci 1696e5c31af7Sopenharmony_ciclass UniformAssignCase : public UniformCase 1697e5c31af7Sopenharmony_ci{ 1698e5c31af7Sopenharmony_cipublic: 1699e5c31af7Sopenharmony_ci enum CheckMethod 1700e5c31af7Sopenharmony_ci { 1701e5c31af7Sopenharmony_ci CHECKMETHOD_GET_UNIFORM = 0, //!< Check values with glGetUniform*(). 1702e5c31af7Sopenharmony_ci CHECKMETHOD_RENDER, //!< Check values by rendering with the value-checking shader. 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci CHECKMETHOD_LAST 1705e5c31af7Sopenharmony_ci }; 1706e5c31af7Sopenharmony_ci enum AssignMethod 1707e5c31af7Sopenharmony_ci { 1708e5c31af7Sopenharmony_ci ASSIGNMETHOD_POINTER = 0, 1709e5c31af7Sopenharmony_ci ASSIGNMETHOD_VALUE, 1710e5c31af7Sopenharmony_ci 1711e5c31af7Sopenharmony_ci ASSIGNMETHOD_LAST 1712e5c31af7Sopenharmony_ci }; 1713e5c31af7Sopenharmony_ci 1714e5c31af7Sopenharmony_ci UniformAssignCase (Context& context, 1715e5c31af7Sopenharmony_ci const char* name, 1716e5c31af7Sopenharmony_ci const char* description, 1717e5c31af7Sopenharmony_ci CaseShaderType shaderType, 1718e5c31af7Sopenharmony_ci const SharedPtr<const UniformCollection>& uniformCollection, 1719e5c31af7Sopenharmony_ci CheckMethod checkMethod, 1720e5c31af7Sopenharmony_ci AssignMethod assignMethod, 1721e5c31af7Sopenharmony_ci deUint32 additionalFeatures = 0); 1722e5c31af7Sopenharmony_ci 1723e5c31af7Sopenharmony_ci bool test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd); 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_ci static const char* getCheckMethodName (CheckMethod checkMethod); 1726e5c31af7Sopenharmony_ci static const char* getCheckMethodDescription (CheckMethod checkMethod); 1727e5c31af7Sopenharmony_ci static const char* getAssignMethodName (AssignMethod checkMethod); 1728e5c31af7Sopenharmony_ci static const char* getAssignMethodDescription (AssignMethod checkMethod); 1729e5c31af7Sopenharmony_ci 1730e5c31af7Sopenharmony_ciprivate: 1731e5c31af7Sopenharmony_ci const CheckMethod m_checkMethod; 1732e5c31af7Sopenharmony_ci}; 1733e5c31af7Sopenharmony_ci 1734e5c31af7Sopenharmony_ciconst char* UniformAssignCase::getCheckMethodName (const CheckMethod checkMethod) 1735e5c31af7Sopenharmony_ci{ 1736e5c31af7Sopenharmony_ci switch (checkMethod) 1737e5c31af7Sopenharmony_ci { 1738e5c31af7Sopenharmony_ci case CHECKMETHOD_GET_UNIFORM: return "get_uniform"; 1739e5c31af7Sopenharmony_ci case CHECKMETHOD_RENDER: return "render"; 1740e5c31af7Sopenharmony_ci default: DE_ASSERT(false); return DE_NULL; 1741e5c31af7Sopenharmony_ci } 1742e5c31af7Sopenharmony_ci} 1743e5c31af7Sopenharmony_ci 1744e5c31af7Sopenharmony_ciconst char* UniformAssignCase::getCheckMethodDescription (const CheckMethod checkMethod) 1745e5c31af7Sopenharmony_ci{ 1746e5c31af7Sopenharmony_ci switch (checkMethod) 1747e5c31af7Sopenharmony_ci { 1748e5c31af7Sopenharmony_ci case CHECKMETHOD_GET_UNIFORM: return "Verify values with glGetUniform*()"; 1749e5c31af7Sopenharmony_ci case CHECKMETHOD_RENDER: return "Verify values by rendering"; 1750e5c31af7Sopenharmony_ci default: DE_ASSERT(false); return DE_NULL; 1751e5c31af7Sopenharmony_ci } 1752e5c31af7Sopenharmony_ci} 1753e5c31af7Sopenharmony_ci 1754e5c31af7Sopenharmony_ciconst char* UniformAssignCase::getAssignMethodName (const AssignMethod assignMethod) 1755e5c31af7Sopenharmony_ci{ 1756e5c31af7Sopenharmony_ci switch (assignMethod) 1757e5c31af7Sopenharmony_ci { 1758e5c31af7Sopenharmony_ci case ASSIGNMETHOD_POINTER: return "by_pointer"; 1759e5c31af7Sopenharmony_ci case ASSIGNMETHOD_VALUE: return "by_value"; 1760e5c31af7Sopenharmony_ci default: DE_ASSERT(false); return DE_NULL; 1761e5c31af7Sopenharmony_ci } 1762e5c31af7Sopenharmony_ci} 1763e5c31af7Sopenharmony_ci 1764e5c31af7Sopenharmony_ciconst char* UniformAssignCase::getAssignMethodDescription (const AssignMethod assignMethod) 1765e5c31af7Sopenharmony_ci{ 1766e5c31af7Sopenharmony_ci switch (assignMethod) 1767e5c31af7Sopenharmony_ci { 1768e5c31af7Sopenharmony_ci case ASSIGNMETHOD_POINTER: return "Assign values by-pointer"; 1769e5c31af7Sopenharmony_ci case ASSIGNMETHOD_VALUE: return "Assign values by-value"; 1770e5c31af7Sopenharmony_ci default: DE_ASSERT(false); return DE_NULL; 1771e5c31af7Sopenharmony_ci } 1772e5c31af7Sopenharmony_ci} 1773e5c31af7Sopenharmony_ci 1774e5c31af7Sopenharmony_ciUniformAssignCase::UniformAssignCase (Context& context, 1775e5c31af7Sopenharmony_ci const char* const name, 1776e5c31af7Sopenharmony_ci const char* const description, 1777e5c31af7Sopenharmony_ci const CaseShaderType shaderType, 1778e5c31af7Sopenharmony_ci const SharedPtr<const UniformCollection>& uniformCollection, 1779e5c31af7Sopenharmony_ci const CheckMethod checkMethod, 1780e5c31af7Sopenharmony_ci const AssignMethod assignMethod, 1781e5c31af7Sopenharmony_ci const deUint32 additionalFeatures) 1782e5c31af7Sopenharmony_ci : UniformCase (context, name, description, shaderType, uniformCollection, 1783e5c31af7Sopenharmony_ci (assignMethod == ASSIGNMETHOD_VALUE ? FEATURE_UNIFORMFUNC_VALUE : 0) | additionalFeatures) 1784e5c31af7Sopenharmony_ci , m_checkMethod (checkMethod) 1785e5c31af7Sopenharmony_ci{ 1786e5c31af7Sopenharmony_ci DE_ASSERT(assignMethod != ASSIGNMETHOD_LAST); 1787e5c31af7Sopenharmony_ci} 1788e5c31af7Sopenharmony_ci 1789e5c31af7Sopenharmony_cibool UniformAssignCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd) 1790e5c31af7Sopenharmony_ci{ 1791e5c31af7Sopenharmony_ci DE_UNREF(basicUniformReportsRef); 1792e5c31af7Sopenharmony_ci 1793e5c31af7Sopenharmony_ci const deUint32 programGL = program.getProgram(); 1794e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1795e5c31af7Sopenharmony_ci 1796e5c31af7Sopenharmony_ci { 1797e5c31af7Sopenharmony_ci const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments"); 1798e5c31af7Sopenharmony_ci assignUniforms(basicUniforms, programGL, rnd); 1799e5c31af7Sopenharmony_ci } 1800e5c31af7Sopenharmony_ci 1801e5c31af7Sopenharmony_ci if (m_checkMethod == CHECKMETHOD_GET_UNIFORM) 1802e5c31af7Sopenharmony_ci { 1803e5c31af7Sopenharmony_ci vector<VarValue> values; 1804e5c31af7Sopenharmony_ci 1805e5c31af7Sopenharmony_ci { 1806e5c31af7Sopenharmony_ci const ScopedLogSection section(log, "GetUniforms", "Uniform value query"); 1807e5c31af7Sopenharmony_ci const bool success = getUniforms(values, basicUniforms, program.getProgram()); 1808e5c31af7Sopenharmony_ci 1809e5c31af7Sopenharmony_ci if (!success) 1810e5c31af7Sopenharmony_ci return false; 1811e5c31af7Sopenharmony_ci } 1812e5c31af7Sopenharmony_ci 1813e5c31af7Sopenharmony_ci { 1814e5c31af7Sopenharmony_ci const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values"); 1815e5c31af7Sopenharmony_ci const bool success = compareUniformValues(values, basicUniforms); 1816e5c31af7Sopenharmony_ci 1817e5c31af7Sopenharmony_ci if (!success) 1818e5c31af7Sopenharmony_ci return false; 1819e5c31af7Sopenharmony_ci } 1820e5c31af7Sopenharmony_ci } 1821e5c31af7Sopenharmony_ci else 1822e5c31af7Sopenharmony_ci { 1823e5c31af7Sopenharmony_ci DE_ASSERT(m_checkMethod == CHECKMETHOD_RENDER); 1824e5c31af7Sopenharmony_ci 1825e5c31af7Sopenharmony_ci const ScopedLogSection section(log, "RenderTest", "Render test"); 1826e5c31af7Sopenharmony_ci const bool success = renderTest(basicUniforms, program, rnd); 1827e5c31af7Sopenharmony_ci 1828e5c31af7Sopenharmony_ci if (!success) 1829e5c31af7Sopenharmony_ci return false; 1830e5c31af7Sopenharmony_ci } 1831e5c31af7Sopenharmony_ci 1832e5c31af7Sopenharmony_ci return true; 1833e5c31af7Sopenharmony_ci} 1834e5c31af7Sopenharmony_ci 1835e5c31af7Sopenharmony_ciProgramUniformTests::ProgramUniformTests (Context& context) 1836e5c31af7Sopenharmony_ci : TestCaseGroup(context, "program_uniform", "glProgramUniform*() tests") 1837e5c31af7Sopenharmony_ci{ 1838e5c31af7Sopenharmony_ci} 1839e5c31af7Sopenharmony_ci 1840e5c31af7Sopenharmony_ciProgramUniformTests::~ProgramUniformTests (void) 1841e5c31af7Sopenharmony_ci{ 1842e5c31af7Sopenharmony_ci} 1843e5c31af7Sopenharmony_ci 1844e5c31af7Sopenharmony_cinamespace 1845e5c31af7Sopenharmony_ci{ 1846e5c31af7Sopenharmony_ci 1847e5c31af7Sopenharmony_ci// \note Although this is only used in ProgramUniformTests::init, it needs to be defined here as it's used as a template argument. 1848e5c31af7Sopenharmony_cistruct UniformCollectionCase 1849e5c31af7Sopenharmony_ci{ 1850e5c31af7Sopenharmony_ci string namePrefix; 1851e5c31af7Sopenharmony_ci SharedPtr<const UniformCollection> uniformCollection; 1852e5c31af7Sopenharmony_ci 1853e5c31af7Sopenharmony_ci UniformCollectionCase (const char* const name, const UniformCollection* uniformCollection_) 1854e5c31af7Sopenharmony_ci : namePrefix (name ? name + string("_") : "") 1855e5c31af7Sopenharmony_ci , uniformCollection (uniformCollection_) 1856e5c31af7Sopenharmony_ci { 1857e5c31af7Sopenharmony_ci } 1858e5c31af7Sopenharmony_ci}; 1859e5c31af7Sopenharmony_ci 1860e5c31af7Sopenharmony_ci} // anonymous 1861e5c31af7Sopenharmony_ci 1862e5c31af7Sopenharmony_civoid ProgramUniformTests::init (void) 1863e5c31af7Sopenharmony_ci{ 1864e5c31af7Sopenharmony_ci // Generate sets of UniformCollections that are used by several cases. 1865e5c31af7Sopenharmony_ci 1866e5c31af7Sopenharmony_ci enum 1867e5c31af7Sopenharmony_ci { 1868e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_BASIC = 0, 1869e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_BASIC_ARRAY, 1870e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_BASIC_STRUCT, 1871e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY, 1872e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT, 1873e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS, 1874e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_MULTIPLE_BASIC, 1875e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY, 1876e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS, 1877e5c31af7Sopenharmony_ci 1878e5c31af7Sopenharmony_ci UNIFORMCOLLECTIONS_LAST 1879e5c31af7Sopenharmony_ci }; 1880e5c31af7Sopenharmony_ci 1881e5c31af7Sopenharmony_ci struct UniformCollectionGroup 1882e5c31af7Sopenharmony_ci { 1883e5c31af7Sopenharmony_ci string name; 1884e5c31af7Sopenharmony_ci vector<UniformCollectionCase> cases; 1885e5c31af7Sopenharmony_ci } defaultUniformCollections[UNIFORMCOLLECTIONS_LAST]; 1886e5c31af7Sopenharmony_ci 1887e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].name = "basic"; 1888e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].name = "basic_array"; 1889e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].name = "basic_struct"; 1890e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].name = "struct_in_array"; 1891e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].name = "array_in_struct"; 1892e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].name = "nested_structs_arrays"; 1893e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].name = "multiple_basic"; 1894e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].name = "multiple_basic_array"; 1895e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].name = "multiple_nested_structs_arrays"; 1896e5c31af7Sopenharmony_ci 1897e5c31af7Sopenharmony_ci for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_testDataTypes); dataTypeNdx++) 1898e5c31af7Sopenharmony_ci { 1899e5c31af7Sopenharmony_ci const glu::DataType dataType = s_testDataTypes[dataTypeNdx]; 1900e5c31af7Sopenharmony_ci const char* const typeName = glu::getDataTypeName(dataType); 1901e5c31af7Sopenharmony_ci 1902e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basic(dataType))); 1903e5c31af7Sopenharmony_ci 1904e5c31af7Sopenharmony_ci if (glu::isDataTypeScalar(dataType) || 1905e5c31af7Sopenharmony_ci (glu::isDataTypeVector(dataType) && glu::getDataTypeScalarSize(dataType) == 4) || 1906e5c31af7Sopenharmony_ci dataType == glu::TYPE_FLOAT_MAT4 || 1907e5c31af7Sopenharmony_ci dataType == glu::TYPE_SAMPLER_2D) 1908e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basicArray(dataType))); 1909e5c31af7Sopenharmony_ci 1910e5c31af7Sopenharmony_ci if (glu::isDataTypeScalar(dataType) || 1911e5c31af7Sopenharmony_ci dataType == glu::TYPE_FLOAT_MAT4 || 1912e5c31af7Sopenharmony_ci dataType == glu::TYPE_SAMPLER_2D) 1913e5c31af7Sopenharmony_ci { 1914e5c31af7Sopenharmony_ci const glu::DataType secondDataType = glu::isDataTypeScalar(dataType) ? glu::getDataTypeVector(dataType, 4) 1915e5c31af7Sopenharmony_ci : dataType == glu::TYPE_FLOAT_MAT4 ? glu::TYPE_FLOAT_MAT2 1916e5c31af7Sopenharmony_ci : dataType == glu::TYPE_SAMPLER_2D ? glu::TYPE_SAMPLER_CUBE 1917e5c31af7Sopenharmony_ci : glu::TYPE_LAST; 1918e5c31af7Sopenharmony_ci DE_ASSERT(secondDataType != glu::TYPE_LAST); 1919e5c31af7Sopenharmony_ci const char* const secondTypeName = glu::getDataTypeName(secondDataType); 1920e5c31af7Sopenharmony_ci const string name = string("") + typeName + "_" + secondTypeName; 1921e5c31af7Sopenharmony_ci 1922e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].cases.push_back (UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, false))); 1923e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].cases.push_back (UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, true))); 1924e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].cases.push_back (UniformCollectionCase(name.c_str(), UniformCollection::structInArray(dataType, secondDataType, false))); 1925e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].cases.push_back (UniformCollectionCase(name.c_str(), UniformCollection::nestedArraysStructs(dataType, secondDataType))); 1926e5c31af7Sopenharmony_ci } 1927e5c31af7Sopenharmony_ci } 1928e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].cases.push_back (UniformCollectionCase(DE_NULL, UniformCollection::multipleBasic())); 1929e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].cases.push_back (UniformCollectionCase(DE_NULL, UniformCollection::multipleBasicArray())); 1930e5c31af7Sopenharmony_ci defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push_back (UniformCollectionCase(DE_NULL, UniformCollection::multipleNestedArraysStructs())); 1931e5c31af7Sopenharmony_ci 1932e5c31af7Sopenharmony_ci // Basic by-pointer or by-value uniform assignment cases. 1933e5c31af7Sopenharmony_ci 1934e5c31af7Sopenharmony_ci for (int assignMethodI = 0; assignMethodI < (int)UniformAssignCase::ASSIGNMETHOD_LAST; assignMethodI++) 1935e5c31af7Sopenharmony_ci { 1936e5c31af7Sopenharmony_ci const UniformAssignCase::AssignMethod assignMethod = (UniformAssignCase::AssignMethod)assignMethodI; 1937e5c31af7Sopenharmony_ci TestCaseGroup* const assignMethodGroup = new TestCaseGroup(m_context, UniformAssignCase::getAssignMethodName(assignMethod), UniformAssignCase::getAssignMethodDescription(assignMethod)); 1938e5c31af7Sopenharmony_ci addChild(assignMethodGroup); 1939e5c31af7Sopenharmony_ci 1940e5c31af7Sopenharmony_ci for (int checkMethodI = 0; checkMethodI < (int)UniformAssignCase::CHECKMETHOD_LAST; checkMethodI++) 1941e5c31af7Sopenharmony_ci { 1942e5c31af7Sopenharmony_ci const UniformAssignCase::CheckMethod checkMethod = (UniformAssignCase::CheckMethod)checkMethodI; 1943e5c31af7Sopenharmony_ci TestCaseGroup* const checkMethodGroup = new TestCaseGroup(m_context, UniformAssignCase::getCheckMethodName(checkMethod), UniformAssignCase::getCheckMethodDescription(checkMethod)); 1944e5c31af7Sopenharmony_ci assignMethodGroup->addChild(checkMethodGroup); 1945e5c31af7Sopenharmony_ci 1946e5c31af7Sopenharmony_ci for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++) 1947e5c31af7Sopenharmony_ci { 1948e5c31af7Sopenharmony_ci const int numArrayFirstElemNameCases = checkMethod == UniformAssignCase::CHECKMETHOD_GET_UNIFORM && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1; 1949e5c31af7Sopenharmony_ci 1950e5c31af7Sopenharmony_ci for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++) 1951e5c31af7Sopenharmony_ci { 1952e5c31af7Sopenharmony_ci const UniformCollectionGroup& collectionGroup = defaultUniformCollections[collectionGroupNdx]; 1953e5c31af7Sopenharmony_ci const string collectionGroupName = collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets"); 1954e5c31af7Sopenharmony_ci TestCaseGroup* collectionTestGroup = DE_NULL; 1955e5c31af7Sopenharmony_ci 1956e5c31af7Sopenharmony_ci for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++) 1957e5c31af7Sopenharmony_ci { 1958e5c31af7Sopenharmony_ci const UniformCollectionCase& collectionCase = collectionGroup.cases[collectionNdx]; 1959e5c31af7Sopenharmony_ci const string collName = collectionCase.namePrefix; 1960e5c31af7Sopenharmony_ci const SharedPtr<const UniformCollection>& uniformCollection = collectionCase.uniformCollection; 1961e5c31af7Sopenharmony_ci const bool containsBooleans = uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec); 1962e5c31af7Sopenharmony_ci const bool varyBoolApiType = checkMethod == UniformAssignCase::CHECKMETHOD_GET_UNIFORM && containsBooleans && 1963e5c31af7Sopenharmony_ci (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY); 1964e5c31af7Sopenharmony_ci const int numBoolVariations = varyBoolApiType ? 3 : 1; 1965e5c31af7Sopenharmony_ci const bool containsMatrices = uniformCollection->containsMatchingBasicType(glu::isDataTypeMatrix); 1966e5c31af7Sopenharmony_ci const bool varyMatrixMode = containsMatrices && 1967e5c31af7Sopenharmony_ci (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY); 1968e5c31af7Sopenharmony_ci const int numMatVariations = varyMatrixMode ? 2 : 1; 1969e5c31af7Sopenharmony_ci 1970e5c31af7Sopenharmony_ci if (containsMatrices && assignMethod != UniformAssignCase::ASSIGNMETHOD_POINTER) 1971e5c31af7Sopenharmony_ci continue; 1972e5c31af7Sopenharmony_ci 1973e5c31af7Sopenharmony_ci for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++) 1974e5c31af7Sopenharmony_ci { 1975e5c31af7Sopenharmony_ci const deUint32 booleanTypeFeat = booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT 1976e5c31af7Sopenharmony_ci : booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT 1977e5c31af7Sopenharmony_ci : 0; 1978e5c31af7Sopenharmony_ci const char* const booleanTypeName = booleanTypeI == 1 ? "int" 1979e5c31af7Sopenharmony_ci : booleanTypeI == 2 ? "uint" 1980e5c31af7Sopenharmony_ci : "float"; 1981e5c31af7Sopenharmony_ci const string nameWithBoolType = varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName; 1982e5c31af7Sopenharmony_ci 1983e5c31af7Sopenharmony_ci for (int matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++) 1984e5c31af7Sopenharmony_ci { 1985e5c31af7Sopenharmony_ci const string nameWithMatrixType = nameWithBoolType + (matrixTypeI == 1 ? "row_major_" : ""); 1986e5c31af7Sopenharmony_ci 1987e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++) 1988e5c31af7Sopenharmony_ci { 1989e5c31af7Sopenharmony_ci const string name = nameWithMatrixType + getCaseShaderTypeName((CaseShaderType)shaderType); 1990e5c31af7Sopenharmony_ci const deUint32 arrayFirstElemNameNoIndexFeat = referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX; 1991e5c31af7Sopenharmony_ci 1992e5c31af7Sopenharmony_ci // skip empty groups by creating groups on demand 1993e5c31af7Sopenharmony_ci if (!collectionTestGroup) 1994e5c31af7Sopenharmony_ci { 1995e5c31af7Sopenharmony_ci collectionTestGroup = new TestCaseGroup(m_context, collectionGroupName.c_str(), ""); 1996e5c31af7Sopenharmony_ci checkMethodGroup->addChild(collectionTestGroup); 1997e5c31af7Sopenharmony_ci } 1998e5c31af7Sopenharmony_ci 1999e5c31af7Sopenharmony_ci collectionTestGroup->addChild(new UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection, 2000e5c31af7Sopenharmony_ci checkMethod, assignMethod, 2001e5c31af7Sopenharmony_ci booleanTypeFeat | arrayFirstElemNameNoIndexFeat | (matrixTypeI == 1 ? UniformCase::FEATURE_MATRIXMODE_ROWMAJOR : 0))); 2002e5c31af7Sopenharmony_ci } 2003e5c31af7Sopenharmony_ci } 2004e5c31af7Sopenharmony_ci } 2005e5c31af7Sopenharmony_ci } 2006e5c31af7Sopenharmony_ci } 2007e5c31af7Sopenharmony_ci } 2008e5c31af7Sopenharmony_ci } 2009e5c31af7Sopenharmony_ci } 2010e5c31af7Sopenharmony_ci 2011e5c31af7Sopenharmony_ci // Cases that assign multiple basic-array elements with one glProgramUniform*v() (i.e. the count parameter is bigger than 1). 2012e5c31af7Sopenharmony_ci 2013e5c31af7Sopenharmony_ci { 2014e5c31af7Sopenharmony_ci static const struct 2015e5c31af7Sopenharmony_ci { 2016e5c31af7Sopenharmony_ci UniformCase::Feature arrayAssignMode; 2017e5c31af7Sopenharmony_ci const char* name; 2018e5c31af7Sopenharmony_ci const char* description; 2019e5c31af7Sopenharmony_ci } arrayAssignGroups[] = 2020e5c31af7Sopenharmony_ci { 2021e5c31af7Sopenharmony_ci { UniformCase::FEATURE_ARRAYASSIGN_FULL, "basic_array_assign_full", "Assign entire basic-type arrays per glProgramUniform*v() call" }, 2022e5c31af7Sopenharmony_ci { UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO, "basic_array_assign_partial", "Assign two elements of a basic-type array per glProgramUniform*v() call" } 2023e5c31af7Sopenharmony_ci }; 2024e5c31af7Sopenharmony_ci 2025e5c31af7Sopenharmony_ci for (int arrayAssignGroupNdx = 0; arrayAssignGroupNdx < DE_LENGTH_OF_ARRAY(arrayAssignGroups); arrayAssignGroupNdx++) 2026e5c31af7Sopenharmony_ci { 2027e5c31af7Sopenharmony_ci UniformCase::Feature arrayAssignMode = arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode; 2028e5c31af7Sopenharmony_ci const char* const groupName = arrayAssignGroups[arrayAssignGroupNdx].name; 2029e5c31af7Sopenharmony_ci const char* const groupDesc = arrayAssignGroups[arrayAssignGroupNdx].description; 2030e5c31af7Sopenharmony_ci 2031e5c31af7Sopenharmony_ci TestCaseGroup* const curArrayAssignGroup = new TestCaseGroup(m_context, groupName, groupDesc); 2032e5c31af7Sopenharmony_ci addChild(curArrayAssignGroup); 2033e5c31af7Sopenharmony_ci 2034e5c31af7Sopenharmony_ci static const int basicArrayCollectionGroups[] = { UNIFORMCOLLECTIONS_BASIC_ARRAY, UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT, UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY }; 2035e5c31af7Sopenharmony_ci 2036e5c31af7Sopenharmony_ci for (int collectionGroupNdx = 0; collectionGroupNdx < DE_LENGTH_OF_ARRAY(basicArrayCollectionGroups); collectionGroupNdx++) 2037e5c31af7Sopenharmony_ci { 2038e5c31af7Sopenharmony_ci const UniformCollectionGroup& collectionGroup = defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]]; 2039e5c31af7Sopenharmony_ci TestCaseGroup* const collectionTestGroup = new TestCaseGroup(m_context, collectionGroup.name.c_str(), ""); 2040e5c31af7Sopenharmony_ci curArrayAssignGroup->addChild(collectionTestGroup); 2041e5c31af7Sopenharmony_ci 2042e5c31af7Sopenharmony_ci for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++) 2043e5c31af7Sopenharmony_ci { 2044e5c31af7Sopenharmony_ci const UniformCollectionCase& collectionCase = collectionGroup.cases[collectionNdx]; 2045e5c31af7Sopenharmony_ci const string collName = collectionCase.namePrefix; 2046e5c31af7Sopenharmony_ci const SharedPtr<const UniformCollection>& uniformCollection = collectionCase.uniformCollection; 2047e5c31af7Sopenharmony_ci 2048e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++) 2049e5c31af7Sopenharmony_ci { 2050e5c31af7Sopenharmony_ci const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType); 2051e5c31af7Sopenharmony_ci collectionTestGroup->addChild(new UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection, 2052e5c31af7Sopenharmony_ci UniformAssignCase::CHECKMETHOD_GET_UNIFORM, UniformAssignCase::ASSIGNMETHOD_POINTER, 2053e5c31af7Sopenharmony_ci arrayAssignMode)); 2054e5c31af7Sopenharmony_ci } 2055e5c31af7Sopenharmony_ci } 2056e5c31af7Sopenharmony_ci } 2057e5c31af7Sopenharmony_ci } 2058e5c31af7Sopenharmony_ci } 2059e5c31af7Sopenharmony_ci 2060e5c31af7Sopenharmony_ci // Cases with unused uniforms. 2061e5c31af7Sopenharmony_ci 2062e5c31af7Sopenharmony_ci { 2063e5c31af7Sopenharmony_ci TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms"); 2064e5c31af7Sopenharmony_ci addChild(unusedUniformsGroup); 2065e5c31af7Sopenharmony_ci 2066e5c31af7Sopenharmony_ci const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT]; 2067e5c31af7Sopenharmony_ci 2068e5c31af7Sopenharmony_ci for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++) 2069e5c31af7Sopenharmony_ci { 2070e5c31af7Sopenharmony_ci const UniformCollectionCase& collectionCase = collectionGroup.cases[collectionNdx]; 2071e5c31af7Sopenharmony_ci const string collName = collectionCase.namePrefix; 2072e5c31af7Sopenharmony_ci const SharedPtr<const UniformCollection>& uniformCollection = collectionCase.uniformCollection; 2073e5c31af7Sopenharmony_ci 2074e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++) 2075e5c31af7Sopenharmony_ci { 2076e5c31af7Sopenharmony_ci const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType); 2077e5c31af7Sopenharmony_ci unusedUniformsGroup->addChild(new UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection, 2078e5c31af7Sopenharmony_ci UniformAssignCase::CHECKMETHOD_GET_UNIFORM, UniformAssignCase::ASSIGNMETHOD_POINTER, 2079e5c31af7Sopenharmony_ci UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX | UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER)); 2080e5c31af7Sopenharmony_ci } 2081e5c31af7Sopenharmony_ci } 2082e5c31af7Sopenharmony_ci } 2083e5c31af7Sopenharmony_ci} 2084e5c31af7Sopenharmony_ci 2085e5c31af7Sopenharmony_ci} // Functional 2086e5c31af7Sopenharmony_ci} // gles31 2087e5c31af7Sopenharmony_ci} // deqp 2088