glsRandomUniformBlockCase.js (14564B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ 20 21 'use strict'; 22 goog.provide('modules.shared.glsRandomUniformBlockCase'); 23 goog.require('framework.common.tcuTestCase'); 24 goog.require('framework.delibs.debase.deMath'); 25 goog.require('framework.delibs.debase.deRandom'); 26 goog.require('framework.opengl.gluShaderUtil'); 27 goog.require('modules.shared.glsUniformBlockCase'); 28 29 goog.scope(function() { 30 31 var glsRandomUniformBlockCase = modules.shared.glsRandomUniformBlockCase; 32 var gluShaderUtil = framework.opengl.gluShaderUtil; 33 var glsUniformBlockCase = modules.shared.glsUniformBlockCase; 34 var tcuTestCase = framework.common.tcuTestCase; 35 var deMath = framework.delibs.debase.deMath; 36 var deRandom = framework.delibs.debase.deRandom; 37 38 glsRandomUniformBlockCase.FeatureBits = { 39 FEATURE_VECTORS: (1 << 0), 40 FEATURE_MATRICES: (1 << 1), 41 FEATURE_ARRAYS: (1 << 2), 42 FEATURE_STRUCTS: (1 << 3), 43 FEATURE_NESTED_STRUCTS: (1 << 4), 44 FEATURE_INSTANCE_ARRAYS: (1 << 5), 45 FEATURE_VERTEX_BLOCKS: (1 << 6), 46 FEATURE_FRAGMENT_BLOCKS: (1 << 7), 47 FEATURE_SHARED_BLOCKS: (1 << 8), 48 FEATURE_UNUSED_UNIFORMS: (1 << 9), 49 FEATURE_UNUSED_MEMBERS: (1 << 10), 50 FEATURE_PACKED_LAYOUT: (1 << 11), 51 FEATURE_SHARED_LAYOUT: (1 << 12), 52 FEATURE_STD140_LAYOUT: (1 << 13), 53 FEATURE_MATRIX_LAYOUT: (1 << 14), //!< Matrix layout flags. 54 FEATURE_ARRAYS_OF_ARRAYS: (1 << 15) 55 }; 56 57 /** 58 * glsRandomUniformBlockCase.RandomUniformBlockCase class 59 * @param {string} name 60 * @param {string} description 61 * @param {glsUniformBlockCase.BufferMode} bufferMode 62 * @param {number} features 63 * @param {number} seed 64 * @constructor 65 * @extends {glsUniformBlockCase.UniformBlockCase} 66 */ 67 glsRandomUniformBlockCase.RandomUniformBlockCase = function(name, description, bufferMode, features, seed) { 68 glsUniformBlockCase.UniformBlockCase.call(this, name, description, bufferMode); 69 this.m_features = features; 70 this.m_maxVertexBlocks = ((features & glsRandomUniformBlockCase.FeatureBits.FEATURE_VERTEX_BLOCKS) ? 4 : 0); 71 this.m_maxFragmentBlocks = ((features & glsRandomUniformBlockCase.FeatureBits.FEATURE_FRAGMENT_BLOCKS) ? 4 : 0); 72 this.m_maxSharedBlocks = ((features & glsRandomUniformBlockCase.FeatureBits.FEATURE_SHARED_BLOCKS) ? 4 : 0); 73 this.m_maxInstances = ((features & glsRandomUniformBlockCase.FeatureBits.FEATURE_INSTANCE_ARRAYS) ? 3 : 0); 74 this.m_maxArrayLength = ((features & glsRandomUniformBlockCase.FeatureBits.FEATURE_ARRAYS) ? 8 : 0); 75 this.m_maxStructDepth = ((features & glsRandomUniformBlockCase.FeatureBits.FEATURE_STRUCTS) ? 2 : 0); 76 this.m_maxBlockMembers = 5; 77 this.m_maxStructMembers = 4; 78 this.m_seed = seed; 79 this.m_blockNdx = 1; 80 this.m_uniformNdx = 1; 81 this.m_structNdx = 1; 82 }; 83 84 glsRandomUniformBlockCase.RandomUniformBlockCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype); 85 glsRandomUniformBlockCase.RandomUniformBlockCase.prototype.constructor = glsRandomUniformBlockCase.RandomUniformBlockCase; 86 87 /** 88 * generateType 89 * @param {deRandom.Random} rnd 90 * @param {number} typeDepth 91 * @param {boolean} arrayOk 92 * @return {glsUniformBlockCase.VarType} 93 */ 94 glsRandomUniformBlockCase.RandomUniformBlockCase.prototype.generateType = function(rnd, typeDepth, arrayOk) { 95 /** @type {number} */ var structWeight = 0.1; 96 /** @type {number} */ var arrayWeight = 0.1; 97 /** @type {number} */ var flags; 98 99 if (typeDepth < this.m_maxStructDepth && rnd.getFloat() < structWeight) { 100 /** @type {number} */ var unusedVtxWeight = 0.15; 101 /** @type {number} */ var unusedFragWeight = 0.15; 102 /** @type {boolean} */ var unusedOk = (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_UNUSED_MEMBERS) != 0; 103 /** @type {Array<glsUniformBlockCase.VarType>} */ var memberTypes = []; 104 /** @type {number} */ var numMembers = rnd.getInt(1, this.m_maxStructMembers); 105 106 // Generate members first so nested struct declarations are in correct order. 107 for (var ndx = 0; ndx < numMembers; ndx++) 108 memberTypes.push(this.generateType(rnd, typeDepth + 1, true)); 109 110 /** @type {glsUniformBlockCase.StructType} */ var structType = this.m_interface.allocStruct('s' + this.genName('A'.charCodeAt(0), 'Z'.charCodeAt(0), this.m_structNdx)); 111 this.m_structNdx += 1; 112 113 assertMsgOptions(this.m_blockNdx <= 'Z'.charCodeAt(0) - 'A'.charCodeAt(0), 'generateType', false, true); 114 for (var ndx = 0; ndx < numMembers; ndx++) { 115 flags = 0; 116 117 flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? glsUniformBlockCase.UniformFlags.UNUSED_VERTEX : 0; 118 flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? glsUniformBlockCase.UniformFlags.UNUSED_FRAGMENT : 0; 119 120 structType.addMember('m' + ('A'.charCodeAt(0) + ndx), memberTypes[ndx], flags); 121 } 122 123 return glsUniformBlockCase.newVarTypeStruct(structType); 124 } else if (this.m_maxArrayLength > 0 && arrayOk && rnd.getFloat() < arrayWeight) { 125 /** @type {boolean} */ var arraysOfArraysOk = (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_ARRAYS_OF_ARRAYS) != 0; 126 /** @type {number} */ var arrayLength = rnd.getInt(1, this.m_maxArrayLength); 127 /** @type {glsUniformBlockCase.VarType} */ var elementType = this.generateType(rnd, typeDepth, arraysOfArraysOk); 128 return glsUniformBlockCase.newVarTypeArray(elementType, arrayLength); 129 } else { 130 /** @type {Array<gluShaderUtil.DataType>} */ var typeCandidates = []; 131 132 typeCandidates.push(gluShaderUtil.DataType.FLOAT); 133 typeCandidates.push(gluShaderUtil.DataType.INT); 134 typeCandidates.push(gluShaderUtil.DataType.UINT); 135 typeCandidates.push(gluShaderUtil.DataType.BOOL); 136 137 if (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_VECTORS) { 138 typeCandidates.push(gluShaderUtil.DataType.FLOAT_VEC2); 139 typeCandidates.push(gluShaderUtil.DataType.FLOAT_VEC3); 140 typeCandidates.push(gluShaderUtil.DataType.FLOAT_VEC4); 141 typeCandidates.push(gluShaderUtil.DataType.INT_VEC2); 142 typeCandidates.push(gluShaderUtil.DataType.INT_VEC3); 143 typeCandidates.push(gluShaderUtil.DataType.INT_VEC4); 144 typeCandidates.push(gluShaderUtil.DataType.UINT_VEC2); 145 typeCandidates.push(gluShaderUtil.DataType.UINT_VEC3); 146 typeCandidates.push(gluShaderUtil.DataType.UINT_VEC4); 147 typeCandidates.push(gluShaderUtil.DataType.BOOL_VEC2); 148 typeCandidates.push(gluShaderUtil.DataType.BOOL_VEC3); 149 typeCandidates.push(gluShaderUtil.DataType.BOOL_VEC4); 150 } 151 152 if (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_MATRICES) { 153 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT2); 154 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT2X3); 155 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT3X2); 156 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT3); 157 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT3X4); 158 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT4X2); 159 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT4X3); 160 typeCandidates.push(gluShaderUtil.DataType.FLOAT_MAT4); 161 } 162 163 /** @type {gluShaderUtil.DataType} */ var type = (rnd.choose(typeCandidates)[0]); 164 flags = 0; 165 166 if (!gluShaderUtil.isDataTypeBoolOrBVec(type)) { 167 // Precision. 168 /** @type {Array<number>} */ var precisionCandidates = [glsUniformBlockCase.UniformFlags.PRECISION_LOW, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM, glsUniformBlockCase.UniformFlags.PRECISION_HIGH]; 169 flags |= rnd.choose(precisionCandidates)[0]; 170 } 171 172 return glsUniformBlockCase.newVarTypeBasic(type, flags); 173 } 174 }; 175 176 /** 177 * genName 178 * @param {number} first 179 * @param {number} last 180 * @param {number} ndx 181 * @return {string} 182 */ 183 glsRandomUniformBlockCase.RandomUniformBlockCase.prototype.genName = function(first, last, ndx) { 184 /** @type {string} */ var str = ''; 185 /** @type {number} */ var alphabetLen = last - first + 1; 186 187 while (ndx > alphabetLen) { 188 str = String.fromCharCode(first + ((ndx - 1) % alphabetLen)) + str; 189 ndx = Math.floor((ndx - 1) / alphabetLen); 190 } 191 192 str = String.fromCharCode(first + (ndx % (alphabetLen + 1)) - 1) + str; 193 194 return str; 195 }; 196 197 /** 198 * generateUniform 199 * @param {deRandom.Random} rnd 200 * @param {glsUniformBlockCase.UniformBlock} block 201 */ 202 glsRandomUniformBlockCase.RandomUniformBlockCase.prototype.generateUniform = function(rnd, block) { 203 /** @type {number} */ var unusedVtxWeight = 0.15; 204 /** @type {number} */ var unusedFragWeight = 0.15; 205 /** @type {boolean} */ var unusedOk = (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_UNUSED_UNIFORMS) != 0; 206 /** @type {number} */ var flags = 0; 207 /** @type {string} */ var name = this.genName('a'.charCodeAt(0), 'z'.charCodeAt(0), this.m_uniformNdx); 208 /** @type {glsUniformBlockCase.VarType} */ var type = this.generateType(rnd, 0, true); //TODO: implement this. 209 210 flags |= (unusedOk && rnd.getFloat() < unusedVtxWeight) ? glsUniformBlockCase.UniformFlags.UNUSED_VERTEX : 0; 211 flags |= (unusedOk && rnd.getFloat() < unusedFragWeight) ? glsUniformBlockCase.UniformFlags.UNUSED_FRAGMENT : 0; 212 213 block.addUniform(new glsUniformBlockCase.Uniform(name, type, flags)); 214 215 this.m_uniformNdx += 1; 216 }; 217 218 /** 219 * generateBlock 220 * @param {deRandom.Random} rnd 221 * @param {number} layoutFlags 222 */ 223 glsRandomUniformBlockCase.RandomUniformBlockCase.prototype.generateBlock = function(rnd, layoutFlags) { 224 assertMsgOptions(this.m_blockNdx <= 'z'.charCodeAt(0) - 'a'.charCodeAt(0), 'generateBlock', false, true); 225 226 /** @type {number} */ var instanceArrayWeight = 0.3; 227 /** @type {glsUniformBlockCase.UniformBlock} */ var block = this.m_interface.allocBlock('Block' + String.fromCharCode('A'.charCodeAt(0) + this.m_blockNdx)); 228 /** @type {number} */ var numInstances = (this.m_maxInstances > 0 && rnd.getFloat() < instanceArrayWeight) ? rnd.getInt(0, this.m_maxInstances) : 0; 229 /** @type {number} */ var numUniforms = rnd.getInt(1, this.m_maxBlockMembers); 230 231 if (numInstances > 0) 232 block.setArraySize(numInstances); 233 234 if (numInstances > 0 || rnd.getBool()) 235 block.setInstanceName('block' + String.fromCharCode('A'.charCodeAt(0) + this.m_blockNdx)); 236 237 // Layout flag candidates. 238 /** @type {Array<number>} */ var layoutFlagCandidates = []; 239 layoutFlagCandidates.push(0); 240 if (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_PACKED_LAYOUT) 241 layoutFlagCandidates.push(glsUniformBlockCase.UniformFlags.LAYOUT_SHARED); 242 if ((this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_SHARED_LAYOUT) && ((layoutFlags & glsUniformBlockCase.UniformFlags.DECLARE_BOTH) != glsUniformBlockCase.UniformFlags.DECLARE_BOTH)) 243 layoutFlagCandidates.push(glsUniformBlockCase.UniformFlags.LAYOUT_PACKED); // \note packed layout can only be used in a single shader stage. 244 if (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_STD140_LAYOUT) 245 layoutFlagCandidates.push(glsUniformBlockCase.UniformFlags.LAYOUT_STD140); 246 247 layoutFlags |= rnd.choose(layoutFlagCandidates)[0]; //In Javascript, this function returns an array, so taking element 0. 248 249 if (this.m_features & glsRandomUniformBlockCase.FeatureBits.FEATURE_MATRIX_LAYOUT) { 250 /** @type {Array<number>}*/ var matrixCandidates = [0, glsUniformBlockCase.UniformFlags.LAYOUT_ROW_MAJOR, glsUniformBlockCase.UniformFlags.LAYOUT_COLUMN_MAJOR]; 251 layoutFlags |= rnd.choose(matrixCandidates)[0]; 252 } 253 254 block.setFlags(layoutFlags); 255 256 for (var ndx = 0; ndx < numUniforms; ndx++) 257 this.generateUniform(rnd, block); 258 259 this.m_blockNdx += 1; 260 }; 261 262 /** 263 * Initializes the glsRandomUniformBlockCase.RandomUniformBlockCase 264 */ 265 glsRandomUniformBlockCase.RandomUniformBlockCase.prototype.init = function() { 266 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(this.m_seed); 267 268 /** @type {number} */ var numShared = this.m_maxSharedBlocks > 0 ? rnd.getInt(1, this.m_maxSharedBlocks) : 0; 269 /** @type {number} */ var numVtxBlocks = this.m_maxVertexBlocks - numShared > 0 ? rnd.getInt(1, this.m_maxVertexBlocks - numShared) : 0; 270 /** @type {number} */ var numFragBlocks = this.m_maxFragmentBlocks - numShared > 0 ? rnd.getInt(1, this.m_maxFragmentBlocks - numShared) : 0; 271 272 for (var ndx = 0; ndx < numShared; ndx++) 273 this.generateBlock(rnd, glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT); 274 275 for (var ndx = 0; ndx < numVtxBlocks; ndx++) 276 this.generateBlock(rnd, glsUniformBlockCase.UniformFlags.DECLARE_VERTEX); 277 278 for (var ndx = 0; ndx < numFragBlocks; ndx++) 279 this.generateBlock(rnd, glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT); 280 }; 281 282 });