1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) Module 3e5c31af7Sopenharmony_ci * ----------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Random uniform block layout case. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "glsRandomUniformBlockCase.hpp" 25e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 26e5c31af7Sopenharmony_ci#include "deRandom.hpp" 27e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ciusing std::string; 30e5c31af7Sopenharmony_ciusing std::vector; 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_cinamespace deqp 33e5c31af7Sopenharmony_ci{ 34e5c31af7Sopenharmony_cinamespace gls 35e5c31af7Sopenharmony_ci{ 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ciusing namespace gls::ub; 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ciRandomUniformBlockCase::RandomUniformBlockCase (tcu::TestContext& testCtx, 40e5c31af7Sopenharmony_ci glu::RenderContext& renderCtx, 41e5c31af7Sopenharmony_ci glu::GLSLVersion glslVersion, 42e5c31af7Sopenharmony_ci const char* name, 43e5c31af7Sopenharmony_ci const char* description, 44e5c31af7Sopenharmony_ci BufferMode bufferMode, 45e5c31af7Sopenharmony_ci deUint32 features, 46e5c31af7Sopenharmony_ci deUint32 seed) 47e5c31af7Sopenharmony_ci : UniformBlockCase (testCtx, renderCtx, name, description, glslVersion, bufferMode) 48e5c31af7Sopenharmony_ci , m_features (features) 49e5c31af7Sopenharmony_ci , m_maxVertexBlocks ((features & FEATURE_VERTEX_BLOCKS) ? 4 : 0) 50e5c31af7Sopenharmony_ci , m_maxFragmentBlocks ((features & FEATURE_FRAGMENT_BLOCKS) ? 4 : 0) 51e5c31af7Sopenharmony_ci , m_maxSharedBlocks ((features & FEATURE_SHARED_BLOCKS) ? 4 : 0) 52e5c31af7Sopenharmony_ci , m_maxInstances ((features & FEATURE_INSTANCE_ARRAYS) ? 3 : 0) 53e5c31af7Sopenharmony_ci , m_maxArrayLength ((features & FEATURE_ARRAYS) ? 8 : 0) 54e5c31af7Sopenharmony_ci , m_maxStructDepth ((features & FEATURE_STRUCTS) ? 2 : 0) 55e5c31af7Sopenharmony_ci , m_maxBlockMembers (5) 56e5c31af7Sopenharmony_ci , m_maxStructMembers (4) 57e5c31af7Sopenharmony_ci , m_seed (seed) 58e5c31af7Sopenharmony_ci , m_blockNdx (1) 59e5c31af7Sopenharmony_ci , m_uniformNdx (1) 60e5c31af7Sopenharmony_ci , m_structNdx (1) 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_ci} 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_civoid RandomUniformBlockCase::init (void) 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_ci de::Random rnd(m_seed); 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ci int numShared = m_maxSharedBlocks > 0 ? rnd.getInt(1, m_maxSharedBlocks) : 0; 69e5c31af7Sopenharmony_ci int numVtxBlocks = m_maxVertexBlocks-numShared > 0 ? rnd.getInt(1, m_maxVertexBlocks-numShared) : 0; 70e5c31af7Sopenharmony_ci int numFragBlocks = m_maxFragmentBlocks-numShared > 0 ? rnd.getInt(1, m_maxFragmentBlocks-numShared) : 0; 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numShared; ndx++) 73e5c31af7Sopenharmony_ci generateBlock(rnd, DECLARE_VERTEX|DECLARE_FRAGMENT); 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numVtxBlocks; ndx++) 76e5c31af7Sopenharmony_ci generateBlock(rnd, DECLARE_VERTEX); 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numFragBlocks; ndx++) 79e5c31af7Sopenharmony_ci generateBlock(rnd, DECLARE_FRAGMENT); 80e5c31af7Sopenharmony_ci} 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_civoid RandomUniformBlockCase::generateBlock (de::Random& rnd, deUint32 layoutFlags) 83e5c31af7Sopenharmony_ci{ 84e5c31af7Sopenharmony_ci DE_ASSERT(m_blockNdx <= 'z' - 'a'); 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ci const float instanceArrayWeight = 0.3f; 87e5c31af7Sopenharmony_ci UniformBlock& block = m_interface.allocBlock((string("Block") + (char)('A' + m_blockNdx)).c_str()); 88e5c31af7Sopenharmony_ci int numInstances = (m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, m_maxInstances) : 0; 89e5c31af7Sopenharmony_ci int numUniforms = rnd.getInt(1, m_maxBlockMembers); 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci if (numInstances > 0) 92e5c31af7Sopenharmony_ci block.setArraySize(numInstances); 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci if (numInstances > 0 || rnd.getBool()) 95e5c31af7Sopenharmony_ci block.setInstanceName((string("block") + (char)('A' + m_blockNdx)).c_str()); 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci // Layout flag candidates. 98e5c31af7Sopenharmony_ci vector<deUint32> layoutFlagCandidates; 99e5c31af7Sopenharmony_ci layoutFlagCandidates.push_back(0); 100e5c31af7Sopenharmony_ci if (m_features & FEATURE_PACKED_LAYOUT) 101e5c31af7Sopenharmony_ci layoutFlagCandidates.push_back(LAYOUT_SHARED); 102e5c31af7Sopenharmony_ci if ((m_features & FEATURE_SHARED_LAYOUT) && ((layoutFlags & DECLARE_BOTH) != DECLARE_BOTH)) 103e5c31af7Sopenharmony_ci layoutFlagCandidates.push_back(LAYOUT_PACKED); // \note packed layout can only be used in a single shader stage. 104e5c31af7Sopenharmony_ci if (m_features & FEATURE_STD140_LAYOUT) 105e5c31af7Sopenharmony_ci layoutFlagCandidates.push_back(LAYOUT_STD140); 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci layoutFlags |= rnd.choose<deUint32>(layoutFlagCandidates.begin(), layoutFlagCandidates.end()); 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci if (m_features & FEATURE_MATRIX_LAYOUT) 110e5c31af7Sopenharmony_ci { 111e5c31af7Sopenharmony_ci static const deUint32 matrixCandidates[] = { 0, LAYOUT_ROW_MAJOR, LAYOUT_COLUMN_MAJOR }; 112e5c31af7Sopenharmony_ci layoutFlags |= rnd.choose<deUint32>(&matrixCandidates[0], &matrixCandidates[DE_LENGTH_OF_ARRAY(matrixCandidates)]); 113e5c31af7Sopenharmony_ci } 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci block.setFlags(layoutFlags); 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numUniforms; ndx++) 118e5c31af7Sopenharmony_ci generateUniform(rnd, block); 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci m_blockNdx += 1; 121e5c31af7Sopenharmony_ci} 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_cistatic std::string genName (char first, char last, int ndx) 124e5c31af7Sopenharmony_ci{ 125e5c31af7Sopenharmony_ci std::string str = ""; 126e5c31af7Sopenharmony_ci int alphabetLen = last - first + 1; 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci while (ndx > alphabetLen) 129e5c31af7Sopenharmony_ci { 130e5c31af7Sopenharmony_ci str.insert(str.begin(), (char)(first + ((ndx-1)%alphabetLen))); 131e5c31af7Sopenharmony_ci ndx = ((ndx-1) / alphabetLen); 132e5c31af7Sopenharmony_ci } 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci str.insert(str.begin(), (char)(first + (ndx%(alphabetLen+1)) - 1)); 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci return str; 137e5c31af7Sopenharmony_ci} 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_civoid RandomUniformBlockCase::generateUniform (de::Random& rnd, UniformBlock& block) 140e5c31af7Sopenharmony_ci{ 141e5c31af7Sopenharmony_ci const float unusedVtxWeight = 0.15f; 142e5c31af7Sopenharmony_ci const float unusedFragWeight = 0.15f; 143e5c31af7Sopenharmony_ci bool unusedOk = (m_features & FEATURE_UNUSED_UNIFORMS) != 0; 144e5c31af7Sopenharmony_ci deUint32 flags = 0; 145e5c31af7Sopenharmony_ci std::string name = genName('a', 'z', m_uniformNdx); 146e5c31af7Sopenharmony_ci VarType type = generateType(rnd, 0, true); 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? UNUSED_VERTEX : 0; 149e5c31af7Sopenharmony_ci flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? UNUSED_FRAGMENT : 0; 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci block.addUniform(Uniform(name.c_str(), type, flags)); 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ci m_uniformNdx += 1; 154e5c31af7Sopenharmony_ci} 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ciVarType RandomUniformBlockCase::generateType (de::Random& rnd, int typeDepth, bool arrayOk) 157e5c31af7Sopenharmony_ci{ 158e5c31af7Sopenharmony_ci const float structWeight = 0.1f; 159e5c31af7Sopenharmony_ci const float arrayWeight = 0.1f; 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_ci if (typeDepth < m_maxStructDepth && rnd.getFloat() < structWeight) 162e5c31af7Sopenharmony_ci { 163e5c31af7Sopenharmony_ci const float unusedVtxWeight = 0.15f; 164e5c31af7Sopenharmony_ci const float unusedFragWeight = 0.15f; 165e5c31af7Sopenharmony_ci bool unusedOk = (m_features & FEATURE_UNUSED_MEMBERS) != 0; 166e5c31af7Sopenharmony_ci vector<VarType> memberTypes; 167e5c31af7Sopenharmony_ci int numMembers = rnd.getInt(1, m_maxStructMembers); 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci // Generate members first so nested struct declarations are in correct order. 170e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numMembers; ndx++) 171e5c31af7Sopenharmony_ci memberTypes.push_back(generateType(rnd, typeDepth+1, true)); 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci StructType& structType = m_interface.allocStruct((string("s") + genName('A', 'Z', m_structNdx)).c_str()); 174e5c31af7Sopenharmony_ci m_structNdx += 1; 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci DE_ASSERT(numMembers <= 'Z' - 'A'); 177e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numMembers; ndx++) 178e5c31af7Sopenharmony_ci { 179e5c31af7Sopenharmony_ci deUint32 flags = 0; 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? UNUSED_VERTEX : 0; 182e5c31af7Sopenharmony_ci flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? UNUSED_FRAGMENT : 0; 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci structType.addMember((string("m") + (char)('A' + ndx)).c_str(), memberTypes[ndx], flags); 185e5c31af7Sopenharmony_ci } 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci return VarType(&structType); 188e5c31af7Sopenharmony_ci } 189e5c31af7Sopenharmony_ci else if (m_maxArrayLength > 0 && arrayOk && rnd.getFloat() < arrayWeight) 190e5c31af7Sopenharmony_ci { 191e5c31af7Sopenharmony_ci const bool arraysOfArraysOk = (m_features & FEATURE_ARRAYS_OF_ARRAYS) != 0; 192e5c31af7Sopenharmony_ci const int arrayLength = rnd.getInt(1, m_maxArrayLength); 193e5c31af7Sopenharmony_ci VarType elementType = generateType(rnd, typeDepth, arraysOfArraysOk); 194e5c31af7Sopenharmony_ci return VarType(elementType, arrayLength); 195e5c31af7Sopenharmony_ci } 196e5c31af7Sopenharmony_ci else 197e5c31af7Sopenharmony_ci { 198e5c31af7Sopenharmony_ci vector<glu::DataType> typeCandidates; 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT); 201e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_INT); 202e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_UINT); 203e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_BOOL); 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci if (m_features & FEATURE_VECTORS) 206e5c31af7Sopenharmony_ci { 207e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_VEC2); 208e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_VEC3); 209e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_VEC4); 210e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_INT_VEC2); 211e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_INT_VEC3); 212e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_INT_VEC4); 213e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_UINT_VEC2); 214e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_UINT_VEC3); 215e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_UINT_VEC4); 216e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_BOOL_VEC2); 217e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_BOOL_VEC3); 218e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_BOOL_VEC4); 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci if (m_features & FEATURE_MATRICES) 222e5c31af7Sopenharmony_ci { 223e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT2); 224e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT2X3); 225e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X2); 226e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT3); 227e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT3X4); 228e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X2); 229e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT4X3); 230e5c31af7Sopenharmony_ci typeCandidates.push_back(glu::TYPE_FLOAT_MAT4); 231e5c31af7Sopenharmony_ci } 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci glu::DataType type = rnd.choose<glu::DataType>(typeCandidates.begin(), typeCandidates.end()); 234e5c31af7Sopenharmony_ci deUint32 flags = 0; 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci if (!glu::isDataTypeBoolOrBVec(type)) 237e5c31af7Sopenharmony_ci { 238e5c31af7Sopenharmony_ci // Precision. 239e5c31af7Sopenharmony_ci static const deUint32 precisionCandidates[] = { PRECISION_LOW, PRECISION_MEDIUM, PRECISION_HIGH }; 240e5c31af7Sopenharmony_ci flags |= rnd.choose<deUint32>(&precisionCandidates[0], &precisionCandidates[DE_LENGTH_OF_ARRAY(precisionCandidates)]); 241e5c31af7Sopenharmony_ci } 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci return VarType(type, flags); 244e5c31af7Sopenharmony_ci } 245e5c31af7Sopenharmony_ci} 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci} // gls 248e5c31af7Sopenharmony_ci} // deqp 249