es3fShaderBuiltinVarTests.js (52694B)
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.es3fShaderBuiltinVarTests'); 23 goog.require('framework.delibs.debase.deMath'); 24 goog.require('framework.delibs.debase.deRandom'); 25 goog.require('framework.delibs.debase.deString'); 26 goog.require('framework.common.tcuImageCompare'); 27 goog.require('framework.common.tcuLogImage'); 28 goog.require('framework.common.tcuPixelFormat'); 29 goog.require('framework.common.tcuRGBA'); 30 goog.require('framework.common.tcuSurface'); 31 goog.require('framework.common.tcuTestCase'); 32 goog.require('framework.common.tcuTexture'); 33 goog.require('framework.opengl.gluDrawUtil'); 34 goog.require('framework.opengl.gluShaderProgram'); 35 goog.require('framework.opengl.gluShaderUtil'); 36 goog.require('framework.opengl.gluVarType'); 37 goog.require('framework.opengl.simplereference.sglrReferenceContext'); 38 goog.require('framework.opengl.simplereference.sglrShaderProgram'); 39 goog.require('framework.referencerenderer.rrFragmentOperations'); 40 goog.require('framework.referencerenderer.rrGenericVector'); 41 goog.require('framework.referencerenderer.rrMultisamplePixelBufferAccess'); 42 goog.require('framework.referencerenderer.rrRenderer'); 43 goog.require('framework.referencerenderer.rrRenderState'); 44 goog.require('framework.referencerenderer.rrShadingContext'); 45 goog.require('framework.referencerenderer.rrVertexAttrib'); 46 goog.require('framework.referencerenderer.rrVertexPacket'); 47 goog.require('modules.shared.glsShaderRenderCase'); 48 goog.require('modules.shared.glsShaderExecUtil'); 49 50 goog.scope(function() { 51 var es3fShaderBuiltinVarTests = functional.gles3.es3fShaderBuiltinVarTests; 52 var deMath = framework.delibs.debase.deMath; 53 var deString = framework.delibs.debase.deString; 54 var deRandom = framework.delibs.debase.deRandom; 55 var glsShaderExecUtil = modules.shared.glsShaderExecUtil; 56 var glsShaderRenderCase = modules.shared.glsShaderRenderCase; 57 var gluShaderProgram = framework.opengl.gluShaderProgram; 58 var gluShaderUtil = framework.opengl.gluShaderUtil; 59 var gluDrawUtil = framework.opengl.gluDrawUtil; 60 var gluVarType = framework.opengl.gluVarType; 61 var tcuPixelFormat = framework.common.tcuPixelFormat; 62 var tcuSurface = framework.common.tcuSurface; 63 var tcuTexture = framework.common.tcuTexture; 64 var tcuLogImage = framework.common.tcuLogImage; 65 var tcuTestCase = framework.common.tcuTestCase; 66 var tcuImageCompare = framework.common.tcuImageCompare; 67 var tcuRGBA = framework.common.tcuRGBA; 68 var rrGenericVector = framework.referencerenderer.rrGenericVector; 69 var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations; 70 var rrMultisamplePixelBufferAccess = framework.referencerenderer.rrMultisamplePixelBufferAccess; 71 var rrRenderer = framework.referencerenderer.rrRenderer; 72 var rrRenderState = framework.referencerenderer.rrRenderState; 73 var rrShadingContext = framework.referencerenderer.rrShadingContext; 74 var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib; 75 var rrVertexPacket = framework.referencerenderer.rrVertexPacket; 76 var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram; 77 var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext; 78 79 /** @typedef {function():number} */ es3fShaderBuiltinVarTests.GetConstantValueFunc; 80 81 /** 82 * @param {number} pname 83 * @return {number} getParameter returns values of any kind 84 */ 85 es3fShaderBuiltinVarTests.getInteger = function(pname) { 86 return /** @type {number} */ (gl.getParameter(pname)); 87 }; 88 89 /** 90 * @param {number} pname 91 * @return {number} forcing number 92 */ 93 es3fShaderBuiltinVarTests.getVectorsFromComps = function(pname) { 94 var value = /** @type {number} */ (gl.getParameter(pname)); 95 assertMsgOptions(value%4 === 0, 'Expected value to be divisible by 4.', false, true); 96 return value / 4; 97 }; 98 99 /** 100 * @constructor 101 * @extends {tcuTestCase.DeqpTest} 102 * @param {string} name 103 * @param {string} desc 104 * @param {string} varName 105 * @param {es3fShaderBuiltinVarTests.GetConstantValueFunc} getValue 106 * @param {gluShaderProgram.shaderType} shaderType 107 */ 108 es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase = function(name, desc, varName, getValue, shaderType) { 109 tcuTestCase.DeqpTest.call(this, name, desc); 110 /** @type {string} */ this.m_varName = varName; 111 /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ this.m_getValue = getValue; 112 /** @type {gluShaderProgram.shaderType} */ this.m_shaderType = shaderType; 113 }; 114 115 es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 116 es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.constructor = es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase; 117 118 es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.deinit = function() { 119 // an attempt to cleanup the GL state when the test fails 120 bufferedLogToConsole('ShaderBuildInConstantCase.deinit()'); 121 gl.useProgram(null); 122 gl.bindBuffer(gl.ARRAY_BUFFER, null); 123 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 124 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 125 gl.bindRenderbuffer(gl.RENDERBUFFER, null); 126 }; 127 128 /** 129 * @param {gluShaderProgram.shaderType} shaderType 130 * @param {string} varName 131 * @return {glsShaderExecUtil.ShaderExecutor} 132 */ 133 es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.createGetConstantExecutor = function(shaderType, varName) { 134 /** @type {glsShaderExecUtil.ShaderSpec} */ var shaderSpec = new glsShaderExecUtil.ShaderSpec(); 135 shaderSpec.version = gluShaderUtil.GLSLVersion.V300_ES; 136 shaderSpec.source = 'result = ' + varName + ';\n'; 137 shaderSpec.outputs.push(new glsShaderExecUtil.Symbol('result', 138 gluVarType.newTypeBasic(gluShaderUtil.DataType.INT, gluShaderUtil.precision.PRECISION_HIGHP))); 139 return glsShaderExecUtil.createExecutor(shaderType, shaderSpec); 140 141 }; 142 143 /** 144 * @return {tcuTestCase.IterateResult} 145 */ 146 es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.iterate = function() { 147 /** @type {glsShaderExecUtil.ShaderExecutor} */ 148 var shaderExecutor = this.createGetConstantExecutor(this.m_shaderType, this.m_varName); 149 /** @type {number} */ var reference = this.m_getValue(); 150 /** @type {goog.NumberArray} */ var shaderExecutorResult; 151 /** @type {number} */ var result; 152 153 if (!shaderExecutor.isOk()) 154 assertMsgOptions(false, 'Compile failed', false, true); 155 156 shaderExecutor.useProgram(); 157 158 shaderExecutorResult = shaderExecutor.execute(1, null); 159 result = new Int32Array(shaderExecutorResult[0].buffer)[0]; 160 161 bufferedLogToConsole(this.m_varName + ' = ' + result); 162 163 if (result != reference) { 164 bufferedLogToConsole('ERROR: Expected ' + this.m_varName + ' = ' + reference + '\n' + 165 'Test shader:' + shaderExecutor.m_program.getProgramInfo().infoLog); 166 testFailedOptions('Invalid builtin constant value', false); 167 } else 168 testPassedOptions('Pass', true); 169 170 return tcuTestCase.IterateResult.STOP; 171 }; 172 173 /** 174 * @struct 175 * @constructor 176 * @param {number=} near 177 * @param {number=} far 178 */ 179 es3fShaderBuiltinVarTests.DepthRangeParams = function(near, far) { 180 /** @type {number} */ this.zNear = near === undefined ? 0.0 : near; 181 /** @type {number} */ this.zFar = far === undefined ? 1.0 : far; 182 }; 183 184 /** 185 * @constructor 186 * @extends {glsShaderRenderCase.ShaderEvaluator} 187 * @param {es3fShaderBuiltinVarTests.DepthRangeParams} params 188 */ 189 es3fShaderBuiltinVarTests.DepthRangeEvaluator = function(params) { 190 /** @type {es3fShaderBuiltinVarTests.DepthRangeParams} */ this.m_params = params; 191 }; 192 193 es3fShaderBuiltinVarTests.DepthRangeEvaluator.prototype = Object.create(glsShaderRenderCase.ShaderEvaluator.prototype); 194 es3fShaderBuiltinVarTests.DepthRangeEvaluator.prototype.constructor = es3fShaderBuiltinVarTests.DepthRangeEvaluator; 195 196 /** 197 * @param {glsShaderRenderCase.ShaderEvalContext} c 198 */ 199 es3fShaderBuiltinVarTests.DepthRangeEvaluator.prototype.evaluate = function(c) { 200 /** @type {number} */ var zNear = deMath.clamp(this.m_params.zNear, 0.0, 1.0); 201 /** @type {number} */ var zFar = deMath.clamp(this.m_params.zFar, 0.0, 1.0); 202 /** @type {number} */ var diff = zFar - zNear; 203 c.color[0] = zNear; 204 c.color[1] = zFar; 205 c.color[2] = diff * 0.5 + 0.5; 206 }; 207 208 /** 209 * @constructor 210 * @extends {glsShaderRenderCase.ShaderRenderCase} 211 * @param {string} name 212 * @param {string} desc 213 * @param {boolean} isVertexCase 214 */ 215 es3fShaderBuiltinVarTests.ShaderDepthRangeTest = function(name, desc, isVertexCase) { 216 glsShaderRenderCase.ShaderRenderCase.call(this, name, desc, isVertexCase); 217 /** @type {es3fShaderBuiltinVarTests.DepthRangeParams} */ this.m_depthRange = new es3fShaderBuiltinVarTests.DepthRangeParams(); 218 /** @type {es3fShaderBuiltinVarTests.DepthRangeEvaluator} */ this.m_evaluator = new es3fShaderBuiltinVarTests.DepthRangeEvaluator(this.m_depthRange); 219 /** @type {number} */ this.m_iterNdx = 0; 220 }; 221 222 es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype); 223 es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype.constructor = es3fShaderBuiltinVarTests.ShaderDepthRangeTest; 224 225 es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype.init = function() { 226 /** @type {string} */ var defaultVertSrc = '' + 227 '#version 300 es\n' + 228 'in highp vec4 a_position;\n' + 229 'void main (void)\n' + 230 '{\n' + 231 ' gl_Position = a_position;\n' + 232 '}\n'; 233 /** @type {string} */ var defaultFragSrc = '' + 234 '#version 300 es\n' + 235 'in mediump vec4 v_color;\n' + 236 'layout(location = 0) out mediump vec4 o_color;\n\n' + 237 'void main (void)\n' + 238 '{\n' + 239 ' o_color = v_color;\n' + 240 '}\n'; 241 242 // Construct shader. 243 /** @type {string} */ var src = '#version 300 es\n'; 244 if (this.m_isVertexCase) 245 src += 'in highp vec4 a_position;\n' + 246 'out mediump vec4 v_color;\n'; 247 else 248 src += 'layout(location = 0) out mediump vec4 o_color;\n'; 249 250 src += 'void main (void)\n{\n' + 251 '\t' + (this.m_isVertexCase ? 'v_color' : 'o_color') + ' = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff*0.5 + 0.5, 1.0);\n'; 252 253 if (this.m_isVertexCase) 254 src += '\tgl_Position = a_position;\n'; 255 256 src += '}\n'; 257 258 this.m_vertShaderSource = this.m_isVertexCase ? src : defaultVertSrc; 259 this.m_fragShaderSource = this.m_isVertexCase ? defaultFragSrc : src; 260 261 this.postinit(); 262 }; 263 264 /** 265 * @return {tcuTestCase.IterateResult} 266 */ 267 es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype.iterate = function() { 268 /** @type {Array<es3fShaderBuiltinVarTests.DepthRangeParams>} */ var cases = [ 269 new es3fShaderBuiltinVarTests.DepthRangeParams(0.0, 1.0) 270 ]; 271 272 this.m_depthRange = cases[this.m_iterNdx]; 273 bufferedLogToConsole('gl.depthRange(' + this.m_depthRange.zNear + ', ' + this.m_depthRange.zFar + ')'); 274 gl.depthRange(this.m_depthRange.zNear, this.m_depthRange.zFar); 275 276 this.postiterate(); 277 this.m_iterNdx += 1; 278 279 if (this.m_iterNdx == cases.length) 280 return tcuTestCase.IterateResult.STOP; 281 else 282 return tcuTestCase.IterateResult.CONTINUE; 283 }; 284 285 /** 286 * @constructor 287 * @extends {tcuTestCase.DeqpTest} 288 */ 289 es3fShaderBuiltinVarTests.FragCoordXYZCase = function() { 290 tcuTestCase.DeqpTest.call(this, 'fragcoord_xyz', 'gl_FragCoord.xyz Test'); 291 }; 292 293 es3fShaderBuiltinVarTests.FragCoordXYZCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 294 es3fShaderBuiltinVarTests.FragCoordXYZCase.prototype.constructor = es3fShaderBuiltinVarTests.FragCoordXYZCase; 295 296 es3fShaderBuiltinVarTests.FragCoordXYZCase.prototype.iterate = function() { 297 /** @type {number} */ var width = gl.drawingBufferWidth; 298 /** @type {number} */ var height = gl.drawingBufferHeight; 299 /** @type {Array<number>} */ var threshold = deMath.add([1, 1, 1, 1], tcuPixelFormat.PixelFormatFromContext(gl).getColorThreshold()); 300 /** @type {Array<number>} */ var scale = [1. / width, 1. / height, 1.0]; 301 302 /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height); 303 /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height); 304 305 /** @type {string} */ var vtxSource = '' + 306 '#version 300 es\n' + 307 'in highp vec4 a_position;\n' + 308 'void main (void)\n' + 309 '{\n' + 310 ' gl_Position = a_position;\n' + 311 '}\n'; 312 /** @type {string} */ var fragSource = '' + 313 '#version 300 es\n' + 314 'uniform highp vec3 u_scale;\n' + 315 'layout(location = 0) out mediump vec4 o_color;\n' + 316 'void main (void)\n' + 317 '{\n' + 318 ' o_color = vec4(gl_FragCoord.xyz*u_scale, 1.0);\n' + 319 '}\n'; 320 /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource)); 321 322 bufferedLogToConsole(program.getProgramInfo().infoLog); 323 324 if (!program.isOk()) 325 throw new Error('Compile failed'); 326 327 // Draw with GL. 328 /** @type {Array<number>} */ var positions = [ 329 -1.0, 1.0, -1.0, 1.0, 330 -1.0, -1.0, 0.0, 1.0, 331 1.0, 1.0, 0.0, 1.0, 332 1.0, -1.0, 1.0, 1.0 333 ]; 334 /** @type {Array<number>} */ var indices = [0, 1, 2, 2, 1, 3]; 335 336 /** @type {WebGLUniformLocation} */ var scaleLoc = gl.getUniformLocation(program.getProgram(), 'u_scale'); 337 /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions); 338 339 gl.useProgram(program.getProgram()); 340 gl.uniform3fv(scaleLoc, scale); 341 342 gl.viewport(0, 0, width, height); 343 gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indices)); 344 345 testImg.readViewport(gl, [0, 0, width, height]); 346 347 // Draw reference 348 for (var y = 0; y < refImg.getHeight(); y++) { 349 for (var x = 0; x < refImg.getWidth(); x++) { 350 /** @type {number} */ var xf = (x + .5) / refImg.getWidth(); 351 /** @type {number} */ var yf = (refImg.getHeight() - y - 1 + .5) / refImg.getHeight(); 352 /** @type {number} */ var z = (xf + yf) / 2.0; 353 /** @type {Array<number>} */ var fragCoord = [x + .5, y + .5, z]; 354 /** @type {Array<number>} */ var scaledFC = deMath.multiply(fragCoord, scale); 355 /** @type {Array<number>} */ 356 var color = [ 357 deMath.clamp(Math.floor(scaledFC[0] * 255 + 0.5), 0, 255), 358 deMath.clamp(Math.floor(scaledFC[1] * 255 + 0.5), 0, 255), 359 deMath.clamp(Math.floor(scaledFC[2] * 255 + 0.5), 0, 255), 360 255]; 361 refImg.setPixel(x, y, color); 362 } 363 } 364 365 // Compare 366 /** @type {boolean} */ var isOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', refImg, testImg, threshold); 367 368 if (!isOk) 369 testFailedOptions('Image comparison failed', false); 370 else 371 testPassedOptions('Pass', true); 372 373 return tcuTestCase.IterateResult.STOP; 374 }; 375 376 /** 377 * @param {Array<number>} s 378 * @param {Array<number>} w 379 * @param {number} nx 380 * @param {number} ny 381 * @return {number} 382 */ 383 es3fShaderBuiltinVarTests.projectedTriInterpolate = function(s, w, nx, ny) { 384 return (s[0] * (1.0 - nx - ny)/w[0] + s[1] * ny / w[1] + s[2] * nx / w[2]) / ((1.0 - nx - ny) / w[0] + ny / w[1] + nx / w[2]); 385 }; 386 387 /** 388 * @constructor 389 * @extends {tcuTestCase.DeqpTest} 390 */ 391 es3fShaderBuiltinVarTests.FragCoordWCase = function() { 392 tcuTestCase.DeqpTest.call(this, 'fragcoord_w', 'gl_FragCoord.w Test'); 393 }; 394 395 es3fShaderBuiltinVarTests.FragCoordWCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 396 es3fShaderBuiltinVarTests.FragCoordWCase.prototype.constructor = es3fShaderBuiltinVarTests.FragCoordWCase; 397 398 /** 399 * @return {tcuTestCase.IterateResult} 400 */ 401 es3fShaderBuiltinVarTests.FragCoordWCase.prototype.iterate = function() { 402 /** @type {number} */ var width = gl.drawingBufferWidth; 403 /** @type {number} */ var height = gl.drawingBufferHeight; 404 /** @type {Array<number>} */ var threshold = deMath.add([1, 1, 1, 1], tcuPixelFormat.PixelFormatFromContext(gl).getColorThreshold()); 405 406 /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height); 407 /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height); 408 409 /** @type {Array<number>} */ var w = [1.7, 2.0, 1.2, 1.0]; 410 411 /** @type {string} */ var vtxSource = '#version 300 es\n' + 412 'in highp vec4 a_position;\n' + 413 'void main (void)\n' + 414 '{\n' + 415 ' gl_Position = a_position;\n' + 416 '}\n'; 417 418 /** @type {string} */ var fragSource = '#version 300 es\n' + 419 'layout(location = 0) out mediump vec4 o_color;\n' + 420 'void main (void)\n' + 421 '{\n' + 422 ' o_color = vec4(0.0, 1.0/gl_FragCoord.w - 1.0, 0.0, 1.0);\n' + 423 '}\n'; 424 425 /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource)); 426 bufferedLogToConsole(program.getProgramInfo().infoLog); 427 428 if (!program.isOk()) 429 throw new Error('Compile failed'); 430 431 // Draw with GL. 432 /** @type {Array<number>} */ var positions = [ 433 -w[0], w[0], 0.0, w[0], 434 -w[1], -w[1], 0.0, w[1], 435 w[2], w[2], 0.0, w[2], 436 w[3], -w[3], 0.0, w[3] 437 ]; 438 /** @type {Array<number>} */ var indices = [0, 1, 2, 2, 1, 3]; 439 440 /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions); 441 gl.useProgram(program.getProgram()); 442 443 gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indices)); 444 testImg.readViewport(gl, [0, 0, width, height]); 445 446 // Draw reference 447 for (var y = 0; y < refImg.getHeight(); y++) { 448 for (var x = 0; x < refImg.getWidth(); x++) { 449 /** @type {number} */ var xf = (x + 0.5) / refImg.getWidth(); 450 /** @type {number} */ var yf = (refImg.getHeight() - y - 1 + 0.5) / refImg.getHeight(); 451 /** @type {number} */ var oow = ((xf + yf) < 1.0) ? 452 es3fShaderBuiltinVarTests.projectedTriInterpolate([w[0], w[1], w[2]], [w[0], w[1], w[2]], xf, yf) : 453 es3fShaderBuiltinVarTests.projectedTriInterpolate([w[3], w[2], w[1]], [w[3], w[2], w[1]], 1.0 - xf, 1.0 - yf); 454 /** @type {Array<number>} */ 455 var color = [ 456 0, 457 deMath.clamp(Math.floor((oow - 1.0) * 255 + 0.5), 0, 255), 458 0, 459 255]; 460 refImg.setPixel(x, y, color); 461 } 462 } 463 464 // Compare 465 /** @type {boolean} */ var isOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', refImg, testImg, threshold); 466 467 if (!isOk) { 468 testFailedOptions('Image comparison failed', false); 469 } else 470 testPassedOptions('Pass', true); 471 472 return tcuTestCase.IterateResult.STOP; 473 }; 474 475 /** 476 * @constructor 477 * @extends {tcuTestCase.DeqpTest} 478 */ 479 es3fShaderBuiltinVarTests.PointCoordCase = function() { 480 tcuTestCase.DeqpTest.call(this, 'pointcoord', 'gl_PointCoord Test'); 481 }; 482 483 es3fShaderBuiltinVarTests.PointCoordCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 484 es3fShaderBuiltinVarTests.PointCoordCase.prototype.constructor = es3fShaderBuiltinVarTests.PointCoordCase; 485 486 /** 487 * @return {tcuTestCase.IterateResult} 488 */ 489 es3fShaderBuiltinVarTests.PointCoordCase.prototype.iterate = function() { 490 /** @type {number} */ var width = Math.min(256, gl.drawingBufferWidth); 491 /** @type {number} */ var height = Math.min(256, gl.drawingBufferHeight); 492 /** @type {number} */ var threshold = 0.02; 493 494 /** @type {number} */ var numPoints = 8; 495 496 /** @type {Array<number>} */ var coords = []; 497 /** @type {Array<number>} */ var pointSizeRange = [0.0, 0.0]; 498 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0x145fa); 499 /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height); 500 /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height); 501 502 pointSizeRange = /** @type {Array<number>} */ (gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE)); 503 504 if (pointSizeRange[0] <= 0.0 || pointSizeRange[1] <= 0.0 || pointSizeRange[1] < pointSizeRange[0]) 505 throw new Error('Invalid gl.ALIASED_POINT_SIZE_RANGE'); 506 507 // Compute coordinates. 508 for (var i = 0; i < numPoints; i++) 509 coords.push([ 510 rnd.getFloat(-0.9, 0.9), 511 rnd.getFloat(-0.9, 0.9), 512 rnd.getFloat(pointSizeRange[0], pointSizeRange[1]) 513 ]); 514 515 /** @type {string} */ var vtxSource = '#version 300 es\n' + 516 'in highp vec3 a_positionSize;\n' + 517 'void main (void)\n' + 518 '{\n' + 519 ' gl_Position = vec4(a_positionSize.xy, 0.0, 1.0);\n' + 520 ' gl_PointSize = a_positionSize.z;\n' + 521 '}\n'; 522 523 /** @type {string} */ var fragSource = '#version 300 es\n' + 524 'layout(location = 0) out mediump vec4 o_color;\n' + 525 'void main (void)\n' + 526 '{\n' + 527 ' o_color = vec4(gl_PointCoord, 0.0, 1.0);\n' + 528 '}\n'; 529 530 /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource)); 531 bufferedLogToConsole(program.getProgramInfo().infoLog); 532 533 if (!program.isOk()) 534 throw new Error('Compile failed'); 535 536 // Draw with GL. 537 var newCoords = [].concat.apply([], coords); 538 539 // /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_positionSize', 3, coords.length, 0, coords); 540 /** @type {gluDrawUtil.VertexArrayBinding} */ 541 var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_positionSize', 3, coords.length, 12, newCoords); 542 /** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - width); 543 /** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - height); 544 545 gl.viewport(viewportX, viewportY, width, height); 546 gl.clearColor(0.0, 0.0, 0.0, 1.0); 547 gl.clear(gl.COLOR_BUFFER_BIT); 548 549 gl.useProgram(program.getProgram()); 550 551 gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.pointsFromElements(coords.length)); 552 testImg.readViewport(gl, [viewportX, viewportY, width, height]); 553 554 // Draw reference 555 refImg.getAccess().clear([0.0, 0.0, 0.0, 1.0]); 556 for (var i = 0; i < coords.length; i++) { 557 /** @type {number} */ var x0 = Math.round(width * (coords[i][0] * 0.5 + 0.5) - coords[i][2] * 0.5); 558 /** @type {number} */ var y0 = Math.round(height* (coords[i][1] * 0.5 + 0.5) - coords[i][2] * 0.5); 559 /** @type {number} */ var x1 = Math.round(width * (coords[i][0] * 0.5 + 0.5) + coords[i][2] * 0.5); 560 /** @type {number} */ var y1 = Math.round(height * (coords[i][1] * 0.5 + 0.5) + coords[i][2] * 0.5); 561 /** @type {number} */ var w = x1 - x0; 562 /** @type {number} */ var h = y1 - y0; 563 564 for (var yo = 0; yo < h; yo++) { 565 for (var xo = 0; xo < w; xo++) { 566 /** @type {number} */ var xf = (xo + 0.5) / w; 567 /** @type {number} */ var yf = ((h - yo - 1) + 0.5) / h; 568 /** @type {number} */ var dx = x0 + xo; 569 /** @type {number} */ var dy = y0 + yo; 570 /** @type {Array<number>} */ 571 var color = [ 572 deMath.clamp(Math.floor(xf * 255 + 0.5), 0, 255), 573 deMath.clamp(Math.floor(yf * 255 + 0.5), 0, 255), 574 0, 575 255]; 576 if (deMath.deInBounds32(dx, 0, refImg.getWidth()) && deMath.deInBounds32(dy, 0, refImg.getHeight())) 577 refImg.setPixel(dx, dy, color); 578 } 579 } 580 } 581 582 // Compare 583 /** @type {boolean} */ var isOk = tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', refImg.getAccess(), testImg.getAccess(), threshold); 584 585 if (!isOk) { 586 testFailedOptions('Image comparison failed', false); 587 } else 588 testPassedOptions('Pass', true); 589 590 return tcuTestCase.IterateResult.STOP; 591 }; 592 593 /** 594 * @constructor 595 * @extends {tcuTestCase.DeqpTest} 596 */ 597 es3fShaderBuiltinVarTests.FrontFacingCase = function() { 598 tcuTestCase.DeqpTest.call(this, 'frontfacing', 'gl_FrontFacing Test'); 599 }; 600 601 es3fShaderBuiltinVarTests.FrontFacingCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 602 es3fShaderBuiltinVarTests.FrontFacingCase.prototype.constructor = es3fShaderBuiltinVarTests.FrontFacingCase; 603 604 /** 605 * @return {tcuTestCase.IterateResult} 606 */ 607 es3fShaderBuiltinVarTests.FrontFacingCase.prototype.iterate = function() { 608 // Test case renders two adjecent quads, where left is has front-facing 609 // triagles and right back-facing. Color is selected based on gl_FrontFacing 610 // value. 611 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0x89f2c); 612 /** @type {number} */ var width = Math.min(64, gl.drawingBufferWidth); 613 /** @type {number} */ var height = Math.min(64, gl.drawingBufferHeight); 614 /** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - width); 615 /** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - height); 616 /** @type {Array<number>} */ var threshold = deMath.add([1, 1, 1, 1], tcuPixelFormat.PixelFormatFromContext(gl).getColorThreshold()); 617 618 /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height); 619 /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height); 620 621 /** @type {string} */ var vtxSource = '#version 300 es\n' + 622 'in highp vec4 a_position;\n' + 623 'void main (void)\n' + 624 '{\n' + 625 ' gl_Position = a_position;\n' + 626 '}\n'; 627 628 /** @type {string} */ var fragSource = '#version 300 es\n' + 629 'layout(location = 0) out mediump vec4 o_color;\n' + 630 'void main (void)\n' + 631 '{\n' + 632 ' if (gl_FrontFacing)\n' + 633 ' o_color = vec4(0.0, 1.0, 0.0, 1.0);\n' + 634 ' else\n' + 635 ' o_color = vec4(0.0, 0.0, 1.0, 1.0);\n' + 636 '}\n'; 637 638 /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource)); 639 640 bufferedLogToConsole(program.getProgramInfo().infoLog); 641 642 if (!program.isOk()) 643 throw new Error('Compile failed'); 644 645 // Draw with GL. 646 /** @type {Array<number>} */ var positions = [ 647 -1.0, 1.0, 0.0, 1.0, 648 -1.0, -1.0, 0.0, 1.0, 649 1.0, 1.0, 0.0, 1.0, 650 1.0, -1.0, 0.0, 1.0 651 ]; 652 653 /** @type {Array<number>} */ var indicesCCW = [0, 1, 2, 2, 1, 3]; 654 /** @type {Array<number>} */ var indicesCW = [2, 1, 0, 3, 1, 2]; 655 656 /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions); 657 658 gl.useProgram(program.getProgram()); 659 660 gl.viewport(viewportX, viewportY, Math.floor(width / 2), height); 661 662 gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indicesCCW)); 663 664 gl.viewport(viewportX + Math.floor(width / 2), viewportY, width - Math.floor(width / 2), height); 665 gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indicesCW)); 666 testImg.readViewport(gl, [viewportX, viewportY, width, height]); 667 // Draw reference 668 for (var y = 0; y < refImg.getHeight(); y++) { 669 for (var x = 0; x < Math.floor(refImg.getWidth() / 2); x++) 670 refImg.setPixel(x, y, tcuRGBA.RGBA.green.toIVec()); 671 672 for (var x = Math.floor(refImg.getWidth() / 2); x < refImg.getWidth(); x++) 673 refImg.setPixel(x, y, tcuRGBA.RGBA.blue.toIVec()); 674 } 675 676 // Compare 677 /** @type {boolean} */ var isOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', refImg, testImg, threshold); 678 679 if (!isOk) { 680 testFailedOptions('Image comparison failed', false); 681 } else 682 testPassedOptions('Pass', true); 683 684 return tcuTestCase.IterateResult.STOP; 685 }; 686 687 /** 688 * @constructor 689 * @extends {tcuTestCase.DeqpTest} 690 */ 691 es3fShaderBuiltinVarTests.VertexIDCase = function() { 692 tcuTestCase.DeqpTest.call(this, 'vertex_id', 'gl_VertexID Test'); 693 /** @type {?gluShaderProgram.ShaderProgram} */ this.m_program = null; 694 /** @type {WebGLBuffer} */ this.m_positionBuffer = null; 695 /** @type {WebGLBuffer} */ this.m_elementBuffer = null; 696 /** @type {number} */ this.m_viewportW = 0; 697 /** @type {number} */ this.m_viewportH = 0; 698 /** @type {number} */ this.m_iterNdx = 0; 699 /** @type {Array<Array<number>>} */ this.m_positions = []; 700 /** @type {Array<Array<number>>} */ this.m_colors = []; 701 }; 702 703 es3fShaderBuiltinVarTests.VertexIDCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 704 es3fShaderBuiltinVarTests.VertexIDCase.prototype.constructor = es3fShaderBuiltinVarTests.VertexIDCase; 705 706 es3fShaderBuiltinVarTests.VertexIDCase.MAX_VERTICES = 24; //!< 8 triangles, totals 24 vertices 707 708 es3fShaderBuiltinVarTests.VertexIDCase.prototype.init = function() { 709 /** @type {number} */ var width = gl.drawingBufferWidth; 710 /** @type {number} */ var height = gl.drawingBufferHeight; 711 712 /** @type {number} */ var quadWidth = 32; 713 /** @type {number} */ var quadHeight = 32; 714 715 if (width < quadWidth) 716 throw new Error('Too small render target'); 717 718 /** @type {number} */ var maxQuadsX = Math.floor(width / quadWidth); 719 /** @type {number} */ var numVertices = es3fShaderBuiltinVarTests.VertexIDCase.MAX_VERTICES; 720 721 /** @type {number} */ var numQuads = Math.floor(numVertices / 6) + (numVertices % 6 != 0 ? 1 : 0); 722 /** @type {number} */ var viewportW = Math.min(numQuads, maxQuadsX)*quadWidth; 723 /** @type {number} */ var viewportH = (Math.floor(numQuads/maxQuadsX) + (numQuads % maxQuadsX != 0 ? 1 : 0)) * quadHeight; 724 725 if (viewportH > height) 726 throw new Error('Too small render target'); 727 728 assertMsgOptions(viewportW <= width && viewportH <= height, 'Unexpected viewport dimensions.', false, true); 729 730 assertMsgOptions(!this.m_program, 'Program should not be defined at this point.', false, true); 731 732 /** @type {string} */ var vtxSource = '#version 300 es\n' + 733 'in highp vec4 a_position;\n' + 734 'out mediump vec4 v_color;\n' + 735 'uniform highp vec4 u_colors[24];\n' + 736 'void main (void)\n' + 737 '{\n' + 738 ' gl_Position = a_position;\n' + 739 ' v_color = u_colors[gl_VertexID];\n' + 740 '}\n'; 741 742 /** @type {string} */ var fragSource = '#version 300 es\n' + 743 'in mediump vec4 v_color;\n' + 744 'layout(location = 0) out mediump vec4 o_color;\n' + 745 'void main (void)\n' + 746 '{\n' + 747 ' o_color = v_color;\n' + 748 '}\n'; 749 750 this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource)); 751 bufferedLogToConsole(this.m_program.getProgramInfo().infoLog); 752 753 if (!this.m_program.isOk()) { 754 this.m_program = null; 755 throw new Error('Compile failed'); 756 } 757 758 this.m_positionBuffer = gl.createBuffer(); 759 this.m_elementBuffer = gl.createBuffer(); 760 761 // Set colors (in dynamic memory to save static data space). 762 this.m_colors[0] = [0.0, 0.0, 0.0, 1.0]; 763 this.m_colors[1] = [0.5, 1.0, 0.5, 1.0]; 764 this.m_colors[2] = [0.0, 0.5, 1.0, 1.0]; 765 this.m_colors[3] = [0.0, 1.0, 0.0, 1.0]; 766 this.m_colors[4] = [0.0, 1.0, 1.0, 1.0]; 767 this.m_colors[5] = [0.5, 0.0, 0.0, 1.0]; 768 this.m_colors[6] = [0.5, 0.0, 1.0, 1.0]; 769 this.m_colors[7] = [0.5, 0.0, 0.5, 1.0]; 770 this.m_colors[8] = [1.0, 0.0, 0.0, 1.0]; 771 this.m_colors[9] = [0.5, 1.0, 0.0, 1.0]; 772 this.m_colors[10] = [0.0, 0.5, 0.0, 1.0]; 773 this.m_colors[11] = [0.5, 1.0, 1.0, 1.0]; 774 this.m_colors[12] = [0.0, 0.0, 1.0, 1.0]; 775 this.m_colors[13] = [1.0, 0.0, 0.5, 1.0]; 776 this.m_colors[14] = [0.0, 0.5, 0.5, 1.0]; 777 this.m_colors[15] = [1.0, 1.0, 0.5, 1.0]; 778 this.m_colors[16] = [1.0, 0.0, 1.0, 1.0]; 779 this.m_colors[17] = [1.0, 0.5, 0.0, 1.0]; 780 this.m_colors[18] = [0.0, 1.0, 0.5, 1.0]; 781 this.m_colors[19] = [1.0, 0.5, 1.0, 1.0]; 782 this.m_colors[20] = [1.0, 1.0, 0.0, 1.0]; 783 this.m_colors[21] = [1.0, 0.5, 0.5, 1.0]; 784 this.m_colors[22] = [0.0, 0.0, 0.5, 1.0]; 785 this.m_colors[23] = [1.0, 1.0, 1.0, 1.0]; 786 787 // Compute positions. 788 assertMsgOptions(numVertices % 3 == 0, 'Number of vertices should be multiple of 3.', false, true); 789 790 for (var vtxNdx = 0; vtxNdx < numVertices; vtxNdx += 3) { 791 /** @type {number} */ var h = 2.0 * quadHeight / viewportH; 792 /** @type {number} */ var w = 2.0 * quadWidth / viewportW; 793 794 /** @type {number} */ var triNdx = Math.floor(vtxNdx / 3); 795 /** @type {number} */ var quadNdx = Math.floor(triNdx / 2); 796 /** @type {number} */ var quadY = Math.floor(quadNdx / maxQuadsX); 797 /** @type {number} */ var quadX = quadNdx % maxQuadsX; 798 799 /** @type {number} */ var x0 = -1.0 + quadX * w; 800 /** @type {number} */ var y0 = -1.0 + quadY * h; 801 802 if (triNdx % 2 === 0) { 803 this.m_positions[vtxNdx + 0] = [x0, y0, 0.0, 1.0]; 804 this.m_positions[vtxNdx + 1] = [x0+w, y0+h, 0.0, 1.0]; 805 this.m_positions[vtxNdx + 2] = [x0, y0+h, 0.0, 1.0]; 806 } else { 807 this.m_positions[vtxNdx + 0] = [x0 + w, y0 + h, 0.0, 1.0]; 808 this.m_positions[vtxNdx + 1] = [x0, y0, 0.0, 1.0]; 809 this.m_positions[vtxNdx + 2] = [x0+w, y0, 0.0, 1.0]; 810 } 811 } 812 813 this.m_viewportW = viewportW; 814 this.m_viewportH = viewportH; 815 this.m_iterNdx = 0; 816 817 }; 818 819 es3fShaderBuiltinVarTests.VertexIDCase.prototype.deinit = function() { 820 this.m_program = null; 821 822 if (this.m_positionBuffer) { 823 gl.deleteBuffer(this.m_positionBuffer); 824 this.m_positionBuffer = null; 825 } 826 827 if (this.m_elementBuffer) { 828 gl.deleteBuffer(this.m_elementBuffer); 829 this.m_elementBuffer = null; 830 } 831 832 this.m_positions = []; 833 this.m_colors = []; 834 }; 835 836 /** 837 * @constructor 838 * @extends {sglrShaderProgram.ShaderProgram} 839 */ 840 es3fShaderBuiltinVarTests.VertexIDReferenceShader = function() { 841 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var declaration = new sglrShaderProgram.ShaderProgramDeclaration(); 842 declaration.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('', rrGenericVector.GenericVecType.FLOAT)); 843 declaration.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('', rrGenericVector.GenericVecType.FLOAT)); 844 declaration.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT, new sglrShaderProgram.VaryingFlags())); 845 declaration.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT)); 846 declaration.pushVertexSource(new sglrShaderProgram.VertexSource('')); // ShaderProgram fails if we don't push a source, even though GLSL source is not used 847 declaration.pushFragmentSource(new sglrShaderProgram.FragmentSource('')); 848 sglrShaderProgram.ShaderProgram.call(this, declaration); 849 }; 850 851 es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype); 852 es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype.constructor = es3fShaderBuiltinVarTests.VertexIDReferenceShader; 853 854 /** @const {number} */ es3fShaderBuiltinVarTests.VertexIDReferenceShader.VARYINGLOC_COLOR = 0; 855 856 /** 857 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs 858 * @param {Array<rrVertexPacket.VertexPacket>} packets 859 */ 860 es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype.shadeVertices = function(inputs, packets) { 861 for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx) { 862 /** @type {number} */ var positionAttrLoc = 0; 863 /** @type {number} */ var colorAttrLoc = 1; 864 865 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx]; 866 867 // Transform to position 868 packet.position = rrVertexAttrib.readVertexAttrib(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT); 869 870 // Pass color to FS 871 packet.outputs[es3fShaderBuiltinVarTests.VertexIDReferenceShader.VARYINGLOC_COLOR] = rrVertexAttrib.readVertexAttrib(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT); 872 } 873 }; 874 875 /** 876 * @param {Array<rrFragmentOperations.Fragment>} packets 877 * @param {rrShadingContext.FragmentShadingContext} context 878 */ 879 es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype.shadeFragments = function(packets, context) { 880 for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx) { 881 /** @type {rrFragmentOperations.Fragment} */ var packet = packets[packetNdx]; 882 packet.value = rrShadingContext.readVarying(packet, context, es3fShaderBuiltinVarTests.VertexIDReferenceShader.VARYINGLOC_COLOR); 883 } 884 }; 885 886 /** 887 * @param {tcuTexture.PixelBufferAccess} dst 888 * @param {Array<number>} indices 889 * @param {goog.NumberArray} positions 890 * @param {goog.NumberArray} colors 891 */ 892 es3fShaderBuiltinVarTests.VertexIDCase.prototype.renderReference = function(dst, indices, positions, colors) { 893 /** @type {rrRenderState.RenderState} */ 894 var referenceState = new rrRenderState.RenderState( 895 new rrRenderState.ViewportState(rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(dst)) 896 ); 897 898 /** @type {rrRenderer.RenderTarget} */ 899 var referenceTarget = new rrRenderer.RenderTarget( 900 rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(dst) 901 ); 902 903 /** @type {es3fShaderBuiltinVarTests.VertexIDReferenceShader} */ 904 var referenceShaderProgram = new es3fShaderBuiltinVarTests.VertexIDReferenceShader(); 905 906 /** @type {Array<rrVertexAttrib.VertexAttrib>} */ var attribs = []; 907 attribs[0] = new rrVertexAttrib.VertexAttrib(); 908 attribs[0].type = rrVertexAttrib.VertexAttribType.FLOAT; 909 attribs[0].size = 4; 910 attribs[0].stride = 0; 911 attribs[0].instanceDivisor = 0; 912 attribs[0].pointer = positions.buffer; 913 914 attribs[1] = new rrVertexAttrib.VertexAttrib(); 915 attribs[1].type = rrVertexAttrib.VertexAttribType.FLOAT; 916 attribs[1].size = 4; 917 attribs[1].stride = 0; 918 attribs[1].instanceDivisor = 0; 919 attribs[1].pointer = colors.buffer; 920 rrRenderer.drawTriangles(referenceState, referenceTarget, referenceShaderProgram, 921 attribs, rrRenderer.PrimitiveType.TRIANGLES, 0, indices.length, /*instanceID = */ 0); 922 }; 923 924 /** 925 * @return {tcuTestCase.IterateResult} 926 */ 927 es3fShaderBuiltinVarTests.VertexIDCase.prototype.iterate = function() { 928 /** @type {number} */ var width = gl.drawingBufferWidth; 929 /** @type {number} */ var height = gl.drawingBufferHeight; 930 /** @type {number} */ var viewportW = this.m_viewportW; 931 /** @type {number} */ var viewportH = this.m_viewportH; 932 933 /** @type {number} */ var threshold = 0.02; 934 935 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xcf23ab1 ^ deString.deStringHash(this.m_iterNdx.toString())); 936 /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(viewportW, viewportH); 937 /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(viewportW, viewportH); 938 939 /** @type {number} */ var viewportX = rnd.getInt(0, width - viewportW); 940 /** @type {number} */ var viewportY = rnd.getInt(0, height - viewportH); 941 942 /** @type {number} */ var posLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position'); 943 /** @type {WebGLUniformLocation} */ var colorsLoc = gl.getUniformLocation(this.m_program.getProgram(), 'u_colors[0]'); 944 /** @type {Array<number>} */ var clearColor = [0.0, 0.0, 0.0, 1.0]; 945 /** @type {Array<number>} */ var indices = []; 946 /** @type {Array<Array<number>>} */ var mappedPos = []; 947 /** @type {goog.NumberArray} */ var flatColorArray; 948 /** @type {goog.NumberArray} */ var flatPosArray; 949 // Setup common state. 950 gl.viewport(viewportX, viewportY, viewportW, viewportH); 951 gl.useProgram(this.m_program.getProgram()); 952 gl.bindBuffer(gl.ARRAY_BUFFER, this.m_positionBuffer); 953 gl.enableVertexAttribArray(posLoc); 954 gl.vertexAttribPointer(posLoc, 4, gl.FLOAT, false, 0, 0); 955 gl.uniform4fv(colorsLoc, [].concat.apply([], this.m_colors)); 956 957 // Clear render target to black. 958 gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); 959 gl.clear(gl.COLOR_BUFFER_BIT); 960 961 refImg.getAccess().clear(clearColor); 962 963 if (this.m_iterNdx === 0) { 964 bufferedLogToConsole('Iter0: glDrawArrays()'); 965 966 flatPosArray = new Float32Array([].concat.apply([], this.m_positions)); 967 flatColorArray = new Float32Array([].concat.apply([], this.m_colors)); 968 gl.bufferData(gl.ARRAY_BUFFER, flatPosArray.buffer, gl.DYNAMIC_DRAW); 969 gl.drawArrays(gl.TRIANGLES, 0, Math.floor(flatPosArray.length / 4)); 970 971 //glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess()); 972 testImg.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]); 973 // Reference indices 974 for (var ndx = 0; ndx < this.m_positions.length; ndx++) 975 indices.push(ndx); 976 977 this.renderReference(refImg.getAccess(), indices, flatPosArray, flatColorArray); 978 } else if (this.m_iterNdx === 1) { 979 bufferedLogToConsole('Iter1: glDrawElements(), indices in buffer'); 980 981 // Compute initial indices and suffle 982 for (var ndx = 0; ndx < this.m_positions.length; ndx++) 983 indices.push(ndx); 984 // deRandom.shuffle(rnd, indices); 985 // \note [2015-08-05 dag] The original test shuffles the indices array but the reference renderer cannot handle triangles with sides not parallel to the axes. 986 987 // Use indices to re-map positions. 988 for (var ndx = 0; ndx < indices.length; ndx++) 989 mappedPos[indices[ndx]] = this.m_positions[ndx]; 990 991 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.m_elementBuffer); 992 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, (new Uint16Array(indices)).buffer, gl.DYNAMIC_DRAW); 993 994 flatPosArray = new Float32Array([].concat.apply([], mappedPos)); 995 flatColorArray = new Float32Array([].concat.apply([], this.m_colors)); 996 gl.bufferData(gl.ARRAY_BUFFER, flatPosArray.buffer, gl.DYNAMIC_DRAW); 997 gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); 998 999 //glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess()); 1000 testImg.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]); 1001 refImg.getAccess().clear(clearColor); 1002 this.renderReference(refImg.getAccess(), indices, flatPosArray, flatColorArray); 1003 } else 1004 throw new Error('Iteration count exceeded.'); 1005 1006 if (!tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', refImg.getAccess(), testImg.getAccess(), threshold)) 1007 testFailedOptions('Image comparison failed', false); 1008 else 1009 testPassedOptions('Pass', true); 1010 1011 this.m_iterNdx += 1; 1012 return (this.m_iterNdx < 2) ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP; 1013 }; 1014 1015 /** 1016 * @constructor 1017 * @extends {tcuTestCase.DeqpTest} 1018 */ 1019 es3fShaderBuiltinVarTests.ShaderBuiltinVarTests = function() { 1020 tcuTestCase.DeqpTest.call(this, 'builtin_variable', 'Built-in Variable Tests'); 1021 }; 1022 1023 es3fShaderBuiltinVarTests.ShaderBuiltinVarTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 1024 es3fShaderBuiltinVarTests.ShaderBuiltinVarTests.prototype.constructor = es3fShaderBuiltinVarTests.ShaderBuiltinVarTests; 1025 1026 es3fShaderBuiltinVarTests.ShaderBuiltinVarTests.prototype.init = function() { 1027 var testGroup = tcuTestCase.runner.testCases; 1028 // Builtin constants. 1029 /** 1030 * @struct 1031 * @constructor 1032 * @param {string} caseName 1033 * @param {string} varName 1034 * @param {es3fShaderBuiltinVarTests.GetConstantValueFunc} getValue 1035 */ 1036 var BuiltinConstant = function(caseName, varName, getValue) { 1037 /** @type {string} */ this.caseName = caseName; 1038 /** @type {string} */ this.varName = varName; 1039 /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ this.getValue = getValue; 1040 1041 }; 1042 1043 /** @type {Array<BuiltinConstant>} */ var builtinConstants = [ 1044 // GLES 2. 1045 1046 new BuiltinConstant('max_vertex_attribs', 'gl_MaxVertexAttribs', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_VERTEX_ATTRIBS); }), 1047 new BuiltinConstant('max_vertex_uniform_vectors', 'gl_MaxVertexUniformVectors', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_VERTEX_UNIFORM_VECTORS); }), 1048 new BuiltinConstant('max_fragment_uniform_vectors', 'gl_MaxFragmentUniformVectors', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_FRAGMENT_UNIFORM_VECTORS); }), 1049 new BuiltinConstant('max_texture_image_units', 'gl_MaxTextureImageUnits', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_TEXTURE_IMAGE_UNITS); }), 1050 new BuiltinConstant('max_vertex_texture_image_units', 'gl_MaxVertexTextureImageUnits', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); }), 1051 new BuiltinConstant('max_combined_texture_image_units', 'gl_MaxCombinedTextureImageUnits', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); }), 1052 new BuiltinConstant('max_draw_buffers', 'gl_MaxDrawBuffers', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_DRAW_BUFFERS); }), 1053 1054 // GLES 3. 1055 1056 new BuiltinConstant('max_vertex_output_vectors', 'gl_MaxVertexOutputVectors', function() { return es3fShaderBuiltinVarTests.getVectorsFromComps(gl.MAX_VERTEX_OUTPUT_COMPONENTS); }), 1057 new BuiltinConstant('max_fragment_input_vectors', 'gl_MaxFragmentInputVectors', function() { return es3fShaderBuiltinVarTests.getVectorsFromComps(gl.MAX_FRAGMENT_INPUT_COMPONENTS); }), 1058 new BuiltinConstant('min_program_texel_offset', 'gl_MinProgramTexelOffset', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MIN_PROGRAM_TEXEL_OFFSET); }), 1059 new BuiltinConstant('max_program_texel_offset', 'gl_MaxProgramTexelOffset', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_PROGRAM_TEXEL_OFFSET); }) 1060 ]; 1061 1062 for (var ndx = 0; ndx < builtinConstants.length; ndx++) { 1063 /** @type {string} */ var caseName = builtinConstants[ndx].caseName; 1064 /** @type {string} */ var varName = builtinConstants[ndx].varName; 1065 /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ var getValue = builtinConstants[ndx].getValue; 1066 1067 testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase(caseName + '_vertex', varName, varName, getValue, gluShaderProgram.shaderType.VERTEX)); 1068 testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase(caseName + '_fragment', varName, varName, getValue, gluShaderProgram.shaderType.FRAGMENT)); 1069 } 1070 1071 testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderDepthRangeTest('depth_range_vertex', 'gl_DepthRange', true)); 1072 testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderDepthRangeTest('depth_range_fragment', 'gl_DepthRange', false)); 1073 1074 // Vertex shader builtin variables. 1075 testGroup.addChild(new es3fShaderBuiltinVarTests.VertexIDCase()); 1076 // \todo [2013-03-20 pyry] gl_InstanceID -- tested in instancing tests quite thoroughly. 1077 1078 // Fragment shader builtin variables. 1079 testGroup.addChild(new es3fShaderBuiltinVarTests.FragCoordXYZCase()); 1080 testGroup.addChild(new es3fShaderBuiltinVarTests.FragCoordWCase()); 1081 testGroup.addChild(new es3fShaderBuiltinVarTests.PointCoordCase()); 1082 testGroup.addChild(new es3fShaderBuiltinVarTests.FrontFacingCase()); 1083 }; 1084 1085 /** 1086 * Run test 1087 * @param {WebGL2RenderingContext} context 1088 */ 1089 es3fShaderBuiltinVarTests.run = function(context) { 1090 gl = context; 1091 //Set up Test Root parameters 1092 var state = tcuTestCase.runner; 1093 state.setRoot(new es3fShaderBuiltinVarTests.ShaderBuiltinVarTests()); 1094 1095 //Set up name and description of this test series. 1096 setCurrentTestName(state.testCases.fullName()); 1097 description(state.testCases.getDescription()); 1098 1099 try { 1100 //Run test cases 1101 tcuTestCase.runTestCases(); 1102 } 1103 catch (err) { 1104 testFailedOptions('Failed to es3fShaderBuiltinVarTests.run tests', false); 1105 tcuTestCase.runner.terminate(); 1106 } 1107 }; 1108 1109 });