es3fIndexedStateQueryTests.js (16624B)
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('functional.gles3.es3fIndexedStateQueryTests'); 23 goog.require('framework.common.tcuTestCase'); 24 goog.require('functional.gles3.es3fApiCase'); 25 26 goog.scope(function() { 27 var es3fIndexedStateQueryTests = functional.gles3.es3fIndexedStateQueryTests; 28 var tcuTestCase = framework.common.tcuTestCase; 29 var es3fApiCase = functional.gles3.es3fApiCase; 30 31 /** 32 * @constructor 33 * @extends {es3fApiCase.ApiCase} 34 * @param {string} name 35 * @param {string} description 36 */ 37 es3fIndexedStateQueryTests.TransformFeedbackCase = function(name, description) { 38 es3fApiCase.ApiCase.call(this, name, description, gl); 39 }; 40 41 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype = Object.create(es3fApiCase.ApiCase.prototype); 42 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackCase; 43 44 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.testTransformFeedback = function() { 45 throw new Error('This method should be overriden.'); 46 }; 47 48 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.test = function() { 49 /** @type {string} */ var transformFeedbackTestVertSource = '' + 50 '#version 300 es\n' + 51 'out highp vec4 anotherOutput;\n' + 52 'void main (void)\n' + 53 '{\n' + 54 ' gl_Position = vec4(0.0);\n' + 55 ' anotherOutput = vec4(0.0);\n' + 56 '}\n'; 57 /** @type {string} */ var transformFeedbackTestFragSource = '' + 58 '#version 300 es\n' + 59 'layout(location = 0) out mediump vec4 fragColor;' + 60 'void main (void)\n' + 61 '{\n' + 62 ' fragColor = vec4(0.0);\n' + 63 '}\n'; 64 65 /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER); 66 /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER); 67 68 gl.shaderSource(shaderVert, transformFeedbackTestVertSource); 69 gl.shaderSource(shaderFrag, transformFeedbackTestFragSource); 70 71 gl.compileShader(shaderVert); 72 gl.compileShader(shaderFrag); 73 74 /** @type {WebGLProgram} */ var shaderProg = gl.createProgram(); 75 gl.attachShader(shaderProg, shaderVert); 76 gl.attachShader(shaderProg, shaderFrag); 77 78 /** @type {Array<string>} */ var transformFeedbackOutputs = ['gl_Position', 'anotherOutput']; 79 80 gl.transformFeedbackVaryings(shaderProg, transformFeedbackOutputs, gl.INTERLEAVED_ATTRIBS); 81 gl.linkProgram(shaderProg); 82 83 /** @type {WebGLTransformFeedback} */ var transformFeedbackId = gl.createTransformFeedback(); 84 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackId); 85 86 this.testTransformFeedback(); 87 88 // cleanup 89 90 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); 91 92 gl.deleteTransformFeedback(transformFeedbackId); 93 gl.deleteShader(shaderVert); 94 gl.deleteShader(shaderFrag); 95 gl.deleteProgram(shaderProg); 96 }; 97 98 /** 99 * @constructor 100 * @extends {es3fIndexedStateQueryTests.TransformFeedbackCase} 101 * @param {string} name 102 * @param {string} description 103 */ 104 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase = function(name, description) { 105 es3fIndexedStateQueryTests.TransformFeedbackCase.call(this, name, description); 106 }; 107 108 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype = Object.create(es3fIndexedStateQueryTests.TransformFeedbackCase.prototype); 109 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase; 110 111 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype.testTransformFeedback = function() { 112 /** @type {number} */ var feedbackPositionIndex = 0; 113 /** @type {number} */ var feedbackOutputIndex = 1; 114 /** @type {Array<number>} */ var feedbackIndex = [feedbackPositionIndex, feedbackOutputIndex]; 115 116 // bind buffers 117 118 /** @type {Array<WebGLBuffer>} */ var feedbackBuffers = []; 119 for (var ndx = 0; ndx < 2; ndx++) 120 feedbackBuffers[ndx] = gl.createBuffer(); 121 122 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) { 123 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[ndx]); 124 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ); 125 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackIndex[ndx], feedbackBuffers[ndx]); 126 } 127 128 // test TRANSFORM_FEEDBACK_BUFFER_BINDING 129 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) { 130 var boundBuffer = /** @type {WebGLBuffer} */ (gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, ndx)); 131 this.check(boundBuffer === feedbackBuffers[ndx], 'buffers do not match'); 132 } 133 134 // cleanup 135 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) 136 gl.deleteBuffer(feedbackBuffers[ndx]); 137 }; 138 139 /** 140 * @constructor 141 * @extends {es3fIndexedStateQueryTests.TransformFeedbackCase} 142 * @param {string} name 143 * @param {string} description 144 */ 145 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase = function(name, description) { 146 es3fIndexedStateQueryTests.TransformFeedbackCase.call(this, name, description); 147 }; 148 149 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype = Object.create(es3fIndexedStateQueryTests.TransformFeedbackCase.prototype); 150 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase; 151 152 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype.testTransformFeedback = function() { 153 /** @type {number} */ var feedbackPositionIndex = 0; 154 /** @type {number} */ var feedbackOutputIndex = 1; 155 156 /** @type {number} */ var rangeBufferOffset = 4; 157 /** @type {number} */ var rangeBufferSize = 8; 158 159 // bind buffers 160 161 /** @type {Array<WebGLBuffer>} */ var feedbackBuffers = []; 162 for (var ndx = 0; ndx < 2; ndx++) 163 feedbackBuffers[ndx] = gl.createBuffer(); 164 165 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[0]); 166 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ); 167 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackPositionIndex, feedbackBuffers[0]); 168 169 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[1]); 170 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ); 171 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackOutputIndex, feedbackBuffers[1], rangeBufferOffset, rangeBufferSize); 172 173 /** @type {Array<{index: number, pname: number, value: number}>} */ var requirements = [ 174 {index: feedbackPositionIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_START, value: 0}, 175 {index: feedbackPositionIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, value: 0}, 176 {index: feedbackOutputIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_START, value: rangeBufferOffset}, 177 {index: feedbackOutputIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, value: rangeBufferSize} 178 ]; 179 180 for (var ndx = 0; ndx < requirements.length; ndx++) { 181 var state = /** @type {number} */ (gl.getIndexedParameter(requirements[ndx].pname, requirements[ndx].index)); 182 this.check(state === requirements[ndx].value, 'got ' + state + '; expected ' + requirements[ndx].value); 183 } 184 185 // cleanup 186 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) 187 gl.deleteBuffer(feedbackBuffers[ndx]); 188 }; 189 190 /** 191 * @constructor 192 * @extends {es3fApiCase.ApiCase} 193 * @param {string} name 194 * @param {string} description 195 */ 196 es3fIndexedStateQueryTests.UniformBufferCase = function(name, description) { 197 es3fApiCase.ApiCase.call(this, name, description, gl); 198 /** @type {?WebGLProgram} */ this.m_program = null; 199 }; 200 201 es3fIndexedStateQueryTests.UniformBufferCase.prototype = Object.create(es3fApiCase.ApiCase.prototype); 202 es3fIndexedStateQueryTests.UniformBufferCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferCase; 203 204 es3fIndexedStateQueryTests.UniformBufferCase.prototype.testUniformBuffers = function() { 205 throw new Error('This method should be overriden.'); 206 }; 207 208 es3fIndexedStateQueryTests.UniformBufferCase.prototype.test = function() { 209 210 /** @type {string} */ var testVertSource = '' + 211 '#version 300 es\n' + 212 'uniform highp vec4 input1;\n' + 213 'uniform highp vec4 input2;\n' + 214 'void main (void)\n' + 215 '{\n' + 216 ' gl_Position = input1 + input2;\n' + 217 '}\n'; 218 /** @type {string} */ var testFragSource = '' + 219 '#version 300 es\n' + 220 'layout(location = 0) out mediump vec4 fragColor;' + 221 'void main (void)\n' + 222 '{\n' + 223 ' fragColor = vec4(0.0);\n' + 224 '}\n'; 225 226 /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER); 227 /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER); 228 229 gl.shaderSource(shaderVert, testVertSource); 230 gl.shaderSource(shaderFrag, testFragSource); 231 232 gl.compileShader(shaderVert); 233 gl.compileShader(shaderFrag); 234 235 this.m_program = gl.createProgram(); 236 gl.attachShader(this.m_program, shaderVert); 237 gl.attachShader(this.m_program, shaderFrag); 238 gl.linkProgram(this.m_program); 239 gl.useProgram(this.m_program); 240 241 this.testUniformBuffers(); 242 243 gl.useProgram(null); 244 gl.deleteShader(shaderVert); 245 gl.deleteShader(shaderFrag); 246 gl.deleteProgram(this.m_program); 247 }; 248 249 /** 250 * @constructor 251 * @extends {es3fIndexedStateQueryTests.UniformBufferCase} 252 * @param {string} name 253 * @param {string} description 254 */ 255 es3fIndexedStateQueryTests.UniformBufferBindingCase = function(name, description) { 256 es3fIndexedStateQueryTests.UniformBufferCase.call(this, name, description); 257 /** @type {?WebGLProgram} */ this.m_program = null; 258 }; 259 260 es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype = Object.create(es3fIndexedStateQueryTests.UniformBufferCase.prototype); 261 es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferBindingCase; 262 263 es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype.testUniformBuffers = function() { 264 /** @type {Array<string>} */ var uniformNames = ['input1', 'input2']; 265 266 /** @type {Array<number>} */ var uniformIndices = gl.getUniformIndices(this.m_program, uniformNames); 267 268 /** @type {Array<WebGLBuffer>} */ var buffers = []; 269 for (var ndx = 0; ndx < 2; ndx++) 270 buffers[ndx] = gl.createBuffer(); 271 272 for (var ndx = 0; ndx < buffers.length; ++ndx) { 273 gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[ndx]); 274 gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW); 275 gl.bindBufferBase(gl.UNIFORM_BUFFER, uniformIndices[ndx], buffers[ndx]); 276 } 277 278 /** @type {Array<WebGLBuffer>} */ var boundBuffer = []; 279 for (var ndx = 0; ndx < buffers.length; ndx++) { 280 boundBuffer[ndx] = /** @type {WebGLBuffer} */ (gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, uniformIndices[ndx])); 281 this.check(boundBuffer[ndx] === buffers[ndx], 'buffers do not match'); 282 } 283 284 for (var ndx = 0; ndx < buffers.length; ndx++) 285 gl.deleteBuffer(buffers[ndx]); 286 }; 287 288 /** 289 * @constructor 290 * @extends {es3fIndexedStateQueryTests.UniformBufferCase} 291 * @param {string} name 292 * @param {string} description 293 */ 294 es3fIndexedStateQueryTests.UniformBufferBufferCase = function(name, description) { 295 es3fIndexedStateQueryTests.UniformBufferCase.call(this, name, description); 296 /** @type {?WebGLProgram} */ this.m_program = null; 297 }; 298 299 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype = Object.create(es3fIndexedStateQueryTests.UniformBufferCase.prototype); 300 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferBufferCase; 301 302 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.testUniformBuffers = function() { 303 /** @type {Array<string>} */ var uniformNames = ['input1', 'input2']; 304 305 /** @type {Array<number>} */ var uniformIndices = gl.getUniformIndices(this.m_program, uniformNames); 306 307 /** @type {number} */ var alignment = this.getAlignment(); 308 if (alignment === -1) // cannot continue without this 309 return; 310 311 bufferedLogToConsole('Alignment is ' + alignment); 312 313 /** @type {number} */ var rangeBufferOffset = alignment; 314 /** @type {number} */ var rangeBufferSize = alignment * 2; 315 /** @type {number} */ var rangeBufferTotalSize = rangeBufferOffset + rangeBufferSize + 8; // + 8 has no special meaning, just to make it != with the size of the range 316 317 /** @type {Array<WebGLBuffer>} */ var buffers = []; 318 for (var ndx = 0; ndx < 2; ndx++) 319 buffers[ndx] = gl.createBuffer(); 320 321 gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[0]); 322 gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW); 323 gl.bindBufferBase(gl.UNIFORM_BUFFER, uniformIndices[0], buffers[0]); 324 325 gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[1]); 326 gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW); 327 gl.bindBufferRange(gl.UNIFORM_BUFFER, uniformIndices[1], buffers[1], rangeBufferOffset, rangeBufferSize); 328 329 // test UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE 330 331 /** @type {Array<{index: number, pname: number, value: number}>} */ var requirements = [ 332 {index: uniformIndices[0], pname: gl.UNIFORM_BUFFER_START, value: 0}, 333 {index: uniformIndices[0], pname: gl.UNIFORM_BUFFER_SIZE, value: 0}, 334 {index: uniformIndices[1], pname: gl.UNIFORM_BUFFER_START, value: rangeBufferOffset}, 335 {index: uniformIndices[1], pname: gl.UNIFORM_BUFFER_SIZE, value: rangeBufferSize} 336 ]; 337 338 for (var ndx = 0; ndx < requirements.length; ndx++) { 339 var state = /** @type {number} */ (gl.getIndexedParameter(requirements[ndx].pname, requirements[ndx].index)); 340 341 this.check(state === requirements[ndx].value, 'got ' + state + '; expected ' + requirements[ndx].value); 342 } 343 344 for (var ndx = 0; ndx < buffers.length; ndx++) 345 gl.deleteBuffer(buffers[ndx]); 346 347 }; 348 349 /** 350 * @return {number} 351 */ 352 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.getAlignment = function() { 353 var state = /** @type {number} */ (gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT)); 354 355 if (state <= 256) 356 return state; 357 358 bufferedLogToConsole('ERROR: UNIFORM_BUFFER_OFFSET_ALIGNMENT has a maximum value of 256.'); 359 testFailedOptions('invalid UNIFORM_BUFFER_OFFSET_ALIGNMENT value', false); 360 361 return -1; 362 }; 363 364 /** 365 * @constructor 366 * @extends {tcuTestCase.DeqpTest} 367 */ 368 es3fIndexedStateQueryTests.IndexedStateQueryTests = function() { 369 tcuTestCase.DeqpTest.call(this, 'indexed', 'Indexed Integer Values'); 370 }; 371 372 es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 373 es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype.constructor = es3fIndexedStateQueryTests.IndexedStateQueryTests; 374 375 es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype.init = function() { 376 // transform feedback 377 this.addChild(new es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase('transform_feedback_buffer_binding', 'TRANSFORM_FEEDBACK_BUFFER_BINDING')); 378 this.addChild(new es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase('transform_feedback_buffer_start_size', 'TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE')); 379 380 // uniform buffers 381 this.addChild(new es3fIndexedStateQueryTests.UniformBufferBindingCase('uniform_buffer_binding', 'UNIFORM_BUFFER_BINDING')); 382 this.addChild(new es3fIndexedStateQueryTests.UniformBufferBufferCase('uniform_buffer_start_size', 'UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE')); 383 }; 384 385 /** 386 * Run test 387 * @param {WebGL2RenderingContext} context 388 */ 389 es3fIndexedStateQueryTests.run = function(context) { 390 gl = context; 391 //Set up Test Root parameters 392 var state = tcuTestCase.runner; 393 state.setRoot(new es3fIndexedStateQueryTests.IndexedStateQueryTests()); 394 395 //Set up name and description of this test series. 396 setCurrentTestName(state.testCases.fullName()); 397 description(state.testCases.getDescription()); 398 399 try { 400 //Run test cases 401 tcuTestCase.runTestCases(); 402 } 403 catch (err) { 404 testFailedOptions('Failed to es3fIndexedStateQueryTests.run tests', false); 405 tcuTestCase.runner.terminate(); 406 } 407 }; 408 409 });