es3fLifetimeTests.js (17366B)
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 'use strict'; 21 goog.provide('functional.gles3.es3fLifetimeTests'); 22 goog.require('framework.common.tcuSurface'); 23 goog.require('framework.common.tcuTestCase'); 24 goog.require('framework.delibs.debase.deRandom'); 25 goog.require('framework.opengl.gluShaderProgram'); 26 goog.require('modules.shared.glsLifetimeTests'); 27 goog.require('modules.shared.glsTextureTestUtil'); 28 29 goog.scope(function() { 30 var es3fLifetimeTests = functional.gles3.es3fLifetimeTests; 31 var glsLifetimeTests = modules.shared.glsLifetimeTests; 32 var gluShaderProgram = framework.opengl.gluShaderProgram; 33 var deRandom = framework.delibs.debase.deRandom; 34 var tcuSurface = framework.common.tcuSurface; 35 var glsTextureTestUtil = modules.shared.glsTextureTestUtil; 36 var tcuTestCase = framework.common.tcuTestCase; 37 38 /** @const */ var VIEWPORT_SIZE = 128; 39 /** @const */ var NUM_COMPONENTS = 4; 40 /** @const */ var NUM_VERTICES = 3; 41 42 /** @type {WebGL2RenderingContext} */ var gl; 43 44 var setParentClass = function(child, parent) { 45 child.prototype = Object.create(parent.prototype); 46 child.prototype.constructor = child; 47 }; 48 49 /** 50 * @constructor 51 * @extends {gluShaderProgram.ShaderProgram} 52 */ 53 es3fLifetimeTests.ScaleProgram = function() { 54 gluShaderProgram.ShaderProgram.call(this, gl, this.getSources()); 55 assertMsgOptions(this.isOk(), 'Program creation failed', false, true); 56 this.m_scaleLoc = gl.getUniformLocation(this.getProgram(), 'scale'); 57 this.m_posLoc = gl.getAttribLocation(this.getProgram(), 'pos'); 58 }; 59 60 setParentClass(es3fLifetimeTests.ScaleProgram, gluShaderProgram.ShaderProgram); 61 62 /** 63 * @param {WebGLVertexArrayObject} vao 64 * @param {number} scale 65 * @param {boolean} tf 66 * @param {tcuSurface.Surface} dst 67 */ 68 es3fLifetimeTests.ScaleProgram.prototype.draw = function(vao, scale, tf, dst) { 69 es3fLifetimeTests.ScaleProgram.seed = es3fLifetimeTests.ScaleProgram.seed || 0; 70 ++es3fLifetimeTests.ScaleProgram.seed; 71 72 var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), VIEWPORT_SIZE, VIEWPORT_SIZE, es3fLifetimeTests.ScaleProgram.seed); 73 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); 74 gl.clearColor(0, 0, 0, 1); 75 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 76 77 gl.bindVertexArray(vao); 78 gl.enableVertexAttribArray(this.m_posLoc); 79 gl.useProgram(this.getProgram()); 80 81 gl.uniform1f(this.m_scaleLoc, scale); 82 83 if (tf) 84 gl.beginTransformFeedback(gl.TRIANGLES); 85 gl.drawArrays(gl.TRIANGLES, 0, 3); 86 if (tf) 87 gl.endTransformFeedback(); 88 89 if (dst) 90 glsLifetimeTests.readRectangle(viewport, dst); 91 92 gl.bindVertexArray(null); 93 94 }; 95 96 /** 97 * @param {WebGLBuffer} buffer 98 * @param {WebGLVertexArrayObject} vao 99 */ 100 es3fLifetimeTests.ScaleProgram.prototype.setPos = function(buffer, vao) { 101 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 102 gl.bindVertexArray(vao); 103 gl.vertexAttribPointer(this.m_posLoc, NUM_COMPONENTS, gl.FLOAT, false, 0, 0); 104 gl.bindVertexArray(null); 105 gl.bindBuffer(gl.ARRAY_BUFFER, null); 106 }; 107 108 /** 109 * @private 110 */ 111 es3fLifetimeTests.ScaleProgram.prototype.getSources = function() { 112 /** @const */ var s_vertexShaderSrc = 113 '#version 100\n' + 114 'attribute vec4 pos;\n' + 115 'uniform float scale;\n' + 116 'void main ()\n' + 117 '{\n' + 118 ' gl_Position = vec4(scale * pos.xy, pos.zw);\n' + 119 '}'; 120 121 /** @const */ var s_fragmentShaderSrc = 122 '#version 100\n' + 123 'void main ()\n' + 124 '{\n' + 125 ' gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\n' + 126 '}'; 127 var sources = new gluShaderProgram.ProgramSources(); 128 sources.add(new gluShaderProgram.VertexSource(s_vertexShaderSrc)); 129 sources.add(new gluShaderProgram.FragmentSource(s_fragmentShaderSrc)); 130 sources.add(new gluShaderProgram.TransformFeedbackMode(gl.INTERLEAVED_ATTRIBS)); 131 sources.add(new gluShaderProgram.TransformFeedbackVarying('gl_Position')); 132 return sources; 133 }; 134 135 /** 136 * @constructor 137 * @extends {glsLifetimeTests.SimpleBinder} 138 */ 139 es3fLifetimeTests.VertexArrayBinder = function() { 140 glsLifetimeTests.SimpleBinder.call(this, null, gl.NONE, gl.VERTEX_ARRAY_BINDING); 141 }; 142 143 setParentClass(es3fLifetimeTests.VertexArrayBinder, glsLifetimeTests.SimpleBinder); 144 145 es3fLifetimeTests.VertexArrayBinder.prototype.bind = function(obj) { 146 var vao = /** @type {WebGLVertexArrayObject} */ (obj); 147 gl.bindVertexArray(vao); 148 }; 149 150 /** 151 * @constructor 152 * @extends {glsLifetimeTests.Binder} 153 */ 154 es3fLifetimeTests.SamplerBinder = function() { 155 glsLifetimeTests.Binder.call(this); 156 }; 157 158 setParentClass(es3fLifetimeTests.SamplerBinder, glsLifetimeTests.Binder); 159 160 es3fLifetimeTests.SamplerBinder.prototype.bind = function(obj) { 161 var sampler = /** @type {WebGLSampler} */ (obj); 162 gl.bindSampler(0, sampler); 163 }; 164 es3fLifetimeTests.SamplerBinder.prototype.getBinding = function() { return /** @type {WebGLSampler} */ (gl.getParameter(gl.SAMPLER_BINDING)); }; 165 166 /** 167 * @constructor 168 * @extends {glsLifetimeTests.Binder} 169 */ 170 es3fLifetimeTests.QueryBinder = function() { 171 glsLifetimeTests.Binder.call(this); 172 }; 173 174 setParentClass(es3fLifetimeTests.QueryBinder, glsLifetimeTests.Binder); 175 176 es3fLifetimeTests.QueryBinder.prototype.bind = function(obj) { 177 var query = /** @type {WebGLQuery} */ (obj); 178 if (query) 179 gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); 180 else 181 gl.endQuery(gl.ANY_SAMPLES_PASSED); 182 }; 183 184 es3fLifetimeTests.QueryBinder.prototype.getBinding = function() { return null; }; 185 186 /** 187 * @constructor 188 * @extends {glsLifetimeTests.Attacher} 189 * @param {glsLifetimeTests.Type} elementType 190 * @param {glsLifetimeTests.Type} varrType 191 * @param {es3fLifetimeTests.ScaleProgram} program 192 */ 193 es3fLifetimeTests.BufferVAOAttacher = function(elementType, varrType, program) { 194 glsLifetimeTests.Attacher.call(this, elementType, varrType); 195 this.m_program = program; 196 }; 197 198 setParentClass(es3fLifetimeTests.BufferVAOAttacher, glsLifetimeTests.Attacher); 199 200 /** 201 * @return {es3fLifetimeTests.ScaleProgram} 202 */ 203 es3fLifetimeTests.BufferVAOAttacher.prototype.getProgram = function() { return this.m_program; }; 204 205 /** 206 * @param {number} seed 207 * @param {number} usage 208 * @param {WebGLBuffer} buffer 209 */ 210 es3fLifetimeTests.initBuffer = function(seed, usage, buffer) { 211 /** @const */ var s_varrData = [ 212 -1.0, 0.0, 0.0, 1.0, 213 1.0, 1.0, 0.0, 1.0, 214 0.0, -1.0, 0.0, 1.0 215 ]; 216 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 217 if (seed == 0) 218 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(s_varrData), usage); 219 else { 220 var rnd = new deRandom.Random(seed); 221 var data = []; 222 223 for (var ndx = 0; ndx < NUM_VERTICES; ndx++) { 224 data.push(2 * (rnd.getFloat() - 0.5)); 225 data.push(2 * (rnd.getFloat() - 0.5)); 226 data.push(0); 227 data.push(1); 228 } 229 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), usage); 230 } 231 gl.bindBuffer(gl.ARRAY_BUFFER, null); 232 }; 233 234 es3fLifetimeTests.BufferVAOAttacher.prototype.initAttachment = function(seed, obj) { 235 var buffer = /** @type {WebGLBuffer} */ (obj); 236 es3fLifetimeTests.initBuffer(seed, gl.STATIC_DRAW, buffer); 237 bufferedLogToConsole('Initialized buffer ' + buffer + ' from seed ' + seed); 238 }; 239 240 es3fLifetimeTests.BufferVAOAttacher.prototype.attach = function(element, target) { 241 var buffer = /** @type {WebGLBuffer} */ (element); 242 var vao = /** @type {WebGLVertexArrayObject} */ (target); 243 244 this.m_program.setPos(buffer, vao); 245 bufferedLogToConsole('Set the `pos` attribute in VAO ' + vao + ' to buffer ' + buffer); 246 }; 247 248 es3fLifetimeTests.BufferVAOAttacher.prototype.detach = function(element, target) { 249 var vao = /** @type {WebGLVertexArrayObject} */ (target); 250 this.attach(null, vao); 251 }; 252 253 es3fLifetimeTests.BufferVAOAttacher.prototype.getAttachment = function(target) { 254 var vao = /** @type {WebGLVertexArrayObject} */ (target); 255 gl.bindVertexArray(vao); 256 var name = gl.getVertexAttrib(this.m_posLoc, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); 257 gl.bindVertexArray(null); 258 return name; 259 }; 260 261 /** 262 * @constructor 263 * @extends {glsLifetimeTests.InputAttacher} 264 * @param {es3fLifetimeTests.BufferVAOAttacher} attacher 265 */ 266 es3fLifetimeTests.BufferVAOInputAttacher = function(attacher) { 267 glsLifetimeTests.InputAttacher.call(this, attacher); 268 this.m_program = attacher.getProgram(); 269 }; 270 271 setParentClass(es3fLifetimeTests.BufferVAOInputAttacher, glsLifetimeTests.InputAttacher); 272 273 es3fLifetimeTests.BufferVAOInputAttacher.prototype.drawContainer = function(obj, dst) { 274 var vao = /** @type {WebGLVertexArrayObject} */ (obj); 275 this.m_program.draw(vao, 1.0, false, dst); 276 bufferedLogToConsole('Drew an output image with VAO ' + vao); 277 }; 278 279 /** 280 * @constructor 281 * @extends {glsLifetimeTests.Attacher} 282 * @param {glsLifetimeTests.Type} elementType 283 * @param {glsLifetimeTests.Type} tfType 284 */ 285 es3fLifetimeTests.BufferTfAttacher = function(elementType, tfType) { 286 glsLifetimeTests.Attacher.call(this, elementType, tfType); 287 }; 288 289 setParentClass(es3fLifetimeTests.BufferTfAttacher, glsLifetimeTests.Attacher); 290 291 es3fLifetimeTests.BufferTfAttacher.prototype.initAttachment = function(seed, obj) { 292 var buffer = /** @type {WebGLBuffer} */ (obj); 293 es3fLifetimeTests.initBuffer(seed, gl.DYNAMIC_READ, buffer); 294 bufferedLogToConsole('Initialized buffer ' + buffer + ' from seed ' + seed); 295 }; 296 297 es3fLifetimeTests.BufferTfAttacher.prototype.attach = function(element, target) { 298 var buffer = /** @type {WebGLBuffer} */ (element); 299 var tf = /** @type {WebGLTransformFeedback} */ (target); 300 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf); 301 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer); 302 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); 303 }; 304 305 es3fLifetimeTests.BufferTfAttacher.prototype.detach = function(element, target) { 306 var buffer = /** @type {WebGLBuffer} */ (element); 307 var tf = /** @type {WebGLTransformFeedback} */ (target); 308 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf); 309 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); 310 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); 311 312 }; 313 314 es3fLifetimeTests.BufferTfAttacher.prototype.getAttachment = function(target) { 315 var tf = /** @type {WebGLTransformFeedback} */ (target); 316 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf); 317 var name = gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0); 318 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); 319 return name; 320 }; 321 322 /** 323 * @constructor 324 * @extends {glsLifetimeTests.OutputAttacher} 325 */ 326 es3fLifetimeTests.BufferTfOutputAttacher = function(attacher, program) { 327 glsLifetimeTests.OutputAttacher.call(this, attacher); 328 this.m_program = program; 329 }; 330 331 setParentClass(es3fLifetimeTests.BufferTfOutputAttacher, glsLifetimeTests.OutputAttacher); 332 333 es3fLifetimeTests.BufferTfOutputAttacher.prototype.setupContainer = function(seed, obj) { 334 var tf = /** @type {WebGLTransformFeedback} */ (obj); 335 var posBuf = gl.createBuffer(); 336 var vao = gl.createVertexArray(); 337 338 es3fLifetimeTests.initBuffer(seed, gl.STATIC_DRAW, posBuf); 339 this.m_program.setPos(posBuf, vao); 340 341 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf); 342 this.m_program.draw(vao, -1.0, true, null); 343 bufferedLogToConsole('Drew an image with seed ' + seed + ' with transform feedback to ' + tf); 344 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); 345 gl.deleteVertexArray(vao); 346 gl.deleteBuffer(posBuf); 347 }; 348 349 es3fLifetimeTests.BufferTfOutputAttacher.prototype.drawAttachment = function(buffer, dst) { 350 var vao = gl.createVertexArray(); 351 352 this.m_program.setPos(buffer, vao); 353 this.m_program.draw(vao, 1.0, false, dst); 354 bufferedLogToConsole('Drew output image with vertices from buffer ' + buffer); 355 gl.deleteVertexArray(vao); 356 }; 357 358 /** 359 * @constructor 360 * @extends {glsLifetimeTests.ES2Types} 361 */ 362 es3fLifetimeTests.ES3Types = function() { 363 glsLifetimeTests.ES2Types.call(this); 364 this.m_program = new es3fLifetimeTests.ScaleProgram(); 365 this.m_queryBind = new es3fLifetimeTests.QueryBinder(); 366 this.m_queryType = new glsLifetimeTests.SimpleType('query', gl.createQuery, gl.deleteQuery, gl.isQuery, this.m_queryBind); 367 this.m_tfBind = new glsLifetimeTests.SimpleBinder(gl.bindTransformFeedback, gl.TRANSFORM_FEEDBACK, 368 gl.TRANSFORM_FEEDBACK_BINDING); 369 this.m_tfType = new glsLifetimeTests.SimpleType('transform_feedback', gl.createTransformFeedback, gl.deleteTransformFeedback, gl.isTransformFeedback, this.m_tfBind); 370 this.m_varrBind = new es3fLifetimeTests.VertexArrayBinder(); 371 this.m_varrType = new glsLifetimeTests.SimpleType('vertex_array', gl.createVertexArray, gl.deleteVertexArray, gl.isVertexArray, this.m_varrBind); 372 this.m_samplerBind = new es3fLifetimeTests.SamplerBinder(); 373 this.m_samplerType = new glsLifetimeTests.SimpleType('sampler', gl.createSampler, gl.deleteSampler, gl.isSampler, this.m_samplerBind, true); 374 this.m_bufVarrAtt = new es3fLifetimeTests.BufferVAOAttacher(this.m_bufferType, this.m_varrType, this.m_program); 375 this.m_bufVarrInAtt = new es3fLifetimeTests.BufferVAOInputAttacher(this.m_bufVarrAtt); 376 this.m_bufTfAtt = new es3fLifetimeTests.BufferTfAttacher(this.m_bufferType, this.m_tfType); 377 this.m_bufTfOutAtt = new es3fLifetimeTests.BufferTfOutputAttacher(this.m_bufTfAtt, this.m_program); 378 379 this.m_types.push(this.m_queryType, this.m_tfType, this.m_varrType, this.m_samplerType); 380 this.m_attachers.push(this.m_bufVarrAtt, this.m_bufTfAtt); 381 this.m_inAttachers.push(this.m_bufVarrInAtt); 382 this.m_outAttachers.push(this.m_bufTfOutAtt); 383 }; 384 385 setParentClass(es3fLifetimeTests.ES3Types, glsLifetimeTests.ES2Types); 386 387 /** 388 * @constructor 389 * @extends {tcuTestCase.DeqpTest} 390 */ 391 es3fLifetimeTests.TfDeleteActiveTest = function(name, description) { 392 tcuTestCase.DeqpTest.call(this, name, description); 393 }; 394 395 setParentClass(es3fLifetimeTests.TfDeleteActiveTest, tcuTestCase.DeqpTest); 396 397 es3fLifetimeTests.TfDeleteActiveTest.prototype.iterate = function() { 398 /** @const */ var s_xfbVertexSource = 399 '#version 300 es\n' + 400 'void main ()\n' + 401 '{\n' + 402 ' gl_Position = vec4(float(gl_VertexID) / 2.0, float(gl_VertexID % 2) / 2.0, 0.0, 1.0);\n' + 403 '}\n'; 404 405 /** @const */ var s_xfbFragmentSource = 406 '#version 300 es\n' + 407 'layout(location=0) out mediump vec4 dEQP_FragColor;\n' + 408 'void main (void)\n' + 409 '{\n' + 410 ' dEQP_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n' + 411 '}\n'; 412 var buf = gl.createBuffer(); 413 414 var sources = new gluShaderProgram.ProgramSources(); 415 sources.add(new gluShaderProgram.VertexSource(s_xfbVertexSource)); 416 sources.add(new gluShaderProgram.FragmentSource(s_xfbFragmentSource)); 417 sources.add(new gluShaderProgram.TransformFeedbackMode(gl.SEPARATE_ATTRIBS)); 418 sources.add(new gluShaderProgram.TransformFeedbackVarying('gl_Position')); 419 var program = new gluShaderProgram.ShaderProgram(gl, sources); 420 if (!program.isOk()) { 421 bufferedLogToConsole(program.getProgramInfo().infoLog); 422 testFailedOptions('failed to build program', true); 423 } 424 gl.useProgram(program.getProgram()); 425 426 var tf = gl.createTransformFeedback(); 427 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf); 428 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf); 429 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 48, gl.STATIC_DRAW); 430 431 gl.beginTransformFeedback(gl.TRIANGLES); 432 var errCode = gl.NONE; 433 gl.deleteTransformFeedback(tf); 434 errCode = gl.getError(); 435 assertMsgOptions(errCode == gl.INVALID_OPERATION, 436 'Deleting active transform feedback must produce INVALID_OPERATION', false, true); 437 gl.endTransformFeedback(); 438 gl.deleteTransformFeedback(tf); 439 testPassed(); 440 return tcuTestCase.IterateResult.STOP; 441 }; 442 443 es3fLifetimeTests.genTestCases = function() { 444 var state = tcuTestCase.runner; 445 state.setRoot(tcuTestCase.newTest('lifetime', 'Top level')); 446 447 var types = new es3fLifetimeTests.ES3Types(); 448 glsLifetimeTests.addTestCases(state.testCases, types); 449 /* TODO: Add TfDeleteActiveTest test */ 450 var deleteActiveGroup = tcuTestCase.newTest('delete_active', 'Delete active object'); 451 state.testCases.addChild(deleteActiveGroup); 452 deleteActiveGroup.addChild( 453 new es3fLifetimeTests.TfDeleteActiveTest('transform_feedback', 'Transform Feedback')); 454 }; 455 456 /** 457 * Create and execute the test cases 458 */ 459 es3fLifetimeTests.run = function(context) { 460 gl = context; 461 try { 462 es3fLifetimeTests.genTestCases(); 463 tcuTestCase.runner.runCallback(tcuTestCase.runTestCases); 464 } catch (err) { 465 bufferedLogToConsole(err); 466 tcuTestCase.runner.terminate(); 467 } 468 469 }; 470 471 });