sglrReferenceContext.js (223251B)
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('framework.opengl.simplereference.sglrReferenceContext'); 23 goog.require('framework.common.tcuMatrix'); 24 goog.require('framework.common.tcuMatrixUtil'); 25 goog.require('framework.common.tcuPixelFormat'); 26 goog.require('framework.common.tcuTexture'); 27 goog.require('framework.common.tcuTextureUtil'); 28 goog.require('framework.delibs.debase.deMath'); 29 goog.require('framework.opengl.gluShaderUtil'); 30 goog.require('framework.opengl.gluTextureUtil'); 31 goog.require('framework.opengl.simplereference.sglrReferenceUtils'); 32 goog.require('framework.opengl.simplereference.sglrShaderProgram'); 33 goog.require('framework.referencerenderer.rrDefs'); 34 goog.require('framework.referencerenderer.rrGenericVector'); 35 goog.require('framework.referencerenderer.rrMultisamplePixelBufferAccess'); 36 goog.require('framework.referencerenderer.rrRenderState'); 37 goog.require('framework.referencerenderer.rrRenderer'); 38 goog.require('framework.referencerenderer.rrVertexAttrib'); 39 40 goog.scope(function() { 41 42 var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext; 43 var rrMultisamplePixelBufferAccess = framework.referencerenderer.rrMultisamplePixelBufferAccess; 44 var tcuTexture = framework.common.tcuTexture; 45 var deMath = framework.delibs.debase.deMath; 46 var gluTextureUtil = framework.opengl.gluTextureUtil; 47 var tcuTextureUtil = framework.common.tcuTextureUtil; 48 var tcuPixelFormat = framework.common.tcuPixelFormat; 49 var gluShaderUtil = framework.opengl.gluShaderUtil; 50 var rrRenderer = framework.referencerenderer.rrRenderer; 51 var rrDefs = framework.referencerenderer.rrDefs; 52 var rrGenericVector = framework.referencerenderer.rrGenericVector; 53 var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib; 54 var rrRenderState = framework.referencerenderer.rrRenderState; 55 var sglrReferenceUtils = framework.opengl.simplereference.sglrReferenceUtils; 56 var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram; 57 var tcuMatrix = framework.common.tcuMatrix; 58 var tcuMatrixUtil = framework.common.tcuMatrixUtil; 59 60 sglrReferenceContext.rrMPBA = rrMultisamplePixelBufferAccess; 61 62 //TODO: Implement automatic error checking in sglrReferenceContext, optional on creation. 63 64 /** @typedef {WebGLRenderbuffer|WebGLTexture|sglrReferenceContext.Renderbuffer|sglrReferenceContext.TextureContainer} */ sglrReferenceContext.AnyRenderbuffer; 65 66 /** @typedef {WebGLFramebuffer|sglrReferenceContext.Framebuffer} */ sglrReferenceContext.AnyFramebuffer; 67 68 /** 69 * @param {number} error 70 * @param {number} message 71 * @throws {Error} 72 */ 73 sglrReferenceContext.GLU_EXPECT_NO_ERROR = function(error, message) { 74 if (error !== gl.NONE) { 75 bufferedLogToConsole('Assertion failed message:' + message); 76 } 77 }; 78 79 var DE_ASSERT = function(x) { 80 if (!x) 81 throw new Error('Assert failed'); 82 }; 83 84 // /* TODO: remove */ 85 // /** @type {WebGL2RenderingContext} */ var gl; 86 87 sglrReferenceContext.MAX_TEXTURE_SIZE_LOG2 = 14; 88 sglrReferenceContext.MAX_TEXTURE_SIZE = 1 << sglrReferenceContext.MAX_TEXTURE_SIZE_LOG2; 89 90 /** 91 * @param {number} width 92 * @param {number} height 93 * @return {number} 94 */ 95 sglrReferenceContext.getNumMipLevels2D = function(width, height) { 96 return Math.floor(Math.log2(Math.max(width, height)) + 1); 97 }; 98 99 /** 100 * @param {number} width 101 * @param {number} height 102 * @param {number} depth 103 * @return {number} 104 */ 105 sglrReferenceContext.getNumMipLevels3D = function(width, height, depth) { 106 return Math.floor(Math.log2(Math.max(width, height, depth)) + 1); 107 }; 108 109 /** 110 * @param {number} baseLevelSize 111 * @param {number} levelNdx 112 * @return {number} 113 */ 114 sglrReferenceContext.getMipLevelSize = function(baseLevelSize, levelNdx) { 115 return Math.max(baseLevelSize >> levelNdx, 1); 116 }; 117 118 sglrReferenceContext.mapGLCubeFace = function(face) { 119 switch (face) { 120 case gl.TEXTURE_CUBE_MAP_NEGATIVE_X: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X; 121 case gl.TEXTURE_CUBE_MAP_POSITIVE_X: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_X; 122 case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y; 123 case gl.TEXTURE_CUBE_MAP_POSITIVE_Y: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y; 124 case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z; 125 case gl.TEXTURE_CUBE_MAP_POSITIVE_Z: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z; 126 default: throw new Error('Invalid cube face: ' + face); 127 } 128 }; 129 130 /** 131 * @param {tcuTexture.FilterMode} mode 132 * @return {boolean} 133 */ 134 sglrReferenceContext.isMipmapFilter = function(/*const tcu::Sampler::FilterMode*/ mode) { 135 return mode != tcuTexture.FilterMode.NEAREST && mode != tcuTexture.FilterMode.LINEAR; 136 }; 137 138 sglrReferenceContext.getNumMipLevels1D = function(size) { 139 return Math.floor(Math.log2(size)) + 1; 140 }; 141 142 /** 143 * @param {?sglrReferenceContext.TextureType} type 144 * @return {sglrReferenceContext.TexTarget} 145 */ 146 sglrReferenceContext.texLayeredTypeToTarget = function(type) { 147 switch (type) { 148 case sglrReferenceContext.TextureType.TYPE_2D_ARRAY: return sglrReferenceContext.TexTarget.TEXTARGET_2D_ARRAY; 149 case sglrReferenceContext.TextureType.TYPE_3D: return sglrReferenceContext.TexTarget.TEXTARGET_3D; 150 case sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_ARRAY; 151 default: throw new Error('Invalid texture type: ' + type); 152 } 153 }; 154 155 /** 156 * @param {rrDefs.IndexType} indexType 157 * @return {number} 158 * @throws {Error} 159 */ 160 sglrReferenceContext.getFixedRestartIndex = function(indexType) { 161 switch (indexType) { 162 case rrDefs.IndexType.INDEXTYPE_UINT8: return 0xFF; 163 case rrDefs.IndexType.INDEXTYPE_UINT16: return 0xFFFF; 164 case rrDefs.IndexType.INDEXTYPE_UINT32: return 0xFFFFFFFF; 165 default: 166 throw new Error('Unrecognized index type: ' + indexType); 167 } 168 }; 169 170 /** 171 * @constructor 172 * @param {sglrShaderProgram.ShaderProgram} program 173 */ 174 sglrReferenceContext.ShaderProgramObjectContainer = function(program) { 175 this.m_program = program; 176 /** @type {boolean} */ this.m_deleteFlag = false; 177 }; 178 179 /** 180 * @param {WebGL2RenderingContext} gl 181 * @constructor 182 */ 183 sglrReferenceContext.ReferenceContextLimits = function(gl) { 184 /** @type {number} */ this.maxTextureImageUnits = 16; 185 /** @type {number} */ this.maxTexture2DSize = 2048; 186 /** @type {number} */ this.maxTextureCubeSize = 2048; 187 /** @type {number} */ this.maxTexture2DArrayLayers = 256; 188 /** @type {number} */ this.maxTexture3DSize = 256; 189 /** @type {number} */ this.maxRenderbufferSize = 2048; 190 /** @type {number} */ this.maxVertexAttribs = 16; 191 192 if (gl) { 193 this.maxTextureImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)); 194 this.maxTexture2DSize = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE)); 195 this.maxTextureCubeSize = /** @type {number} */ (gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)); 196 this.maxRenderbufferSize = /** @type {number} */ (gl.getParameter(gl.MAX_RENDERBUFFER_SIZE)); 197 this.maxVertexAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS)); 198 this.maxTexture2DArrayLayers = /** @type {number} */ (gl.getParameter(gl.MAX_ARRAY_TEXTURE_LAYERS)); 199 this.maxTexture3DSize = /** @type {number} */ (gl.getParameter(gl.MAX_3D_TEXTURE_SIZE)); 200 201 // Limit texture sizes to supported values 202 this.maxTexture2DSize = Math.min(this.maxTexture2DSize, sglrReferenceContext.MAX_TEXTURE_SIZE); 203 this.maxTextureCubeSize = Math.min(this.maxTextureCubeSize, sglrReferenceContext.MAX_TEXTURE_SIZE); 204 this.maxTexture3DSize = Math.min(this.maxTexture3DSize, sglrReferenceContext.MAX_TEXTURE_SIZE); 205 206 sglrReferenceContext.GLU_EXPECT_NO_ERROR(gl.getError(), gl.NO_ERROR); 207 } 208 209 /* TODO: Port 210 // \todo [pyry] Figure out following things: 211 // + supported fbo configurations 212 // ... 213 214 // \todo [2013-08-01 pyry] Do we want to make these conditional based on renderCtx? 215 addExtension("gl.EXT_color_buffer_half_float"); 216 addExtension("gl.WEBGL_color_buffer_float"); 217 */ 218 }; 219 220 /** 221 * @enum 222 */ 223 sglrReferenceContext.TextureType = { 224 TYPE_2D: 0, 225 TYPE_CUBE_MAP: 1, 226 TYPE_2D_ARRAY: 2, 227 TYPE_3D: 3, 228 TYPE_CUBE_MAP_ARRAY: 4 229 }; 230 231 /** 232 * @constructor 233 * @implements {rrDefs.Sampler} 234 * @param {sglrReferenceContext.TextureType} type 235 */ 236 sglrReferenceContext.Texture = function(type) { 237 // NamedObject.call(this, name); 238 /** @type {sglrReferenceContext.TextureType} */ this.m_type = type; 239 /** @type {boolean} */ this.m_immutable = false; 240 /** @type {number} */ this.m_baseLevel = 0; 241 /** @type {number} */ this.m_maxLevel = 1000; 242 /** @type {tcuTexture.Sampler} */ this.m_sampler = new tcuTexture.Sampler( 243 tcuTexture.WrapMode.REPEAT_GL, 244 tcuTexture.WrapMode.REPEAT_GL, 245 tcuTexture.WrapMode.REPEAT_GL, 246 tcuTexture.FilterMode.NEAREST_MIPMAP_LINEAR, 247 tcuTexture.FilterMode.LINEAR, 248 0, 249 true, 250 tcuTexture.CompareMode.COMPAREMODE_NONE, 251 0, 252 [0, 0, 0, 0], 253 true); 254 }; 255 256 /** 257 * @param {Array<number>} pos 258 * @param {number=} lod 259 * @throws {Error} 260 */ 261 sglrReferenceContext.Texture.prototype.sample = function(pos, lod) {throw new Error('Intentionally empty. Call method from child class instead'); }; 262 263 /** 264 * @param {Array<Array<number>>} packetTexcoords 265 * @param {number} lodBias 266 * @throws {Error} 267 */ 268 sglrReferenceContext.Texture.prototype.sample4 = function(packetTexcoords, lodBias) {throw new Error('Intentionally empty. Call method from child class instead'); }; 269 270 // sglrReferenceContext.Texture.prototype = Object.create(NamedObject.prototype); 271 // sglrReferenceContext.Texture.prototype.constructor = sglrReferenceContext.Texture; 272 273 /** 274 * @return {number} 275 */ 276 sglrReferenceContext.Texture.prototype.getType = function() { return this.m_type; }; 277 278 /** 279 * @return {number} 280 */ 281 sglrReferenceContext.Texture.prototype.getBaseLevel = function() { return this.m_baseLevel; }; 282 283 /** 284 * @return {number} 285 */ 286 sglrReferenceContext.Texture.prototype.getMaxLevel = function() { return this.m_maxLevel; }; 287 288 /** 289 * @return {boolean} 290 */ 291 sglrReferenceContext.Texture.prototype.isImmutable = function() { return this.m_immutable; }; 292 293 /** 294 * @param {number} baseLevel 295 */ 296 sglrReferenceContext.Texture.prototype.setBaseLevel = function(baseLevel) { this.m_baseLevel = baseLevel; }; 297 298 /** 299 * @param {number} maxLevel 300 */ 301 sglrReferenceContext.Texture.prototype.setMaxLevel = function(maxLevel) { this.m_maxLevel = maxLevel; }; 302 303 /** 304 */ 305 sglrReferenceContext.Texture.prototype.setImmutable = function() { this.m_immutable = true; }; 306 307 /** 308 * @return {tcuTexture.Sampler} 309 */ 310 sglrReferenceContext.Texture.prototype.getSampler = function() { return this.m_sampler; }; 311 312 /** 313 * @constructor 314 */ 315 sglrReferenceContext.TextureLevelArray = function() { 316 /** @type {Array<ArrayBuffer>} */ this.m_data = []; 317 /** @type {Array<tcuTexture.PixelBufferAccess>} */ this.m_access = []; 318 }; 319 320 /** 321 * @param {number} level 322 * @return {boolean} 323 */ 324 sglrReferenceContext.TextureLevelArray.prototype.hasLevel = function(level) { return this.m_data[level] != null; }; 325 326 /** 327 * @param {number} level 328 * @return {tcuTexture.PixelBufferAccess} 329 * @throws {Error} 330 */ 331 sglrReferenceContext.TextureLevelArray.prototype.getLevel = function(level) { 332 if (!this.hasLevel(level)) 333 throw new Error('Level: ' + level + ' is not defined.'); 334 335 return this.m_access[level]; 336 }; 337 338 /** 339 * @return {Array<tcuTexture.PixelBufferAccess>} 340 */ 341 sglrReferenceContext.TextureLevelArray.prototype.getLevels = function() { return this.m_access; }; 342 343 /** 344 * @param {number} level 345 * @param {tcuTexture.TextureFormat} format 346 * @param {number} width 347 * @param {number} height 348 * @param {number} depth 349 */ 350 sglrReferenceContext.TextureLevelArray.prototype.allocLevel = function(level, format, width, height, depth) { 351 /** @type {number} */ var dataSize = format.getPixelSize() * width * height * depth; 352 if (this.hasLevel(level)) 353 this.clearLevel(level); 354 355 this.m_data[level] = new ArrayBuffer(dataSize); 356 this.m_access[level] = new tcuTexture.PixelBufferAccess({ 357 format: format, 358 width: width, 359 height: height, 360 depth: depth, 361 data: this.m_data[level]}); 362 }; 363 364 /** 365 * @param {number} level 366 */ 367 sglrReferenceContext.TextureLevelArray.prototype.clearLevel = function(level) { 368 delete this.m_data[level]; 369 delete this.m_access[level]; 370 }; 371 372 /** 373 */ 374 sglrReferenceContext.TextureLevelArray.prototype.clear = function() { 375 for (var key in this.m_data) 376 delete this.m_data[key]; 377 378 for (var key in this.m_access) 379 delete this.m_access[key]; 380 }; 381 382 /** 383 * @constructor 384 * @extends {sglrReferenceContext.Texture} 385 */ 386 sglrReferenceContext.Texture2D = function() { 387 sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_2D); 388 /** @type {tcuTexture.Texture2DView} */ this.m_view = new tcuTexture.Texture2DView(0, null); 389 /** @type {sglrReferenceContext.TextureLevelArray} */ this.m_levels = new sglrReferenceContext.TextureLevelArray(); 390 }; 391 392 /** 393 */ 394 sglrReferenceContext.Texture2D.prototype = Object.create(sglrReferenceContext.Texture.prototype); 395 sglrReferenceContext.Texture2D.prototype.constructor = sglrReferenceContext.Texture2D; 396 397 sglrReferenceContext.Texture2D.prototype.clearLevels = function() { this.m_levels.clear(); }; 398 399 /** 400 * @param {number} level 401 * @return {boolean} 402 */ 403 sglrReferenceContext.Texture2D.prototype.hasLevel = function(level) { return this.m_levels.hasLevel(level); }; 404 405 /** 406 * @param {number} level 407 * @return {tcuTexture.PixelBufferAccess} 408 */ 409 sglrReferenceContext.Texture2D.prototype.getLevel = function(level) { return this.m_levels.getLevel(level); }; 410 411 /** 412 * @param {number} level 413 * @param {?tcuTexture.TextureFormat} format 414 * @param {number} width 415 * @param {number} height 416 */ 417 sglrReferenceContext.Texture2D.prototype.allocLevel = function(level, format, width, height) { this.m_levels.allocLevel(level, format, width, height, 1); }; 418 419 /** 420 * @return {boolean} 421 */ 422 sglrReferenceContext.Texture2D.prototype.isComplete = function() { 423 /** @type {number} */ var baseLevel = this.getBaseLevel(); 424 425 if (this.hasLevel(baseLevel)) { 426 /** @type {tcuTexture.PixelBufferAccess} */ var level0 = this.getLevel(baseLevel); 427 /** @type {boolean} */ var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 428 429 if (mipmap) { 430 /** @type {tcuTexture.TextureFormat} */ var format = level0.getFormat(); 431 /** @type {number} */ var w = level0.getWidth(); 432 /** @type {number} */ var h = level0.getHeight(); 433 /** @type {number} */ var numLevels = Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(w, h)); 434 435 for (var levelNdx = 1; levelNdx < numLevels; levelNdx++) { 436 if (this.hasLevel(baseLevel + levelNdx)) { 437 /** @type {tcuTexture.PixelBufferAccess} */ var level = this.getLevel(baseLevel + levelNdx); 438 /** @type {number} */ var expectedW = sglrReferenceContext.getMipLevelSize(w, levelNdx); 439 /** @type {number} */ var expectedH = sglrReferenceContext.getMipLevelSize(h, levelNdx); 440 441 if (level.getWidth() != expectedW || 442 level.getHeight() != expectedH || 443 !level.getFormat().isEqual(format)) 444 return false; 445 } else 446 return false; 447 } 448 } 449 450 return true; 451 } else 452 return false; 453 }; 454 455 /** 456 */ 457 sglrReferenceContext.Texture2D.prototype.updateView = function() { 458 /** @type {number} */ var baseLevel = this.getBaseLevel(); 459 460 if (this.hasLevel(baseLevel) && !this.getLevel(baseLevel).isEmpty()) { 461 // Update number of levels in mipmap pyramid. 462 /** @type {number} */ var width = this.getLevel(baseLevel).getWidth(); 463 /** @type {number} */ var height = this.getLevel(baseLevel).getHeight(); 464 /** @type {boolean} */ var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 465 /** @type {number} */ var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1; 466 467 this.m_view = new tcuTexture.Texture2DView(numLevels, this.m_levels.getLevels().slice(baseLevel)); 468 } else 469 this.m_view = new tcuTexture.Texture2DView(0, null); 470 }; 471 472 /** 473 * @param {Array<number>} pos 474 * @param {number=} lod 475 * @return {Array<number>} 476 */ 477 sglrReferenceContext.Texture2D.prototype.sample = function(pos, lod) { 478 return this.m_view.sample(this.getSampler(), pos, lod); 479 }; 480 481 /** 482 * @param {Array<Array<number>>} packetTexcoords 4 vec2 coordinates 483 * @param {number} lodBias_ 484 * @return {Array<Array<number>>} 4 vec4 samples 485 */ 486 sglrReferenceContext.Texture2D.prototype.sample4 = function(packetTexcoords, lodBias_) { 487 /** @type {number} */ var lodBias = lodBias_ || 0; 488 /** @type {number} */ var texWidth = this.m_view.getWidth(); 489 /** @type {number} */ var texHeight = this.m_view.getHeight(); 490 /** @type {Array<Array<number>>}*/ var output = []; 491 492 /** @type {Array<number>}*/ var dFdx0 = deMath.subtract(packetTexcoords[1], packetTexcoords[0]); 493 /** @type {Array<number>}*/ var dFdx1 = deMath.subtract(packetTexcoords[3], packetTexcoords[2]); 494 /** @type {Array<number>}*/ var dFdy0 = deMath.subtract(packetTexcoords[2], packetTexcoords[0]); 495 /** @type {Array<number>}*/ var dFdy1 = deMath.subtract(packetTexcoords[3], packetTexcoords[1]); 496 497 for (var fragNdx = 0; fragNdx < 4; ++fragNdx) { 498 /** @type {Array<number>}*/var dFdx = (fragNdx & 2) ? dFdx1 : dFdx0; 499 /** @type {Array<number>}*/var dFdy = (fragNdx & 1) ? dFdy1 : dFdy0; 500 501 /** @type {number} */ var mu = Math.max(Math.abs(dFdx[0]), Math.abs(dFdy[0])); 502 /** @type {number} */ var mv = Math.max(Math.abs(dFdx[1]), Math.abs(dFdy[1])); 503 /** @type {number} */ var p = Math.max(mu * texWidth, mv * texHeight); 504 505 /** @type {number} */ var lod = Math.log2(p) + lodBias; 506 507 output.push(this.sample([packetTexcoords[fragNdx][0], packetTexcoords[fragNdx][1]], lod)); 508 } 509 510 return output; 511 }; 512 513 /** 514 * @constructor 515 * @extends {sglrReferenceContext.Texture} 516 */ 517 sglrReferenceContext.TextureCube = function() { 518 sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_CUBE_MAP); 519 /** @type {tcuTexture.TextureCubeView} */ this.m_view = new tcuTexture.TextureCubeView(0, null); 520 /** @type {Array<sglrReferenceContext.TextureLevelArray>} */ this.m_levels = []; 521 for (var face in tcuTexture.CubeFace) 522 this.m_levels[tcuTexture.CubeFace[face]] = new sglrReferenceContext.TextureLevelArray(); 523 }; 524 525 /** 526 */ 527 sglrReferenceContext.TextureCube.prototype = Object.create(sglrReferenceContext.Texture.prototype); 528 sglrReferenceContext.TextureCube.prototype.constructor = sglrReferenceContext.Texture2D; 529 530 sglrReferenceContext.TextureCube.prototype.clearLevels = function() { 531 for (var face in tcuTexture.CubeFace) 532 this.m_levels[tcuTexture.CubeFace[face]].clear(); 533 }; 534 535 /** 536 * @param {number} level 537 * @param {tcuTexture.CubeFace} face 538 * @return {boolean} 539 */ 540 sglrReferenceContext.TextureCube.prototype.hasFace = function(level, face) { return this.m_levels[face].hasLevel(level); }; 541 542 /** 543 * @param {number} level 544 * @param {tcuTexture.CubeFace} face 545 * @return {tcuTexture.PixelBufferAccess} 546 */ 547 sglrReferenceContext.TextureCube.prototype.getFace = function(level, face) { return this.m_levels[face].getLevel(level); }; 548 549 /** 550 * @param {number} level 551 * @param {tcuTexture.CubeFace} face 552 * @param {?tcuTexture.TextureFormat} format 553 * @param {number} width 554 * @param {number} height 555 */ 556 sglrReferenceContext.TextureCube.prototype.allocLevel = function(level, face, format, width, height) { 557 this.m_levels[face].allocLevel(level, format, width, height, 1); 558 }; 559 560 sglrReferenceContext.TextureCube.prototype.isComplete = function() { 561 var baseLevel = this.getBaseLevel(); 562 563 if (this.hasFace(baseLevel, tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X)) { 564 var level = this.getFace(baseLevel, tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X); 565 var width = level.getWidth(); 566 var height = level.getHeight(); 567 var format = level.getFormat(); 568 var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 569 var numLevels = mipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1; 570 571 if (width != height) 572 return false; // Non-square is not supported. 573 574 // \note Level 0 is always checked for consistency 575 for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) { 576 var levelW = sglrReferenceContext.getMipLevelSize(width, levelNdx); 577 var levelH = sglrReferenceContext.getMipLevelSize(height, levelNdx); 578 579 for (var face in tcuTexture.CubeFace) { 580 if (this.hasFace(baseLevel + levelNdx, tcuTexture.CubeFace[face])) { 581 level = this.getFace(baseLevel + levelNdx, tcuTexture.CubeFace[face]); 582 583 if (level.getWidth() != levelW || 584 level.getHeight() != levelH || 585 !level.getFormat().isEqual(format)) 586 return false; 587 } else 588 return false; 589 } 590 } 591 592 return true; 593 } else 594 return false; 595 }; 596 597 sglrReferenceContext.TextureCube.prototype.updateView = function() { 598 599 var baseLevel = this.getBaseLevel(); 600 var faces = []; 601 602 if (this.isComplete()) { 603 var size = this.getFace(baseLevel, tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X).getWidth(); 604 var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 605 var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels1D(size)) : 1; 606 607 for (var face in tcuTexture.CubeFace) 608 faces[tcuTexture.CubeFace[face]] = this.m_levels[tcuTexture.CubeFace[face]].getLevels().slice(baseLevel); 609 610 this.m_view = new tcuTexture.TextureCubeView(numLevels, faces); 611 } else 612 this.m_view = new tcuTexture.TextureCubeView(0, null); 613 }; 614 615 /** 616 * @param {Array<number>} pos 617 * @param {number=} lod 618 * @return {Array<number>} 619 */ 620 sglrReferenceContext.TextureCube.prototype.sample = function(pos, lod) { return this.m_view.sample(this.getSampler(), pos, lod) }; 621 622 /** 623 * @constructor 624 * @extends {sglrReferenceContext.Texture} 625 */ 626 sglrReferenceContext.Texture2DArray = function() { 627 sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_2D_ARRAY); 628 /** @type {tcuTexture.Texture2DArrayView} */ this.m_view = new tcuTexture.Texture2DArrayView(0, null); 629 /** @type {sglrReferenceContext.TextureLevelArray} */ this.m_levels = new sglrReferenceContext.TextureLevelArray(); 630 }; 631 632 /** 633 */ 634 sglrReferenceContext.Texture2DArray.prototype = Object.create(sglrReferenceContext.Texture.prototype); 635 sglrReferenceContext.Texture2DArray.prototype.constructor = sglrReferenceContext.Texture2DArray; 636 637 sglrReferenceContext.Texture2DArray.prototype.clearLevels = function() { this.m_levels.clear(); }; 638 639 /** 640 * @param {number} level 641 * @return {boolean} 642 */ 643 sglrReferenceContext.Texture2DArray.prototype.hasLevel = function(level) { return this.m_levels.hasLevel(level); }; 644 645 /** 646 * @param {number} level 647 * @return {tcuTexture.PixelBufferAccess} 648 */ 649 sglrReferenceContext.Texture2DArray.prototype.getLevel = function(level) { return this.m_levels.getLevel(level); }; 650 651 /** 652 * @param {number} level 653 * @param {?tcuTexture.TextureFormat} format 654 * @param {number} width 655 * @param {number} height 656 * @param {number} numLayers 657 */ 658 sglrReferenceContext.Texture2DArray.prototype.allocLevel = function(level, format, width, height, numLayers) { 659 this.m_levels.allocLevel(level, format, width, height, numLayers); 660 }; 661 662 /** 663 * @return {boolean} 664 */ 665 sglrReferenceContext.Texture2DArray.prototype.isComplete = function() { 666 /** @type {number} */ var baseLevel = this.getBaseLevel(); 667 668 if (this.hasLevel(baseLevel)) { 669 /** @type {tcuTexture.PixelBufferAccess} */ var level0 = this.getLevel(baseLevel); 670 /** @type {boolean} */ var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 671 672 if (mipmap) { 673 /** @type {tcuTexture.TextureFormat} */ var format = level0.getFormat(); 674 /** @type {number} */ var w = level0.getWidth(); 675 /** @type {number} */ var h = level0.getHeight(); 676 /** @type {number} */ var numLayers = level0.getDepth(); 677 /** @type {number} */ var numLevels = Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(w, h)); 678 679 for (var levelNdx = 1; levelNdx < numLevels; levelNdx++) { 680 if (this.hasLevel(baseLevel + levelNdx)) { 681 /** @type {tcuTexture.PixelBufferAccess} */ var level = this.getLevel(baseLevel + levelNdx); 682 /** @type {number} */ var expectedW = sglrReferenceContext.getMipLevelSize(w, levelNdx); 683 /** @type {number} */ var expectedH = sglrReferenceContext.getMipLevelSize(h, levelNdx); 684 685 if (level.getWidth() != expectedW || 686 level.getHeight() != expectedH || 687 level.getDepth() != numLayers || 688 !level.getFormat().isEqual(format)) 689 return false; 690 } else 691 return false; 692 } 693 } 694 695 return true; 696 } else 697 return false; 698 }; 699 700 /** 701 */ 702 sglrReferenceContext.Texture2DArray.prototype.updateView = function() { 703 /** @type {number} */ var baseLevel = this.getBaseLevel(); 704 705 if (this.hasLevel(baseLevel) && !this.getLevel(baseLevel).isEmpty()) { 706 // Update number of levels in mipmap pyramid. 707 /** @type {number} */ var width = this.getLevel(baseLevel).getWidth(); 708 /** @type {number} */ var height = this.getLevel(baseLevel).getHeight(); 709 /** @type {boolean} */ var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 710 /** @type {number} */ var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1; 711 712 this.m_view = new tcuTexture.Texture2DArrayView(numLevels, this.m_levels.getLevels().slice(baseLevel)); 713 } else 714 this.m_view = new tcuTexture.Texture2DArrayView(0, null); 715 }; 716 717 /** 718 * @param {Array<number>} pos 719 * @param {number=} lod 720 * @return {Array<number>} 721 */ 722 sglrReferenceContext.Texture2DArray.prototype.sample = function(pos, lod) { 723 return this.m_view.sample(this.getSampler(), pos, lod); 724 }; 725 726 /** 727 * @constructor 728 * @extends {sglrReferenceContext.Texture} 729 */ 730 sglrReferenceContext.Texture3D = function() { 731 sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_2D_ARRAY); 732 /** @type {tcuTexture.Texture3DView} */ this.m_view = new tcuTexture.Texture3DView(0, null); 733 /** @type {sglrReferenceContext.TextureLevelArray} */ this.m_levels = new sglrReferenceContext.TextureLevelArray(); 734 }; 735 736 /** 737 */ 738 sglrReferenceContext.Texture3D.prototype = Object.create(sglrReferenceContext.Texture.prototype); 739 sglrReferenceContext.Texture3D.prototype.constructor = sglrReferenceContext.Texture3D; 740 741 sglrReferenceContext.Texture3D.prototype.clearLevels = function() { this.m_levels.clear(); }; 742 743 /** 744 * @param {number} level 745 * @return {boolean} 746 */ 747 sglrReferenceContext.Texture3D.prototype.hasLevel = function(level) { return this.m_levels.hasLevel(level); }; 748 749 /** 750 * @param {number} level 751 * @return {tcuTexture.PixelBufferAccess} 752 */ 753 sglrReferenceContext.Texture3D.prototype.getLevel = function(level) { return this.m_levels.getLevel(level); }; 754 755 /** 756 * @param {number} level 757 * @param {?tcuTexture.TextureFormat} format 758 * @param {number} width 759 * @param {number} height 760 * @param {number} depth 761 */ 762 sglrReferenceContext.Texture3D.prototype.allocLevel = function(level, format, width, height, depth) { 763 this.m_levels.allocLevel(level, format, width, height, depth); 764 }; 765 766 /** 767 * @return {boolean} 768 */ 769 sglrReferenceContext.Texture3D.prototype.isComplete = function() { 770 /** @type {number} */ var baseLevel = this.getBaseLevel(); 771 772 if (this.hasLevel(baseLevel)) { 773 /** @type {tcuTexture.PixelBufferAccess} */ var level0 = this.getLevel(baseLevel); 774 /** @type {boolean} */ var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 775 776 if (mipmap) { 777 /** @type {tcuTexture.TextureFormat} */ var format = level0.getFormat(); 778 /** @type {number} */ var w = level0.getWidth(); 779 /** @type {number} */ var h = level0.getHeight(); 780 /** @type {number} */ var d = level0.getDepth(); 781 /** @type {number} */ var numLevels = Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels3D(w, h, d)); 782 783 for (var levelNdx = 1; levelNdx < numLevels; levelNdx++) { 784 if (this.hasLevel(baseLevel + levelNdx)) { 785 /** @type {tcuTexture.PixelBufferAccess} */ var level = this.getLevel(baseLevel + levelNdx); 786 /** @type {number} */ var expectedW = sglrReferenceContext.getMipLevelSize(w, levelNdx); 787 /** @type {number} */ var expectedH = sglrReferenceContext.getMipLevelSize(h, levelNdx); 788 /** @type {number} */ var expectedD = sglrReferenceContext.getMipLevelSize(d, levelNdx); 789 790 if (level.getWidth() != expectedW || 791 level.getHeight() != expectedH || 792 level.getDepth() != expectedD || 793 !level.getFormat().isEqual(format)) 794 return false; 795 } else 796 return false; 797 } 798 } 799 800 return true; 801 } else 802 return false; 803 }; 804 805 /** 806 */ 807 sglrReferenceContext.Texture3D.prototype.updateView = function() { 808 /** @type {number} */ var baseLevel = this.getBaseLevel(); 809 810 if (this.hasLevel(baseLevel) && !this.getLevel(baseLevel).isEmpty()) { 811 // Update number of levels in mipmap pyramid. 812 /** @type {number} */ var width = this.getLevel(baseLevel).getWidth(); 813 /** @type {number} */ var height = this.getLevel(baseLevel).getHeight(); 814 /** @type {boolean} */ var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter); 815 /** @type {number} */ var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1; 816 817 this.m_view = new tcuTexture.Texture3DView(numLevels, this.m_levels.getLevels().slice(baseLevel)); 818 } else 819 this.m_view = new tcuTexture.Texture3DView(0, null); 820 }; 821 822 /** 823 * @param {Array<number>} pos 824 * @param {number=} lod 825 * @return {Array<number>} 826 */ 827 sglrReferenceContext.Texture3D.prototype.sample = function(pos, lod) { return this.m_view.sample(this.getSampler(), pos, lod) }; 828 829 /** 830 * A container object for storing one of texture types; 831 * @constructor 832 */ 833 sglrReferenceContext.TextureContainer = function() { 834 /** @type {sglrReferenceContext.Texture2D | sglrReferenceContext.TextureCube|sglrReferenceContext.Texture2DArray|sglrReferenceContext.Texture3D} */ 835 this.texture = null; 836 /** @type {?sglrReferenceContext.TextureType} */ this.textureType = null; 837 }; 838 839 /** 840 * @return {?sglrReferenceContext.TextureType} 841 */ 842 sglrReferenceContext.TextureContainer.prototype.getType = function() { return this.textureType; }; 843 844 /** 845 * @param {number} target 846 * @throws {Error} 847 */ 848 sglrReferenceContext.TextureContainer.prototype.init = function(target) { 849 switch (target) { 850 case gl.TEXTURE_2D: 851 this.texture = new sglrReferenceContext.Texture2D(); 852 this.textureType = sglrReferenceContext.TextureType.TYPE_2D; 853 break; 854 case gl.TEXTURE_CUBE_MAP: 855 this.texture = new sglrReferenceContext.TextureCube(); 856 this.textureType = sglrReferenceContext.TextureType.TYPE_CUBE_MAP; 857 break; 858 case gl.TEXTURE_2D_ARRAY: 859 this.texture = new sglrReferenceContext.Texture2DArray(); 860 this.textureType = sglrReferenceContext.TextureType.TYPE_2D_ARRAY; 861 break; 862 case gl.TEXTURE_3D: 863 this.texture = new sglrReferenceContext.Texture3D(); 864 this.textureType = sglrReferenceContext.TextureType.TYPE_3D; 865 break; 866 /* TODO: Implement other types */ 867 // case gl.TEXTURE_CUBE_MAP_ARRAY: 868 // this.textureType = sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY; 869 // break; 870 default: throw new Error('Unrecognized target: ' + target); 871 } 872 }; 873 874 /** 875 * @enum 876 */ 877 sglrReferenceContext.AttachmentPoint = { 878 ATTACHMENTPOINT_COLOR0: 0, 879 ATTACHMENTPOINT_DEPTH: 1, 880 ATTACHMENTPOINT_STENCIL: 2 881 }; 882 883 /** 884 * @param {number} attachment 885 * @return {sglrReferenceContext.AttachmentPoint} 886 * @throws {Error} 887 */ 888 sglrReferenceContext.mapGLAttachmentPoint = function(attachment) { 889 switch (attachment) { 890 case gl.COLOR_ATTACHMENT0: return sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0; 891 case gl.DEPTH_ATTACHMENT: return sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH; 892 case gl.STENCIL_ATTACHMENT: return sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL; 893 default: throw new Error('Wrong attachment point:' + attachment); 894 } 895 }; 896 897 /** 898 * @enum 899 */ 900 sglrReferenceContext.AttachmentType = { 901 ATTACHMENTTYPE_RENDERBUFFER: 0, 902 ATTACHMENTTYPE_TEXTURE: 1 903 }; 904 905 /** 906 * @enum 907 */ 908 sglrReferenceContext.TexTarget = { 909 TEXTARGET_2D: 0, 910 TEXTARGET_CUBE_MAP_POSITIVE_X: 1, 911 TEXTARGET_CUBE_MAP_POSITIVE_Y: 2, 912 TEXTARGET_CUBE_MAP_POSITIVE_Z: 3, 913 TEXTARGET_CUBE_MAP_NEGATIVE_X: 4, 914 TEXTARGET_CUBE_MAP_NEGATIVE_Y: 5, 915 TEXTARGET_CUBE_MAP_NEGATIVE_Z: 6, 916 TEXTARGET_2D_ARRAY: 7, 917 TEXTARGET_3D: 8, 918 TEXTARGET_CUBE_MAP_ARRAY: 9 919 }; 920 921 /** 922 * @param {?sglrReferenceContext.TexTarget} target 923 * @return {tcuTexture.CubeFace} 924 */ 925 sglrReferenceContext.texTargetToFace = function(target) { 926 switch (target) { 927 case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_X: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X; 928 case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_X; 929 case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Y: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y; 930 case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Y: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y; 931 case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z; 932 case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Z: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z; 933 default: throw new Error('Invalid target ' + target); 934 } 935 }; 936 937 /** 938 * @param {sglrReferenceContext.TexTarget} target 939 * @return {sglrReferenceContext.TexTarget} 940 * @throws {Error} 941 */ 942 sglrReferenceContext.mapGLFboTexTarget = function(target) { 943 switch (target) { 944 case gl.TEXTURE_2D: return sglrReferenceContext.TexTarget.TEXTARGET_2D; 945 case gl.TEXTURE_CUBE_MAP_POSITIVE_X: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X; 946 case gl.TEXTURE_CUBE_MAP_POSITIVE_Y: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Y; 947 case gl.TEXTURE_CUBE_MAP_POSITIVE_Z: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Z; 948 case gl.TEXTURE_CUBE_MAP_NEGATIVE_X: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_X; 949 case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Y; 950 case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z; 951 default: throw new Error('Wrong texture target:' + target); 952 } 953 }; 954 955 /** 956 * @constructor 957 */ 958 sglrReferenceContext.Attachment = function() { 959 /** @type {?sglrReferenceContext.AttachmentType} */ this.type = null; 960 /** @type {sglrReferenceContext.TextureContainer|sglrReferenceContext.Renderbuffer} */ this.object = null; // TODO: fix reserved word 961 /** @type {?sglrReferenceContext.TexTarget} */ this.texTarget = null; 962 /** @type {number} */ this.level = 0; 963 /** @type {number} */ this.layer = 0; 964 }; 965 966 /** 967 * @constructor 968 */ 969 sglrReferenceContext.Framebuffer = function() { 970 /** @type {Array<sglrReferenceContext.Attachment>} */ this.m_attachments = []; 971 for (var key in sglrReferenceContext.AttachmentPoint) 972 this.m_attachments[sglrReferenceContext.AttachmentPoint[key]] = new sglrReferenceContext.Attachment(); 973 }; 974 975 /** 976 * @param {sglrReferenceContext.AttachmentPoint} point 977 * @return {sglrReferenceContext.Attachment} 978 */ 979 sglrReferenceContext.Framebuffer.prototype.getAttachment = function(point) { return this.m_attachments[point]; }; 980 981 /** 982 * @param {sglrReferenceContext.AttachmentPoint} point 983 * @param {sglrReferenceContext.Attachment} attachment 984 */ 985 sglrReferenceContext.Framebuffer.prototype.setAttachment = function(point, attachment) { this.m_attachments[point] = attachment; }; 986 987 // /** 988 // * @enum 989 // */ 990 // var Format = { 991 // FORMAT_DEPTH_COMPONENT16: 0, 992 // FORMAT_RGBA4: 1, 993 // FORMAT_RGB5_A1: 2, 994 // FORMAT_RGB565: 3, 995 // FORMAT_STENCIL_INDEX8: 4 996 // }; 997 998 /** 999 * @constructor 1000 */ 1001 sglrReferenceContext.Renderbuffer = function() { 1002 /** @type {tcuTexture.TextureLevel} */ this.m_data; 1003 }; 1004 1005 /** 1006 * @param {tcuTexture.TextureFormat} format 1007 * @param {number} width 1008 * @param {number} height 1009 */ 1010 sglrReferenceContext.Renderbuffer.prototype.setStorage = function(format, width, height) { 1011 this.m_data = new tcuTexture.TextureLevel(format, width, height); 1012 }; 1013 1014 /** 1015 * @return {number} 1016 */ 1017 sglrReferenceContext.Renderbuffer.prototype.getWidth = function() { return this.m_data.getWidth(); }; 1018 1019 /** 1020 * @return {number} 1021 */ 1022 sglrReferenceContext.Renderbuffer.prototype.getHeight = function() { return this.m_data.getHeight(); }; 1023 1024 /** 1025 * @return {?tcuTexture.TextureFormat} 1026 */ 1027 sglrReferenceContext.Renderbuffer.prototype.getFormat = function() { return this.m_data.getFormat(); }; 1028 1029 /** 1030 * @return {tcuTexture.PixelBufferAccess} 1031 */ 1032 sglrReferenceContext.Renderbuffer.prototype.getAccess = function() { return this.m_data.getAccess(); }; 1033 1034 /** 1035 * @constructor 1036 * @param {number} maxVertexAttribs 1037 */ 1038 sglrReferenceContext.VertexArray = function(maxVertexAttribs) { 1039 /** @type {sglrReferenceContext.DataBuffer} */ this.m_elementArrayBufferBinding = null; 1040 1041 /** @type {Array<sglrReferenceContext.VertexArray.VertexAttribArray>} */this.m_arrays = []; 1042 for (var i = 0; i < maxVertexAttribs; i++) 1043 this.m_arrays.push(new sglrReferenceContext.VertexArray.VertexAttribArray()); 1044 }; 1045 1046 /** @constructor */ 1047 sglrReferenceContext.VertexArray.VertexAttribArray = function() { 1048 this.enabled = false; 1049 this.size = 4; 1050 this.stride = 0; 1051 this.type = gl.FLOAT; 1052 1053 this.normalized = false; 1054 this.integer = false; 1055 this.divisor = 0; 1056 this.offset = 0; 1057 this.bufferBinding = null; 1058 }; 1059 1060 /** 1061 * @constructor 1062 */ 1063 sglrReferenceContext.DataBuffer = function() { 1064 /** @type {?ArrayBuffer} */ this.m_data = null; 1065 }; 1066 1067 /** 1068 * @param {number} size 1069 */ 1070 sglrReferenceContext.DataBuffer.prototype.setStorage = function(size) {this.m_data = new ArrayBuffer(size); }; 1071 1072 /** 1073 * @return {number} 1074 */ 1075 sglrReferenceContext.DataBuffer.prototype.getSize = function() { 1076 /** @type {number} */ var size = 0; 1077 if (this.m_data) 1078 size = this.m_data.byteLength; 1079 return size; 1080 }; 1081 1082 /** 1083 * @return {?ArrayBuffer} 1084 */ 1085 sglrReferenceContext.DataBuffer.prototype.getData = function() { return this.m_data; }; 1086 1087 /** 1088 * @param {ArrayBuffer|goog.NumberArray} data 1089 */ 1090 sglrReferenceContext.DataBuffer.prototype.setData = function(data) { 1091 /** @type {ArrayBuffer} */ var buffer; 1092 /** @type {number} */ var offset = 0; 1093 /** @type {number} */ var byteLength = data.byteLength; 1094 if (data instanceof ArrayBuffer) 1095 buffer = data; 1096 else { 1097 buffer = data.buffer; 1098 offset = data.byteOffset; 1099 } 1100 1101 if (!buffer) 1102 throw new Error('Invalid buffer'); 1103 1104 this.m_data = buffer.slice(offset, offset + byteLength); 1105 }; 1106 1107 /** 1108 * @param {number} offset 1109 * @param {goog.NumberArray} data 1110 */ 1111 sglrReferenceContext.DataBuffer.prototype.setSubData = function(offset, data) { 1112 /** @type {ArrayBuffer} */ var buffer; 1113 /** @type {number} */ var srcOffset = 0; 1114 /** @type {number} */ var byteLength = data.byteLength; 1115 if (data instanceof ArrayBuffer) 1116 buffer = data; 1117 else { 1118 buffer = data.buffer; 1119 srcOffset = data.byteOffset; 1120 } 1121 1122 if (!buffer) 1123 throw new Error('Invalid buffer'); 1124 1125 /** @type {goog.NumberArray} */ var src = new Uint8Array(buffer, srcOffset, byteLength); 1126 /** @type {goog.NumberArray} */ var dst = new Uint8Array(this.m_data, offset, byteLength); 1127 dst.set(src); 1128 }; 1129 1130 // /** 1131 // * @constructor 1132 // */ 1133 // var ObjectManager = function() { 1134 // this.m_objects = {}; 1135 // }; 1136 1137 // ObjectManager.prototype.insert = function(obj) { 1138 // var name = obj.getName(); 1139 // if (!name) 1140 // throw new Error("Cannot insert unnamed object"); 1141 // this.m_objects[name] = obj; 1142 // }; 1143 1144 // ObjectManager.prototype.find = function(name) { return this.m_objects[name]; }; 1145 1146 // ObjectManager.prototype.acquireReference = function(obj) { 1147 // if (this.find(obj.getName()) !== obj) 1148 // throw new Error("Object is not in the object manager"); 1149 // obj.incRefCount(); 1150 // }; 1151 1152 // ObjectManager.prototype.releaseReference = function(obj) { 1153 // if (this.find(obj.getName()) !== obj) 1154 // throw new Error("Object is not in the object manager"); 1155 1156 // obj.decRefCount(); 1157 1158 // if (obj.getRefCount() == 0) 1159 // delete this.m_objects[obj.getName()]; 1160 // }; 1161 1162 // ObjectManager.prototype.getAll = function() { return this.m_objects; }; 1163 1164 /** 1165 * @constructor 1166 */ 1167 sglrReferenceContext.TextureUnit = function() { 1168 /** @type {?sglrReferenceContext.TextureContainer} */ this.tex2DBinding = null; 1169 /** @type {?sglrReferenceContext.TextureContainer} */ this.texCubeBinding = null; 1170 /** @type {?sglrReferenceContext.TextureContainer} */ this.tex2DArrayBinding = null; 1171 /** @type {?sglrReferenceContext.TextureContainer} */ this.tex3DBinding = null; 1172 /** @type {?sglrReferenceContext.TextureContainer} */ this.texCubeArrayBinding = null; 1173 }; 1174 1175 /** 1176 * @constructor 1177 */ 1178 sglrReferenceContext.StencilState = function() { 1179 /** @type {number} */ this.func = gl.ALWAYS; 1180 /** @type {number} */ this.ref = 0; 1181 /** @type {number} */ this.opMask = ~0; 1182 /** @type {number} */ this.opStencilFail = gl.KEEP; 1183 /** @type {number} */ this.opDepthFail = gl.KEEP; 1184 /** @type {number} */ this.opDepthPass = gl.KEEP; 1185 /** @type {number} */ this.writeMask = ~0; 1186 }; 1187 1188 /** 1189 * @param {tcuPixelFormat.PixelFormat} pixelFmt 1190 * @return {tcuTexture.TextureFormat} 1191 * @throws {Error} 1192 */ 1193 sglrReferenceContext.toTextureFormat = function(pixelFmt) { 1194 if (pixelFmt.equals(8, 8, 8, 8)) 1195 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8); 1196 else if (pixelFmt.equals(8, 8, 8, 0)) 1197 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8); 1198 else if (pixelFmt.equals(4, 4, 4, 4)) 1199 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_4444); 1200 else if (pixelFmt.equals(5, 5, 5, 1)) 1201 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_5551); 1202 else if (pixelFmt.equals(5, 6, 5, 0)) 1203 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_SHORT_565); 1204 1205 throw new Error('Could not map pixel format:' + pixelFmt); 1206 }; 1207 1208 /** 1209 * @param {number} depthBits 1210 * @return {tcuTexture.TextureFormat} 1211 * @throws {Error} 1212 */ 1213 sglrReferenceContext.getDepthFormat = function(depthBits) { 1214 switch (depthBits) { 1215 case 8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNORM_INT8); 1216 case 16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNORM_INT16); 1217 case 24: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNSIGNED_INT_24_8); 1218 case 32: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.FLOAT); 1219 default: 1220 throw new Error("Can't map depth buffer format, bits: " + depthBits); 1221 } 1222 }; 1223 1224 /** 1225 * @param {number} stencilBits 1226 * @return {tcuTexture.TextureFormat} 1227 * @throws {Error} 1228 */ 1229 sglrReferenceContext.getStencilFormat = function(stencilBits) { 1230 switch (stencilBits) { 1231 case 8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT8); 1232 case 16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT16); 1233 case 24: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT_24_8); 1234 case 32: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT32); 1235 default: 1236 throw new Error("Can't map stencil buffer format, bits: " + stencilBits); 1237 } 1238 }; 1239 1240 /** 1241 * @constructor 1242 * @param {tcuPixelFormat.PixelFormat} colorBits 1243 * @param {number} depthBits 1244 * @param {number} stencilBits 1245 * @param {number} width 1246 * @param {number} height 1247 * @param {number=} samples_ 1248 */ 1249 sglrReferenceContext.ReferenceContextBuffers = function(colorBits, depthBits, stencilBits, width, height, samples_) { 1250 if (samples_ === undefined) 1251 samples_ = 1; 1252 1253 /** @type {number} */ var samples = samples_; 1254 /** @type {tcuTexture.TextureLevel} */ this.m_colorbuffer = new tcuTexture.TextureLevel(sglrReferenceContext.toTextureFormat(colorBits), samples, width, height); 1255 1256 if (depthBits > 0) 1257 /** @type {tcuTexture.TextureLevel} */ this.m_depthbuffer = new tcuTexture.TextureLevel(sglrReferenceContext.getDepthFormat(depthBits), samples, width, height); 1258 1259 if (stencilBits > 0) 1260 /** @type {tcuTexture.TextureLevel} */ this.m_stencilbuffer = new tcuTexture.TextureLevel(sglrReferenceContext.getStencilFormat(stencilBits), samples, width, height); 1261 }; 1262 1263 /** 1264 * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 1265 */ 1266 sglrReferenceContext.ReferenceContextBuffers.prototype.getColorbuffer = function() { return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromMultisampleAccess(this.m_colorbuffer.getAccess()); }; 1267 1268 /** 1269 * @return {?rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 1270 */ 1271 sglrReferenceContext.ReferenceContextBuffers.prototype.getDepthbuffer = function() { return this.m_depthbuffer !== undefined ? rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromMultisampleAccess(this.m_depthbuffer.getAccess()) : null; }; 1272 1273 /** 1274 * @return {?rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 1275 */ 1276 sglrReferenceContext.ReferenceContextBuffers.prototype.getStencilbuffer = function() { return this.m_stencilbuffer !== undefined ? rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromMultisampleAccess(this.m_stencilbuffer.getAccess()) : null; }; 1277 1278 /** 1279 * @param {sglrReferenceContext.ReferenceContextLimits} limits 1280 * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} colorbuffer 1281 * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} depthbuffer 1282 * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} stencilbuffer 1283 * @constructor 1284 */ 1285 sglrReferenceContext.ReferenceContext = function(limits, colorbuffer, depthbuffer, stencilbuffer) { 1286 /** @type {sglrReferenceContext.ReferenceContextLimits} */ this.m_limits = limits; 1287 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ this.m_defaultColorbuffer = colorbuffer; 1288 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ this.m_defaultDepthbuffer = depthbuffer; 1289 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ this.m_defaultStencilbuffer = stencilbuffer; 1290 /** @type {Array<number>} */ this.m_viewport = [0, 0, colorbuffer.raw().getHeight(), colorbuffer.raw().getDepth()]; 1291 /** @type {Array<sglrReferenceContext.TextureUnit>} */ this.m_textureUnits = []; 1292 for (var i = 0; i < this.m_limits.maxTextureImageUnits; i++) 1293 this.m_textureUnits.push(new sglrReferenceContext.TextureUnit()); 1294 /** @type {number} */ this.m_activeTexture = 0; 1295 /** @type {number} */ this.m_lastError = gl.NO_ERROR; 1296 // this.m_textures = new ObjectManager(); 1297 /** @type {number} */ this.m_pixelUnpackRowLength = 0; 1298 /** @type {number} */ this.m_pixelUnpackSkipRows = 0; 1299 /** @type {number} */ this.m_pixelUnpackSkipPixels = 0; 1300 /** @type {number} */ this.m_pixelUnpackImageHeight = 0; 1301 /** @type {number} */ this.m_pixelUnpackSkipImages = 0; 1302 /** @type {number} */ this.m_pixelUnpackAlignment = 4; 1303 /** @type {number} */ this.m_pixelPackAlignment = 4; 1304 /** @type {Array<number>} */ this.m_clearColor = [0, 0, 0, 0]; 1305 /** @type {number} */ this.m_clearDepth = 1; 1306 /** @type {number} */ this.m_clearStencil = 0; 1307 /** @type {Array<number>} */ this.m_scissorBox = this.m_viewport; 1308 /** @type {boolean} */ this.m_blendEnabled = false; 1309 /** @type {boolean} */ this.m_scissorEnabled = false; 1310 /** @type {boolean} */ this.m_depthTestEnabled = false; 1311 /** @type {boolean} */ this.m_stencilTestEnabled = false; 1312 /** @type {boolean} */ this.m_polygonOffsetFillEnabled = false; 1313 /** @type {boolean} */ this.m_primitiveRestartFixedIndex = true; //always on 1314 /** @type {boolean} */ this.m_primitiveRestartSettableIndex = true; //always on 1315 /** @type {Array<sglrReferenceContext.StencilState>} */ this.m_stencil = []; 1316 for (var type in rrDefs.FaceType) 1317 this.m_stencil[rrDefs.FaceType[type]] = new sglrReferenceContext.StencilState(); 1318 /** @type {number} */ this.m_depthFunc = gl.LESS; 1319 /** @type {number} */ this.m_depthRangeNear = 0; 1320 /** @type {number} */ this.m_depthRangeFar = 1; 1321 /** @type {number} */ this.m_polygonOffsetFactor = 0; 1322 /** @type {number} */ this.m_polygonOffsetUnits = 0; 1323 /** @type {number} */ this.m_blendModeRGB = gl.FUNC_ADD; 1324 /** @type {number} */ this.m_blendModeAlpha = gl.FUNC_ADD; 1325 /** @type {number} */ this.m_blendFactorSrcRGB = gl.ONE; 1326 /** @type {number} */ this.m_blendFactorDstRGB = gl.ZERO; 1327 /** @type {number} */ this.m_blendFactorSrcAlpha = gl.ONE; 1328 /** @type {number} */ this.m_blendFactorDstAlpha = gl.ZERO; 1329 /** @type {Array<number>} */ this.m_blendColor = [0, 0, 0, 0]; 1330 /** @type {boolean} */ this.m_sRGBUpdateEnabled = true; 1331 /** @type {Array<boolean>} */ this.m_colorMask = [true, true, true, true]; 1332 /** @type {boolean} */ this.m_depthMask = true; 1333 /** @type {sglrReferenceContext.VertexArray} */ this.m_defaultVAO = new sglrReferenceContext.VertexArray(this.m_limits.maxVertexAttribs); 1334 /** @type {sglrReferenceContext.VertexArray} */ this.m_vertexArrayBinding = this.m_defaultVAO; 1335 /** @type {sglrReferenceContext.DataBuffer} */ this.m_arrayBufferBinding = null; 1336 /** @type {sglrReferenceContext.DataBuffer} */ this.m_copyReadBufferBinding = null; 1337 /** @type {sglrReferenceContext.DataBuffer} */ this.m_copyWriteBufferBinding = null; 1338 /** @type {sglrReferenceContext.DataBuffer} */ this.m_drawIndirectBufferBinding = null; 1339 /** @type {sglrReferenceContext.DataBuffer} */ this.m_pixelPackBufferBinding = null; 1340 /** @type {sglrReferenceContext.DataBuffer} */ this.m_pixelUnpackBufferBinding = null; 1341 /** @type {sglrReferenceContext.DataBuffer} */ this.m_transformFeedbackBufferBinding = null; 1342 /** @type {sglrReferenceContext.DataBuffer} */ this.m_uniformBufferBinding = null; 1343 /** @type {sglrReferenceContext.Framebuffer} */ this.m_readFramebufferBinding = null; 1344 /** @type {sglrReferenceContext.Framebuffer} */ this.m_drawFramebufferBinding = null; 1345 /** @type {sglrReferenceContext.Renderbuffer} */ this.m_renderbufferBinding = null; 1346 /** @type {sglrShaderProgram.ShaderProgram} */ this.m_currentProgram = null; 1347 /** @type {Array<rrGenericVector.GenericVec4>} */ this.m_currentAttribs = []; 1348 for (var i = 0; i < this.m_limits.maxVertexAttribs; i++) 1349 this.m_currentAttribs.push(new rrGenericVector.GenericVec4()); 1350 /** @type {number} */ this.m_lineWidth = 1; 1351 1352 /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTex2D = new sglrReferenceContext.TextureContainer(); 1353 this.m_emptyTex2D.init(gl.TEXTURE_2D); 1354 this.m_emptyTex2D.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1355 this.m_emptyTex2D.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1356 this.m_emptyTex2D.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST; 1357 this.m_emptyTex2D.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST; 1358 this.m_emptyTex2D.texture.allocLevel(0, new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1); 1359 this.m_emptyTex2D.texture.getLevel(0).setPixel([0, 0, 0, 1], 0, 0); 1360 this.m_emptyTex2D.texture.updateView(); 1361 1362 /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTexCube = new sglrReferenceContext.TextureContainer(); 1363 this.m_emptyTexCube.init(gl.TEXTURE_CUBE_MAP); 1364 this.m_emptyTexCube.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1365 this.m_emptyTexCube.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1366 this.m_emptyTexCube.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST; 1367 this.m_emptyTexCube.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST; 1368 1369 for (var face in tcuTexture.CubeFace) { 1370 this.m_emptyTexCube.texture.allocLevel(0, tcuTexture.CubeFace[face], 1371 new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1); 1372 this.m_emptyTexCube.texture.getFace(0, tcuTexture.CubeFace[face]).setPixel([0, 0, 0, 1], 0, 0); 1373 } 1374 this.m_emptyTexCube.texture.updateView(); 1375 1376 /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTex2DArray = new sglrReferenceContext.TextureContainer(); 1377 this.m_emptyTex2DArray.init(gl.TEXTURE_2D_ARRAY); 1378 this.m_emptyTex2DArray.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1379 this.m_emptyTex2DArray.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1380 this.m_emptyTex2DArray.texture.getSampler().wrapR = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1381 this.m_emptyTex2DArray.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST; 1382 this.m_emptyTex2DArray.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST; 1383 this.m_emptyTex2DArray.texture.allocLevel(0, new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1); 1384 this.m_emptyTex2DArray.texture.getLevel(0).setPixel([0, 0, 0, 1], 0, 0); 1385 this.m_emptyTex2DArray.texture.updateView(); 1386 1387 /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTex3D = new sglrReferenceContext.TextureContainer(); 1388 this.m_emptyTex3D.init(gl.TEXTURE_3D); 1389 this.m_emptyTex3D.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1390 this.m_emptyTex3D.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1391 this.m_emptyTex3D.texture.getSampler().wrapR = tcuTexture.WrapMode.CLAMP_TO_EDGE; 1392 this.m_emptyTex3D.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST; 1393 this.m_emptyTex3D.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST; 1394 this.m_emptyTex3D.texture.allocLevel(0, new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1); 1395 this.m_emptyTex3D.texture.getLevel(0).setPixel([0, 0, 0, 1], 0, 0); 1396 this.m_emptyTex3D.texture.updateView(); 1397 1398 /** @type {sglrReferenceContext.TextureType} */ this.m_type; 1399 1400 /** @type {boolean} */ this.m_immutable; 1401 1402 /** @type {tcuTexture.Sampler} */ this.m_sampler; 1403 /** @type {number} */ this.m_baseLevel; 1404 /** @type {number} */ this.m_maxLevel; 1405 }; 1406 1407 /** 1408 * @return {number} 1409 */ 1410 sglrReferenceContext.ReferenceContext.prototype.getWidth = function() { return this.m_defaultColorbuffer.raw().getHeight(); }; 1411 1412 /** 1413 * @return {number} 1414 */ 1415 sglrReferenceContext.ReferenceContext.prototype.getHeight = function() { return this.m_defaultColorbuffer.raw().getDepth(); }; 1416 1417 /** 1418 * @param {number} x 1419 * @param {number} y 1420 * @param {number} width 1421 * @param {number} height 1422 */ 1423 sglrReferenceContext.ReferenceContext.prototype.viewport = function(x, y, width, height) { this.m_viewport = [x, y, width, height]; }; 1424 1425 /** 1426 * @param {number} texture 1427 */ 1428 sglrReferenceContext.ReferenceContext.prototype.activeTexture = function(texture) { 1429 if (deMath.deInBounds32(texture, gl.TEXTURE0, gl.TEXTURE0 + this.m_textureUnits.length)) 1430 this.m_activeTexture = texture - gl.TEXTURE0; 1431 else 1432 this.setError(gl.INVALID_ENUM); 1433 }; 1434 1435 /** 1436 * @param {number} error 1437 */ 1438 sglrReferenceContext.ReferenceContext.prototype.setError = function(error) { 1439 if (this.m_lastError == gl.NO_ERROR) 1440 this.m_lastError = error; 1441 }; 1442 1443 /** 1444 * @return {number} error 1445 */ 1446 sglrReferenceContext.ReferenceContext.prototype.getError = function() { 1447 /** @type {number} */ var err = this.m_lastError; 1448 this.m_lastError = gl.NO_ERROR; 1449 return err; 1450 }; 1451 1452 /** 1453 * @param {boolean} condition 1454 * @param {number} error 1455 */ 1456 sglrReferenceContext.ReferenceContext.prototype.conditionalSetError = function(condition, error) { 1457 if (condition) 1458 this.setError(error); 1459 return condition; 1460 }; 1461 1462 /** 1463 * @param {number} target 1464 * @param {sglrReferenceContext.TextureContainer} texture 1465 * @throws {Error} 1466 */ 1467 sglrReferenceContext.ReferenceContext.prototype.bindTexture = function(target, texture) { 1468 /** @type {number} */ var unitNdx = this.m_activeTexture; 1469 1470 if (this.conditionalSetError((target != gl.TEXTURE_2D && 1471 target != gl.TEXTURE_CUBE_MAP && 1472 target != gl.TEXTURE_2D_ARRAY && 1473 target != gl.TEXTURE_3D), // && 1474 // target != gl.TEXTURE_CUBE_MAP_ARRAY), 1475 gl.INVALID_ENUM)) 1476 return; 1477 1478 if (!texture) { 1479 // Clear binding. 1480 switch (target) { 1481 case gl.TEXTURE_2D: this.setTex2DBinding(unitNdx, null); break; 1482 case gl.TEXTURE_CUBE_MAP: this.setTexCubeBinding(unitNdx, null); break; 1483 case gl.TEXTURE_2D_ARRAY: this.setTex2DArrayBinding(unitNdx, null); break; 1484 case gl.TEXTURE_3D: this.setTex3DBinding(unitNdx, null); break; 1485 default: 1486 throw new Error('Unrecognized target: ' + target); 1487 } 1488 } else { 1489 if (texture.textureType == null) { 1490 texture.init(target); 1491 } else { 1492 // Validate type. 1493 /** @type {sglrReferenceContext.TextureType} */ var expectedType; 1494 switch (target) { 1495 case gl.TEXTURE_2D: expectedType = sglrReferenceContext.TextureType.TYPE_2D; break; 1496 case gl.TEXTURE_CUBE_MAP: expectedType = sglrReferenceContext.TextureType.TYPE_CUBE_MAP; break; 1497 case gl.TEXTURE_2D_ARRAY: expectedType = sglrReferenceContext.TextureType.TYPE_2D_ARRAY; break; 1498 case gl.TEXTURE_3D: expectedType = sglrReferenceContext.TextureType.TYPE_3D; break; 1499 default: throw new Error('Unrecognized target: ' + target); 1500 } 1501 if (this.conditionalSetError((texture.textureType != expectedType), gl.INVALID_OPERATION)) 1502 return; 1503 } 1504 switch (target) { 1505 case gl.TEXTURE_2D: this.setTex2DBinding(unitNdx, texture); break; 1506 case gl.TEXTURE_CUBE_MAP: this.setTexCubeBinding(unitNdx, texture); break; 1507 case gl.TEXTURE_2D_ARRAY: this.setTex2DArrayBinding(unitNdx, texture); break; 1508 case gl.TEXTURE_3D: this.setTex3DBinding(unitNdx, texture); break; 1509 default: 1510 throw new Error('Unrecognized target: ' + target); 1511 } 1512 } 1513 }; 1514 1515 /** 1516 * @param {number} unitNdx 1517 * @param {?sglrReferenceContext.TextureContainer} texture 1518 */ 1519 sglrReferenceContext.ReferenceContext.prototype.setTexCubeBinding = function(unitNdx, texture) { 1520 if (this.m_textureUnits[unitNdx].texCubeBinding) { 1521 this.m_textureUnits[unitNdx].texCubeBinding = null; 1522 } 1523 1524 if (texture) { 1525 this.m_textureUnits[unitNdx].texCubeBinding = texture; 1526 } 1527 }; 1528 1529 /** 1530 * @param {number} unitNdx 1531 * @param {?sglrReferenceContext.TextureContainer} texture 1532 */ 1533 sglrReferenceContext.ReferenceContext.prototype.setTex2DBinding = function(unitNdx, texture) { 1534 if (this.m_textureUnits[unitNdx].tex2DBinding) { 1535 // this.m_textures.releaseReference(this.m_textureUnits[unitNdx].tex2DBinding); 1536 this.m_textureUnits[unitNdx].tex2DBinding = null; 1537 } 1538 1539 if (texture) { 1540 // this.m_textures.acquireReference(texture); 1541 this.m_textureUnits[unitNdx].tex2DBinding = texture; 1542 } 1543 }; 1544 1545 /** 1546 * @param {number} unitNdx 1547 * @param {?sglrReferenceContext.TextureContainer} texture 1548 */ 1549 sglrReferenceContext.ReferenceContext.prototype.setTex2DArrayBinding = function(unitNdx, texture) { 1550 if (this.m_textureUnits[unitNdx].tex2DArrayBinding) { 1551 // this.m_textures.releaseReference(this.m_textureUnits[unitNdx].tex2DArrayBinding); 1552 this.m_textureUnits[unitNdx].tex2DArrayBinding = null; 1553 } 1554 1555 if (texture) { 1556 // this.m_textures.acquireReference(texture); 1557 this.m_textureUnits[unitNdx].tex2DArrayBinding = texture; 1558 } 1559 }; 1560 1561 /** 1562 * @param {number} unitNdx 1563 * @param {?sglrReferenceContext.TextureContainer} texture 1564 */ 1565 sglrReferenceContext.ReferenceContext.prototype.setTex3DBinding = function(unitNdx, texture) { 1566 if (this.m_textureUnits[unitNdx].tex3DBinding) { 1567 // this.m_textures.releaseReference(this.m_textureUnits[unitNdx].tex3DBinding); 1568 this.m_textureUnits[unitNdx].tex3DBinding = null; 1569 } 1570 1571 if (texture) { 1572 // this.m_textures.acquireReference(texture); 1573 this.m_textureUnits[unitNdx].tex3DBinding = texture; 1574 } 1575 }; 1576 1577 /** 1578 * @return {sglrReferenceContext.TextureContainer} 1579 */ 1580 sglrReferenceContext.ReferenceContext.prototype.createTexture = function() { return new sglrReferenceContext.TextureContainer(); }; 1581 1582 /** 1583 * @param {sglrReferenceContext.Texture} texture 1584 */ 1585 sglrReferenceContext.ReferenceContext.prototype.deleteTexture = function(texture) { /*empty*/ }; 1586 1587 /** 1588 * @param {number} target 1589 * @param {framework.opengl.simplereference.sglrReferenceContext.Framebuffer} fbo 1590 */ 1591 sglrReferenceContext.ReferenceContext.prototype.bindFramebuffer = function(target, fbo) { 1592 if (this.conditionalSetError((target != gl.FRAMEBUFFER && 1593 target != gl.DRAW_FRAMEBUFFER && 1594 target != gl.READ_FRAMEBUFFER), gl.INVALID_ENUM)) 1595 return; 1596 for (var ndx = 0; ndx < 2; ndx++) { 1597 /** @type {number} */ var bindingTarget = ndx ? gl.DRAW_FRAMEBUFFER : gl.READ_FRAMEBUFFER; 1598 1599 if (target != gl.FRAMEBUFFER && target != bindingTarget) 1600 continue; // Doesn't match this target. 1601 1602 if (ndx) 1603 this.m_drawFramebufferBinding = fbo; 1604 else 1605 this.m_readFramebufferBinding = fbo; 1606 } 1607 }; 1608 1609 /** 1610 * @return {sglrReferenceContext.Framebuffer} 1611 */ 1612 sglrReferenceContext.ReferenceContext.prototype.createFramebuffer = function() { return new sglrReferenceContext.Framebuffer(); }; 1613 1614 /** 1615 * @param {sglrReferenceContext.Framebuffer} fbo 1616 */ 1617 sglrReferenceContext.ReferenceContext.prototype.deleteFramebuffer = function(fbo) { /*empty*/ }; 1618 1619 /** 1620 * @param {number} target 1621 * @param {sglrReferenceContext.Renderbuffer} rbo 1622 */ 1623 sglrReferenceContext.ReferenceContext.prototype.bindRenderbuffer = function(target, rbo) { 1624 if (this.conditionalSetError(target != gl.RENDERBUFFER, gl.INVALID_ENUM)) 1625 return; 1626 1627 this.m_renderbufferBinding = rbo; 1628 }; 1629 1630 /** 1631 * @return {sglrReferenceContext.Renderbuffer} 1632 */ 1633 sglrReferenceContext.ReferenceContext.prototype.createRenderbuffer = function() { return new sglrReferenceContext.Renderbuffer(); }; 1634 1635 /** 1636 * @param {sglrReferenceContext.Renderbuffer} rbo 1637 */ 1638 sglrReferenceContext.ReferenceContext.prototype.deleteRenderbuffer = function(rbo) { /*empty*/ }; 1639 1640 /** 1641 * @param {number} pname 1642 * @param {number} param 1643 */ 1644 sglrReferenceContext.ReferenceContext.prototype.pixelStorei = function(pname, param) { 1645 switch (pname) { 1646 case gl.UNPACK_ALIGNMENT: 1647 if (this.conditionalSetError((param != 1 && param != 2 && param != 4 && param != 8), gl.INVALID_VALUE)) return; 1648 this.m_pixelUnpackAlignment = param; 1649 break; 1650 1651 case gl.PACK_ALIGNMENT: 1652 if (this.conditionalSetError((param != 1 && param != 2 && param != 4 && param != 8), gl.INVALID_VALUE)) return; 1653 this.m_pixelPackAlignment = param; 1654 break; 1655 1656 case gl.UNPACK_ROW_LENGTH: 1657 if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return; 1658 this.m_pixelUnpackRowLength = param; 1659 break; 1660 1661 case gl.UNPACK_SKIP_ROWS: 1662 if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return; 1663 this.m_pixelUnpackSkipRows = param; 1664 break; 1665 1666 case gl.UNPACK_SKIP_PIXELS: 1667 if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return; 1668 this.m_pixelUnpackSkipPixels = param; 1669 break; 1670 1671 case gl.UNPACK_IMAGE_HEIGHT: 1672 if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return; 1673 this.m_pixelUnpackImageHeight = param; 1674 break; 1675 1676 case gl.UNPACK_SKIP_IMAGES: 1677 if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return; 1678 this.m_pixelUnpackSkipImages = param; 1679 break; 1680 1681 default: 1682 this.setError(gl.INVALID_ENUM); 1683 } 1684 }; 1685 1686 /** 1687 * @param {number} red 1688 * @param {number} green 1689 * @param {number} blue 1690 * @param {number} alpha 1691 */ 1692 sglrReferenceContext.ReferenceContext.prototype.clearColor = function(red, green, blue, alpha) { 1693 this.m_clearColor = [deMath.clamp(red, 0, 1), 1694 deMath.clamp(green, 0, 1), 1695 deMath.clamp(blue, 0, 1), 1696 deMath.clamp(alpha, 0, 1)]; 1697 }; 1698 1699 /** 1700 * @param {number} depth 1701 */ 1702 sglrReferenceContext.ReferenceContext.prototype.clearDepthf = function(depth) { 1703 this.m_clearDepth = deMath.clamp(depth, 0, 1); 1704 }; 1705 1706 /** 1707 * @param {number} stencil 1708 */ 1709 sglrReferenceContext.ReferenceContext.prototype.clearStencil = function(stencil) { 1710 this.m_clearStencil = stencil; 1711 }; 1712 1713 /** 1714 * @param {number} x 1715 * @param {number} y 1716 * @param {number} width 1717 * @param {number} height 1718 */ 1719 sglrReferenceContext.ReferenceContext.prototype.scissor = function(x, y, width, height) { 1720 if (this.conditionalSetError(width < 0 || height < 0, gl.INVALID_VALUE)) 1721 return; 1722 this.m_scissorBox = [x, y, width, height]; 1723 }; 1724 1725 /** 1726 * @param {number} cap 1727 */ 1728 sglrReferenceContext.ReferenceContext.prototype.enable = function(cap) { 1729 switch (cap) { 1730 case gl.BLEND: this.m_blendEnabled = true; break; 1731 case gl.SCISSOR_TEST: this.m_scissorEnabled = true; break; 1732 case gl.DEPTH_TEST: this.m_depthTestEnabled = true; break; 1733 case gl.STENCIL_TEST: this.m_stencilTestEnabled = true; break; 1734 case gl.POLYGON_OFFSET_FILL: this.m_polygonOffsetFillEnabled = true; break; 1735 1736 case gl.DITHER: 1737 // Not implemented - just ignored. 1738 break; 1739 1740 default: 1741 this.setError(gl.INVALID_ENUM); 1742 break; 1743 } 1744 }; 1745 1746 /** 1747 * @param {number} cap 1748 */ 1749 sglrReferenceContext.ReferenceContext.prototype.disable = function(cap) { 1750 switch (cap) { 1751 case gl.BLEND: this.m_blendEnabled = false; break; 1752 case gl.SCISSOR_TEST: this.m_scissorEnabled = false; break; 1753 case gl.DEPTH_TEST: this.m_depthTestEnabled = false; break; 1754 case gl.STENCIL_TEST: this.m_stencilTestEnabled = false; break; 1755 case gl.POLYGON_OFFSET_FILL: this.m_polygonOffsetFillEnabled = false; break; 1756 1757 case gl.DITHER: 1758 // Not implemented - just ignored. 1759 break; 1760 1761 default: 1762 this.setError(gl.INVALID_ENUM); 1763 break; 1764 } 1765 }; 1766 1767 /** 1768 * @param {number} func 1769 * @param {number} ref 1770 * @param {number} mask 1771 */ 1772 sglrReferenceContext.ReferenceContext.prototype.stencilFunc = function(func, ref, mask) { 1773 this.stencilFuncSeparate(gl.FRONT_AND_BACK, func, ref, mask); 1774 }; 1775 1776 /** 1777 * @param {number} face 1778 * @param {number} func 1779 * @param {number} ref 1780 * @param {number} mask 1781 */ 1782 sglrReferenceContext.ReferenceContext.prototype.stencilFuncSeparate = function(face, func, ref, mask) { 1783 /** @type {boolean} */ var setFront = face == gl.FRONT || face == gl.FRONT_AND_BACK; 1784 /** @type {boolean} */ var setBack = face == gl.BACK || face == gl.FRONT_AND_BACK; 1785 1786 if (this.conditionalSetError(!sglrReferenceContext.isValidCompareFunc(func), gl.INVALID_ENUM)) 1787 return; 1788 if (this.conditionalSetError(!setFront && !setBack, gl.INVALID_ENUM)) 1789 return; 1790 1791 for (var key in rrDefs.FaceType) { 1792 /** @type {number} */ var type = rrDefs.FaceType[key]; 1793 if ((type == rrDefs.FaceType.FACETYPE_FRONT && setFront) || 1794 (type == rrDefs.FaceType.FACETYPE_BACK && setBack)) { 1795 this.m_stencil[type].func = func; 1796 this.m_stencil[type].ref = ref; 1797 this.m_stencil[type].opMask = mask; 1798 } 1799 } 1800 }; 1801 1802 /** 1803 * @param {number} func 1804 * @return {boolean} 1805 */ 1806 sglrReferenceContext.isValidCompareFunc = function(func) { 1807 switch (func) { 1808 case gl.NEVER: 1809 case gl.LESS: 1810 case gl.LEQUAL: 1811 case gl.GREATER: 1812 case gl.GEQUAL: 1813 case gl.EQUAL: 1814 case gl.NOTEQUAL: 1815 case gl.ALWAYS: 1816 return true; 1817 1818 default: 1819 return false; 1820 } 1821 }; 1822 1823 /** 1824 * @param {number} op 1825 * @return {boolean} 1826 */ 1827 sglrReferenceContext.isValidStencilOp = function(op) { 1828 switch (op) { 1829 case gl.KEEP: 1830 case gl.ZERO: 1831 case gl.REPLACE: 1832 case gl.INCR: 1833 case gl.INCR_WRAP: 1834 case gl.DECR: 1835 case gl.DECR_WRAP: 1836 case gl.INVERT: 1837 return true; 1838 1839 default: 1840 return false; 1841 } 1842 }; 1843 1844 /** 1845 * @param {number} sfail 1846 * @param {number} dpfail 1847 * @param {number} dppass 1848 */ 1849 sglrReferenceContext.ReferenceContext.prototype.stencilOp = function(sfail, dpfail, dppass) { 1850 this.stencilOpSeparate(gl.FRONT_AND_BACK, sfail, dpfail, dppass); 1851 }; 1852 1853 /** 1854 * @param {number} face 1855 * @param {number} sfail 1856 * @param {number} dpfail 1857 * @param {number} dppass 1858 */ 1859 sglrReferenceContext.ReferenceContext.prototype.stencilOpSeparate = function(face, sfail, dpfail, dppass) { 1860 /** @type {boolean} */ var setFront = face == gl.FRONT || face == gl.FRONT_AND_BACK; 1861 /** @type {boolean} */ var setBack = face == gl.BACK || face == gl.FRONT_AND_BACK; 1862 1863 if (this.conditionalSetError((!sglrReferenceContext.isValidStencilOp(sfail) || 1864 !sglrReferenceContext.isValidStencilOp(dpfail) || 1865 !sglrReferenceContext.isValidStencilOp(dppass)), 1866 gl.INVALID_ENUM)) 1867 return; 1868 1869 if (this.conditionalSetError(!setFront && !setBack, gl.INVALID_ENUM)) 1870 return; 1871 1872 for (var key in rrDefs.FaceType) { 1873 /** @type {number} */ var type = rrDefs.FaceType[key]; 1874 if ((type == rrDefs.FaceType.FACETYPE_FRONT && setFront) || 1875 (type == rrDefs.FaceType.FACETYPE_BACK && setBack)) { 1876 this.m_stencil[type].opStencilFail = sfail; 1877 this.m_stencil[type].opDepthFail = dpfail; 1878 this.m_stencil[type].opDepthPass = dppass; 1879 } 1880 } 1881 }; 1882 1883 /** 1884 * @param {number} func 1885 */ 1886 sglrReferenceContext.ReferenceContext.prototype.depthFunc = function(func) { 1887 if (this.conditionalSetError(!sglrReferenceContext.isValidCompareFunc(func), gl.INVALID_ENUM)) 1888 return; 1889 this.m_depthFunc = func; 1890 }; 1891 1892 /** 1893 * @param {number} n 1894 * @param {number} f 1895 */ 1896 sglrReferenceContext.ReferenceContext.prototype.depthRange = function(n, f) { 1897 this.m_depthRangeNear = deMath.clamp(n, 0, 1); 1898 this.m_depthRangeFar = deMath.clamp(f, 0, 1); 1899 }; 1900 1901 /** 1902 * @param {number} factor 1903 * @param {number} units 1904 */ 1905 sglrReferenceContext.ReferenceContext.prototype.polygonOffset = function(factor, units) { 1906 this.m_polygonOffsetFactor = factor; 1907 this.m_polygonOffsetUnits = units; 1908 }; 1909 1910 /** 1911 * @param {number} mode 1912 * @return {boolean} 1913 */ 1914 sglrReferenceContext.isValidBlendEquation = function(mode) { 1915 return mode == gl.FUNC_ADD || 1916 mode == gl.FUNC_SUBTRACT || 1917 mode == gl.FUNC_REVERSE_SUBTRACT || 1918 mode == gl.MIN || 1919 mode == gl.MAX; 1920 }; 1921 1922 /** 1923 * @param {number} factor 1924 * @return {boolean} 1925 */ 1926 sglrReferenceContext.isValidBlendFactor = function(factor) { 1927 switch (factor) { 1928 case gl.ZERO: 1929 case gl.ONE: 1930 case gl.SRC_COLOR: 1931 case gl.ONE_MINUS_SRC_COLOR: 1932 case gl.DST_COLOR: 1933 case gl.ONE_MINUS_DST_COLOR: 1934 case gl.SRC_ALPHA: 1935 case gl.ONE_MINUS_SRC_ALPHA: 1936 case gl.DST_ALPHA: 1937 case gl.ONE_MINUS_DST_ALPHA: 1938 case gl.CONSTANT_COLOR: 1939 case gl.ONE_MINUS_CONSTANT_COLOR: 1940 case gl.CONSTANT_ALPHA: 1941 case gl.ONE_MINUS_CONSTANT_ALPHA: 1942 case gl.SRC_ALPHA_SATURATE: 1943 return true; 1944 1945 default: 1946 return false; 1947 } 1948 }; 1949 1950 /** 1951 * @param {number} mode 1952 */ 1953 sglrReferenceContext.ReferenceContext.prototype.blendEquation = function(mode) { 1954 if (this.conditionalSetError(!sglrReferenceContext.isValidBlendEquation(mode), gl.INVALID_ENUM)) 1955 return; 1956 this.m_blendModeRGB = mode; 1957 this.m_blendModeAlpha = mode; 1958 }; 1959 1960 /** 1961 * @param {number} modeRGB 1962 * @param {number} modeAlpha 1963 */ 1964 sglrReferenceContext.ReferenceContext.prototype.blendEquationSeparate = function(modeRGB, modeAlpha) { 1965 if (this.conditionalSetError(!sglrReferenceContext.isValidBlendEquation(modeRGB) || 1966 !sglrReferenceContext.isValidBlendEquation(modeAlpha), 1967 gl.INVALID_ENUM)) 1968 return; 1969 1970 this.m_blendModeRGB = modeRGB; 1971 this.m_blendModeAlpha = modeAlpha; 1972 }; 1973 1974 /** 1975 * @param {number} src 1976 * @param {number} dst 1977 */ 1978 sglrReferenceContext.ReferenceContext.prototype.blendFunc = function(src, dst) { 1979 if (this.conditionalSetError(!sglrReferenceContext.isValidBlendFactor(src) || 1980 !sglrReferenceContext.isValidBlendFactor(dst), 1981 gl.INVALID_ENUM)) 1982 return; 1983 1984 this.m_blendFactorSrcRGB = src; 1985 this.m_blendFactorSrcAlpha = src; 1986 this.m_blendFactorDstRGB = dst; 1987 this.m_blendFactorDstAlpha = dst; 1988 }; 1989 1990 /** 1991 * @param {number} srcRGB 1992 * @param {number} dstRGB 1993 * @param {number} srcAlpha 1994 * @param {number} dstAlpha 1995 */ 1996 sglrReferenceContext.ReferenceContext.prototype.blendFuncSeparate = function(srcRGB, dstRGB, srcAlpha, dstAlpha) { 1997 if (this.conditionalSetError(!sglrReferenceContext.isValidBlendFactor(srcRGB) || 1998 !sglrReferenceContext.isValidBlendFactor(dstRGB) || 1999 !sglrReferenceContext.isValidBlendFactor(srcAlpha) || 2000 !sglrReferenceContext.isValidBlendFactor(dstAlpha), 2001 gl.INVALID_ENUM)) 2002 return; 2003 2004 this.m_blendFactorSrcRGB = srcRGB; 2005 this.m_blendFactorSrcAlpha = srcAlpha; 2006 this.m_blendFactorDstRGB = dstRGB; 2007 this.m_blendFactorDstAlpha = dstAlpha; 2008 }; 2009 2010 /** 2011 * @param {number} red 2012 * @param {number} green 2013 * @param {number} blue 2014 * @param {number} alpha 2015 */ 2016 sglrReferenceContext.ReferenceContext.prototype.blendColor = function(red, green, blue, alpha) { 2017 this.m_blendColor = [deMath.clamp(red, 0, 1), 2018 deMath.clamp(green, 0, 1), 2019 deMath.clamp(blue, 0, 1), 2020 deMath.clamp(alpha, 0, 1)]; 2021 }; 2022 2023 /** 2024 * @param {boolean} r 2025 * @param {boolean} g 2026 * @param {boolean} b 2027 * @param {boolean} a 2028 */ 2029 sglrReferenceContext.ReferenceContext.prototype.colorMask = function(r, g, b, a) { 2030 this.m_colorMask = [r, g, b, a]; 2031 }; 2032 2033 /** 2034 * @param {boolean} mask 2035 */ 2036 sglrReferenceContext.ReferenceContext.prototype.depthMask = function(mask) { 2037 this.m_depthMask = mask; 2038 }; 2039 2040 /** 2041 * @param {number} mask 2042 */ 2043 sglrReferenceContext.ReferenceContext.prototype.stencilMask = function(mask) { 2044 this.stencilMaskSeparate(gl.FRONT_AND_BACK, mask); 2045 }; 2046 2047 /** 2048 * @param {number} face 2049 * @param {number} mask 2050 */ 2051 sglrReferenceContext.ReferenceContext.prototype.stencilMaskSeparate = function(face, mask) { 2052 /** @type {boolean} */ var setFront = face == gl.FRONT || face == gl.FRONT_AND_BACK; 2053 /** @type {boolean} */ var setBack = face == gl.BACK || face == gl.FRONT_AND_BACK; 2054 2055 if (this.conditionalSetError(!setFront && !setBack, gl.INVALID_ENUM)) 2056 return; 2057 2058 if (setFront) this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask = mask; 2059 if (setBack) this.m_stencil[rrDefs.FaceType.FACETYPE_BACK].writeMask = mask; 2060 }; 2061 2062 /** 2063 * @param {sglrReferenceContext.VertexArray} array 2064 */ 2065 sglrReferenceContext.ReferenceContext.prototype.bindVertexArray = function(array) { 2066 if (array) 2067 this.m_vertexArrayBinding = array; 2068 else 2069 this.m_vertexArrayBinding = this.m_defaultVAO; 2070 }; 2071 2072 /** 2073 * @return {sglrReferenceContext.VertexArray} 2074 */ 2075 sglrReferenceContext.ReferenceContext.prototype.createVertexArray = function() { return new sglrReferenceContext.VertexArray(this.m_limits.maxVertexAttribs); }; 2076 2077 /** 2078 * @param {number} array 2079 */ 2080 sglrReferenceContext.ReferenceContext.prototype.deleteVertexArray = function(array) {}; 2081 2082 /** 2083 * @param {number} index 2084 * @param {number} rawSize 2085 * @param {number} type 2086 * @param {boolean} normalized 2087 * @param {number} stride 2088 * @param {number} offset 2089 */ 2090 sglrReferenceContext.ReferenceContext.prototype.vertexAttribPointer = function(index, rawSize, type, normalized, stride, offset) { 2091 /** @type {boolean} */ var allowBGRA = false; 2092 /** @type {number} */ var effectiveSize = rawSize; 2093 2094 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2095 return; 2096 if (this.conditionalSetError(effectiveSize <= 0 || effectiveSize > 4, gl.INVALID_VALUE)) 2097 return; 2098 if (this.conditionalSetError(type != gl.BYTE && type != gl.UNSIGNED_BYTE && 2099 type != gl.SHORT && type != gl.UNSIGNED_SHORT && 2100 type != gl.INT && type != gl.UNSIGNED_INT && 2101 type != gl.FLOAT && type != gl.HALF_FLOAT && 2102 type != gl.INT_2_10_10_10_REV && type != gl.UNSIGNED_INT_2_10_10_10_REV, gl.INVALID_ENUM)) 2103 return; 2104 if (this.conditionalSetError(normalized != true && normalized != false, gl.INVALID_ENUM)) 2105 return; 2106 if (this.conditionalSetError(stride < 0, gl.INVALID_VALUE)) 2107 return; 2108 if (this.conditionalSetError((type == gl.INT_2_10_10_10_REV || type == gl.UNSIGNED_INT_2_10_10_10_REV) && effectiveSize != 4, gl.INVALID_OPERATION)) 2109 return; 2110 if (this.conditionalSetError(this.m_vertexArrayBinding != null && this.m_arrayBufferBinding == null && offset != 0, gl.INVALID_OPERATION)) 2111 return; 2112 2113 /** @type {?(sglrReferenceContext.VertexArray.VertexAttribArray)} */ var array_ = this.m_vertexArrayBinding.m_arrays[index]; // TODO: fix type 2114 2115 array_.size = rawSize; 2116 array_.stride = stride; 2117 array_.type = type; 2118 array_.normalized = normalized; 2119 array_.integer = false; 2120 array_.offset = offset; 2121 2122 array_.bufferBinding = this.m_arrayBufferBinding; 2123 }; 2124 2125 /** 2126 * @param {number} index 2127 * @param {number} size 2128 * @param {number} type 2129 * @param {number} stride 2130 * @param {number} offset 2131 */ 2132 sglrReferenceContext.ReferenceContext.prototype.vertexAttribIPointer = function(index, size, type, stride, offset) { 2133 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2134 return; 2135 if (this.conditionalSetError(size <= 0 || size > 4, gl.INVALID_VALUE)) 2136 return; 2137 if (this.conditionalSetError(type != gl.BYTE && type != gl.UNSIGNED_BYTE && 2138 type != gl.SHORT && type != gl.UNSIGNED_SHORT && 2139 type != gl.INT && type != gl.UNSIGNED_INT, gl.INVALID_ENUM)) 2140 return; 2141 if (this.conditionalSetError(stride < 0, gl.INVALID_VALUE)) 2142 return; 2143 if (this.conditionalSetError(this.m_vertexArrayBinding != null && this.m_arrayBufferBinding == null && offset != 0, gl.INVALID_OPERATION)) 2144 return; 2145 2146 /** @type {?(sglrReferenceContext.VertexArray.VertexAttribArray)} */ var array_ = this.m_vertexArrayBinding.m_arrays[index]; // TODO: fix type 2147 2148 array_.size = size; 2149 array_.stride = stride; 2150 array_.type = type; 2151 array_.normalized = false; 2152 array_.integer = true; 2153 array_.offset = offset; 2154 2155 array_.bufferBinding = this.m_arrayBufferBinding; 2156 }; 2157 2158 /** 2159 * @param {number} index 2160 */ 2161 sglrReferenceContext.ReferenceContext.prototype.enableVertexAttribArray = function(index) { 2162 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2163 return; 2164 2165 this.m_vertexArrayBinding.m_arrays[index].enabled = true; 2166 }; 2167 2168 /** 2169 * @param {number} index 2170 */ 2171 sglrReferenceContext.ReferenceContext.prototype.disableVertexAttribArray = function(index) { 2172 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2173 return; 2174 2175 this.m_vertexArrayBinding.m_arrays[index].enabled = false; 2176 }; 2177 2178 /** 2179 * @param {number} index 2180 * @param {number} divisor 2181 */ 2182 sglrReferenceContext.ReferenceContext.prototype.vertexAttribDivisor = function(index, divisor) { 2183 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2184 return; 2185 2186 this.m_vertexArrayBinding.m_arrays[index].divisor = divisor; 2187 }; 2188 2189 /** 2190 * @param {number} index 2191 * @param {number} x 2192 */ 2193 sglrReferenceContext.ReferenceContext.prototype.vertexAttrib1f = function(index, x) { 2194 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2195 return; 2196 2197 this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, 0, 0, 1); 2198 }; 2199 2200 /** 2201 * @param {number} index 2202 * @param {number} x 2203 * @param {number} y 2204 */ 2205 sglrReferenceContext.ReferenceContext.prototype.vertexAttrib2f = function(index, x, y) { 2206 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2207 return; 2208 2209 this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, 0, 1); 2210 }; 2211 2212 /** 2213 * @param {number} index 2214 * @param {number} x 2215 * @param {number} y 2216 * @param {number} z 2217 */ 2218 sglrReferenceContext.ReferenceContext.prototype.vertexAttrib3f = function(index, x, y, z) { 2219 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2220 return; 2221 2222 this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, 1); 2223 }; 2224 2225 /** 2226 * @param {number} index 2227 * @param {number} x 2228 * @param {number} y 2229 * @param {number} z 2230 * @param {number} w 2231 */ 2232 sglrReferenceContext.ReferenceContext.prototype.vertexAttrib4f = function(index, x, y, z, w) { 2233 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2234 return; 2235 2236 this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, w); 2237 }; 2238 2239 /** 2240 * @param {number} index 2241 * @param {number} x 2242 * @param {number} y 2243 * @param {number} z 2244 * @param {number} w 2245 */ 2246 sglrReferenceContext.ReferenceContext.prototype.vertexAttribI4i = function(index, x, y, z, w) { 2247 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2248 return; 2249 2250 this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, w); 2251 }; 2252 2253 /** 2254 * @param {number} index 2255 * @param {number} x 2256 * @param {number} y 2257 * @param {number} z 2258 * @param {number} w 2259 */ 2260 sglrReferenceContext.ReferenceContext.prototype.vertexAttribI4ui = function(index, x, y, z, w) { 2261 if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE)) 2262 return; 2263 2264 this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, w); 2265 }; 2266 2267 /** 2268 * @param {sglrShaderProgram.ShaderProgram} program 2269 * @param {string} name 2270 * @return {number} 2271 */ 2272 sglrReferenceContext.ReferenceContext.prototype.getAttribLocation = function(program, name) { 2273 if (this.conditionalSetError(!(program), gl.INVALID_OPERATION)) 2274 return -1; 2275 2276 for (var i = 0; i < program.m_attributeNames.length; i++) 2277 if (program.m_attributeNames[i] === name) 2278 return i; 2279 2280 return -1; 2281 }; 2282 2283 /** 2284 * @param {number} pname 2285 */ 2286 sglrReferenceContext.ReferenceContext.prototype.getParameter = function(pname) { 2287 switch (pname) { 2288 case (gl.VIEWPORT): return new Int32Array(this.m_viewport); 2289 case (gl.SCISSOR_BOX): return new Int32Array(this.m_scissorBox); 2290 default: 2291 throw new Error('Unimplemented'); 2292 } 2293 }; 2294 2295 /** 2296 * @param {number} location 2297 * @param {gluShaderUtil.DataType} type 2298 * @param {Array<number>} value 2299 */ 2300 sglrReferenceContext.ReferenceContext.prototype.uniformValue = function(location, type, value) { 2301 if (this.conditionalSetError(!this.m_currentProgram, gl.INVALID_OPERATION)) 2302 return; 2303 2304 if (location === null) 2305 return; 2306 2307 /** @type {sglrShaderProgram.Uniform} */ var uniform = this.m_currentProgram.m_uniforms[location]; 2308 2309 if (this.conditionalSetError(!uniform, gl.INVALID_OPERATION)) 2310 return; 2311 2312 if (gluShaderUtil.isDataTypeSampler(uniform.type)) { 2313 if (this.conditionalSetError(type != gluShaderUtil.DataType.INT, gl.INVALID_OPERATION)) 2314 return; 2315 } else if (this.conditionalSetError(uniform.type != type, gl.INVALID_OPERATION)) 2316 return; 2317 /* TODO: Do we need to copy objects? */ 2318 uniform.value = value; 2319 }; 2320 2321 /** 2322 * @param {number} location 2323 * @param {number} x 2324 */ 2325 sglrReferenceContext.ReferenceContext.prototype.uniform1f = function(location, x) { 2326 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT, [x]); 2327 }; 2328 2329 /** 2330 * @param {number} location 2331 * @param {Array<number>} x 2332 */ 2333 sglrReferenceContext.ReferenceContext.prototype.uniform1fv = function(location, x) { 2334 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT, x); 2335 }; 2336 2337 /** 2338 * @param {number} location 2339 * @param {number} x 2340 */ 2341 sglrReferenceContext.ReferenceContext.prototype.uniform1i = function(location, x) { 2342 return this.uniformValue(location, gluShaderUtil.DataType.INT, [x]); 2343 }; 2344 2345 /** 2346 * @param {number} location 2347 * @param {Array<number>} x 2348 */ 2349 sglrReferenceContext.ReferenceContext.prototype.uniform1iv = function(location, x) { 2350 return this.uniformValue(location, gluShaderUtil.DataType.INT, x); 2351 }; 2352 2353 /** 2354 * @param {number} location 2355 * @param {number} x 2356 * @param {number} y 2357 */ 2358 sglrReferenceContext.ReferenceContext.prototype.uniform2f = function(location, x, y) { 2359 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC2, [x, y]); 2360 }; 2361 2362 /** 2363 * @param {number} location 2364 * @param {Array<number>} x 2365 */ 2366 sglrReferenceContext.ReferenceContext.prototype.uniform2fv = function(location, x) { 2367 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC2, x); 2368 }; 2369 2370 /** 2371 * @param {number} location 2372 * @param {number} x 2373 * @param {number} y 2374 */ 2375 sglrReferenceContext.ReferenceContext.prototype.uniform2i = function(location, x, y) { 2376 return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC2, [x, y]); 2377 }; 2378 2379 /** 2380 * @param {number} location 2381 * @param {Array<number>} x 2382 */ 2383 sglrReferenceContext.ReferenceContext.prototype.uniform2iv = function(location, x) { 2384 return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC2, x); 2385 }; 2386 2387 /** 2388 * @param {number} location 2389 * @param {number} x 2390 * @param {number} y 2391 * @param {number} z 2392 */ 2393 sglrReferenceContext.ReferenceContext.prototype.uniform3f = function(location, x, y, z) { 2394 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC3, [x, y, z]); 2395 }; 2396 2397 /** 2398 * @param {number} location 2399 * @param {Array<number>} x 2400 */ 2401 sglrReferenceContext.ReferenceContext.prototype.uniform3fv = function(location, x) { 2402 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC3, x); 2403 }; 2404 2405 /** 2406 * @param {number} location 2407 * @param {number} x 2408 * @param {number} y 2409 * @param {number} z 2410 */ 2411 sglrReferenceContext.ReferenceContext.prototype.uniform3i = function(location, x, y, z) { 2412 return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC3, [x, y, z]); 2413 }; 2414 2415 /** 2416 * @param {number} location 2417 * @param {Array<number>} x 2418 */ 2419 sglrReferenceContext.ReferenceContext.prototype.uniform3iv = function(location, x) { 2420 return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC3, x); 2421 }; 2422 2423 /** 2424 * @param {number} location 2425 * @param {number} x 2426 * @param {number} y 2427 * @param {number} z 2428 * @param {number} w 2429 */ 2430 sglrReferenceContext.ReferenceContext.prototype.uniform4f = function(location, x, y, z, w) { 2431 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC4, [x, y, z, w]); 2432 }; 2433 2434 /** 2435 * @param {number} location 2436 * @param {Array<number>} x 2437 */ 2438 sglrReferenceContext.ReferenceContext.prototype.uniform4fv = function(location, x) { 2439 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC4, x); 2440 }; 2441 2442 /** 2443 * @param {number} location 2444 * @param {number} x 2445 * @param {number} y 2446 * @param {number} z 2447 * @param {number} w 2448 */ 2449 sglrReferenceContext.ReferenceContext.prototype.uniform4i = function(location, x, y, z, w) { 2450 return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC4, [x, y, z, w]); 2451 }; 2452 2453 /** 2454 * @param {number} location 2455 * @param {Array<number>} x 2456 */ 2457 sglrReferenceContext.ReferenceContext.prototype.uniform4iv = function(location, x) { 2458 return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC4, x); 2459 }; 2460 2461 /** 2462 * @return {Array<string>} 2463 */ 2464 sglrReferenceContext.ReferenceContext.prototype.getSupportedExtensions = function() { 2465 var extensions = gl.getSupportedExtensions(); //TODO: Let's just return gl's supported extensions for now 2466 return extensions; 2467 }; 2468 2469 /** 2470 * @param {string} name 2471 * @return {*} 2472 */ 2473 sglrReferenceContext.ReferenceContext.prototype.getExtension = function(name) { 2474 return gl.getExtension(name); //TODO: Let's just return gl's supported extensions for now 2475 }; 2476 2477 /** transpose matrix 'x' of 'size' columns and rows 2478 * @param {number} size 2479 * @param {Array<number>} x 2480 * @return {Array<number>} 2481 */ 2482 sglrReferenceContext.trans = function(size, x) { 2483 /** @type {Array<number>} */ var result = []; 2484 for (var row = 0; row < size; ++row) 2485 for (var col = 0; col < size; ++col) 2486 result[row * size + col] = x[col * size + row]; 2487 2488 return result; 2489 }; 2490 2491 /** 2492 * @param {number} location 2493 * @param {Array<number>} x 2494 */ 2495 sglrReferenceContext.ReferenceContext.prototype.uniformMatrix2fv = function(location, transpose, x) { 2496 /* change from column-major to internal row-major if transpose if FALSE */ 2497 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_MAT2, !transpose ? sglrReferenceContext.trans(2, x) : x); 2498 }; 2499 2500 /** 2501 * @param {number} location 2502 * @param {Array<number>} x 2503 */ 2504 sglrReferenceContext.ReferenceContext.prototype.uniformMatrix3fv = function(location, transpose, x) { 2505 /* change from column-major to internal row-major if transpose if FALSE */ 2506 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_MAT3, !transpose ? sglrReferenceContext.trans(3, x) : x); 2507 }; 2508 2509 /** 2510 * @param {number} location 2511 * @param {Array<number>} x 2512 */ 2513 sglrReferenceContext.ReferenceContext.prototype.uniformMatrix4fv = function(location, transpose, x) { 2514 /* change from column-major to internal row-major if transpose if FALSE */ 2515 return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_MAT4, !transpose ? sglrReferenceContext.trans(4, x) : x); 2516 }; 2517 2518 /** 2519 * @param {sglrShaderProgram.ShaderProgram} program 2520 * @param {string} name 2521 * @return {number} 2522 */ 2523 sglrReferenceContext.ReferenceContext.prototype.getUniformLocation = function(program, name) { 2524 if (this.conditionalSetError(!program, gl.INVALID_OPERATION)) 2525 return -1; 2526 2527 for (var i = 0; i < program.m_uniforms.length; i++) 2528 if (program.m_uniforms[i].name === name) 2529 return i; 2530 2531 return -1; 2532 }; 2533 2534 /** 2535 * @param {number} w 2536 */ 2537 sglrReferenceContext.ReferenceContext.prototype.lineWidth = function(w) { 2538 if (this.conditionalSetError(w < 0, gl.INVALID_VALUE)) 2539 return; 2540 this.m_lineWidth = w; 2541 }; 2542 2543 /** 2544 * @param {number} target 2545 * @return {boolean} 2546 */ 2547 sglrReferenceContext.isValidBufferTarget = function(target) { 2548 switch (target) { 2549 case gl.ARRAY_BUFFER: 2550 case gl.COPY_READ_BUFFER: 2551 case gl.COPY_WRITE_BUFFER: 2552 case gl.ELEMENT_ARRAY_BUFFER: 2553 case gl.PIXEL_PACK_BUFFER: 2554 case gl.PIXEL_UNPACK_BUFFER: 2555 case gl.TRANSFORM_FEEDBACK_BUFFER: 2556 case gl.UNIFORM_BUFFER: 2557 return true; 2558 2559 default: 2560 return false; 2561 } 2562 }; 2563 2564 /** 2565 * @param {number} target 2566 * @param {sglrReferenceContext.DataBuffer} buffer 2567 * @throws {Error} 2568 */ 2569 sglrReferenceContext.ReferenceContext.prototype.setBufferBinding = function(target, buffer) { 2570 switch (target) { 2571 case gl.ARRAY_BUFFER: this.m_arrayBufferBinding = buffer; break; 2572 case gl.COPY_READ_BUFFER: this.m_copyReadBufferBinding = buffer; break; 2573 case gl.COPY_WRITE_BUFFER: this.m_copyWriteBufferBinding = buffer; break; 2574 case gl.ELEMENT_ARRAY_BUFFER: this.m_vertexArrayBinding.m_elementArrayBufferBinding = buffer; break; 2575 case gl.PIXEL_PACK_BUFFER: this.m_pixelPackBufferBinding = buffer; break; 2576 case gl.PIXEL_UNPACK_BUFFER: this.m_pixelUnpackBufferBinding = buffer; break; 2577 case gl.TRANSFORM_FEEDBACK_BUFFER: this.m_transformFeedbackBufferBinding = buffer; break; 2578 case gl.UNIFORM_BUFFER: this.m_uniformBufferBinding = buffer; break; 2579 default: 2580 throw new Error('Unrecognized target: ' + target); 2581 } 2582 }; 2583 2584 /** 2585 * @param {number} target 2586 * @return {sglrReferenceContext.DataBuffer} 2587 * @throws {Error} 2588 */ 2589 sglrReferenceContext.ReferenceContext.prototype.getBufferBinding = function(target) { 2590 switch (target) { 2591 case gl.ARRAY_BUFFER: return this.m_arrayBufferBinding; 2592 case gl.COPY_READ_BUFFER: return this.m_copyReadBufferBinding; 2593 case gl.COPY_WRITE_BUFFER: return this.m_copyWriteBufferBinding; 2594 case gl.ELEMENT_ARRAY_BUFFER: return this.m_vertexArrayBinding.m_elementArrayBufferBinding; 2595 case gl.PIXEL_PACK_BUFFER: return this.m_pixelPackBufferBinding; 2596 case gl.PIXEL_UNPACK_BUFFER: return this.m_pixelUnpackBufferBinding; 2597 case gl.TRANSFORM_FEEDBACK_BUFFER: return this.m_transformFeedbackBufferBinding; 2598 case gl.UNIFORM_BUFFER: return this.m_uniformBufferBinding; 2599 default: 2600 throw new Error('Unrecognized target: ' + target); 2601 } 2602 }; 2603 2604 /** 2605 * @param {number} target 2606 * @param {sglrReferenceContext.DataBuffer} buffer 2607 */ 2608 sglrReferenceContext.ReferenceContext.prototype.bindBuffer = function(target, buffer) { 2609 if (this.conditionalSetError(!sglrReferenceContext.isValidBufferTarget(target), gl.INVALID_ENUM)) 2610 return; 2611 2612 this.setBufferBinding(target, buffer); 2613 }; 2614 2615 /** 2616 * @return {sglrReferenceContext.DataBuffer} 2617 */ 2618 sglrReferenceContext.ReferenceContext.prototype.createBuffer = function() { return new sglrReferenceContext.DataBuffer(); }; 2619 2620 /** 2621 * @param {number} buffer 2622 */ 2623 sglrReferenceContext.ReferenceContext.prototype.deleteBuffer = function(buffer) {}; 2624 2625 /** 2626 * @param {number} target 2627 * @param {number|goog.NumberArray} input 2628 * @param {number} usage 2629 */ 2630 sglrReferenceContext.ReferenceContext.prototype.bufferData = function(target, input, usage) { 2631 if (this.conditionalSetError(!sglrReferenceContext.isValidBufferTarget(target), gl.INVALID_ENUM)) 2632 return; 2633 /** @type {sglrReferenceContext.DataBuffer} */ var buffer = this.getBufferBinding(target); 2634 if (this.conditionalSetError(!buffer, gl.INVALID_OPERATION)) 2635 return; 2636 2637 if (typeof input == 'number') { 2638 if (this.conditionalSetError(input < 0, gl.INVALID_VALUE)) 2639 return; 2640 buffer.setStorage(input); 2641 } else { 2642 buffer.setData(input); 2643 } 2644 }; 2645 2646 /** 2647 * @param {number} target 2648 * @param {number} offset 2649 * @param {goog.NumberArray} data 2650 */ 2651 sglrReferenceContext.ReferenceContext.prototype.bufferSubData = function(target, offset, data) { 2652 if (this.conditionalSetError(!sglrReferenceContext.isValidBufferTarget(target), gl.INVALID_ENUM)) 2653 return; 2654 if (this.conditionalSetError(offset < 0, gl.INVALID_VALUE)) 2655 return; 2656 /** @type {sglrReferenceContext.DataBuffer} */ var buffer = this.getBufferBinding(target); 2657 if (this.conditionalSetError(!buffer, gl.INVALID_OPERATION)) 2658 return; 2659 2660 if (this.conditionalSetError(offset + data.byteLength > buffer.getSize(), gl.INVALID_VALUE)) 2661 return; 2662 buffer.setSubData(offset, data); 2663 }; 2664 2665 /** 2666 * @param {number} x 2667 * @param {number} y 2668 * @param {number} width 2669 * @param {number} height 2670 * @param {number} format 2671 * @param {number} type 2672 * @param {goog.NumberArray} pixels 2673 */ 2674 sglrReferenceContext.ReferenceContext.prototype.readPixels = function(x, y, width, height, format, type, pixels) { 2675 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src = this.getReadColorbuffer(); 2676 2677 // Map transfer format. 2678 /** @type {tcuTexture.TextureFormat} */ var transferFmt = gluTextureUtil.mapGLTransferFormat(format, type); 2679 2680 // Clamp input values 2681 /** @type {number} */ var copyX = deMath.clamp(x, 0, src.raw().getHeight()); 2682 /** @type {number} */ var copyY = deMath.clamp(y, 0, src.raw().getDepth()); 2683 /** @type {number} */ var copyWidth = deMath.clamp(width, 0, src.raw().getHeight() - x); 2684 /** @type {number} */ var copyHeight = deMath.clamp(height, 0, src.raw().getDepth() - y); 2685 2686 /** @type {?ArrayBuffer} */ var data; 2687 /** @type {number} */ var offset; 2688 if (this.m_pixelPackBufferBinding) { 2689 if (this.conditionalSetError(typeof pixels !== 'number', gl.INVALID_VALUE)) 2690 return; 2691 data = this.m_pixelPackBufferBinding.getData(); 2692 offset = pixels.byteOffset; 2693 } else { 2694 if (pixels instanceof ArrayBuffer) { 2695 data = pixels; 2696 offset = 0; 2697 } else { 2698 data = pixels.buffer; 2699 offset = pixels.byteOffset; 2700 } 2701 } 2702 2703 /** @type {tcuTexture.PixelBufferAccess} */ 2704 var dst = new tcuTexture.PixelBufferAccess({ 2705 format: transferFmt, 2706 width: width, 2707 height: height, 2708 depth: 1, 2709 rowPitch: deMath.deAlign32(width * transferFmt.getPixelSize(), this.m_pixelPackAlignment), 2710 slicePitch: 0, 2711 data: data, 2712 offset: offset}); 2713 2714 src = src.getSubregion([copyX, copyY, copyWidth, copyHeight]); 2715 src.resolveMultisampleColorBuffer(tcuTextureUtil.getSubregion(dst, 0, 0, 0, copyWidth, copyHeight, 1)); 2716 }; 2717 2718 /** 2719 * @return {number} 2720 */ 2721 sglrReferenceContext.ReferenceContext.prototype.getType = function() { 2722 return this.m_type; 2723 }; 2724 2725 /** 2726 * @return {tcuTexture.PixelBufferAccess} 2727 */ 2728 sglrReferenceContext.nullAccess = function() { 2729 return new tcuTexture.PixelBufferAccess({ 2730 width: 0, 2731 height: 0}); 2732 }; 2733 2734 /** 2735 * @param {sglrReferenceContext.Framebuffer} framebuffer 2736 * @param {sglrReferenceContext.AttachmentPoint} point 2737 * @return {tcuTexture.PixelBufferAccess} 2738 */ 2739 sglrReferenceContext.ReferenceContext.prototype.getFboAttachment = function(framebuffer, point) { 2740 /** @type {sglrReferenceContext.Attachment} */ var attachment = framebuffer.getAttachment(point); 2741 2742 switch (attachment.type) { 2743 case sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE: { 2744 var container = /** @type {sglrReferenceContext.TextureContainer} */ (attachment.object); 2745 /** @type {?sglrReferenceContext.TextureType} */ var type = container.getType(); 2746 var texture = container.texture; 2747 2748 if (type == sglrReferenceContext.TextureType.TYPE_2D) 2749 return texture.getLevel(attachment.level); 2750 else if (type == sglrReferenceContext.TextureType.TYPE_CUBE_MAP) 2751 return texture.getFace(attachment.level, sglrReferenceContext.texTargetToFace(attachment.texTarget)); 2752 else if (type == sglrReferenceContext.TextureType.TYPE_2D_ARRAY || 2753 type == sglrReferenceContext.TextureType.TYPE_3D || 2754 type == sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY) { 2755 /** @type {tcuTexture.PixelBufferAccess} */ var level = texture.getLevel(attachment.level); 2756 2757 return new tcuTexture.PixelBufferAccess({ 2758 format: level.getFormat(), 2759 width: level.getWidth(), 2760 height: level.getHeight(), 2761 depth: 1, 2762 rowPitch: level.getRowPitch(), 2763 slicePitch: 0, 2764 data: level.getBuffer(), 2765 offset: level.getSlicePitch() * attachment.layer}); 2766 } else 2767 return sglrReferenceContext.nullAccess(); 2768 } 2769 2770 case sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_RENDERBUFFER: { 2771 var rbo = /** @type {sglrReferenceContext.Renderbuffer} */ (attachment.object); 2772 return rbo.getAccess(); 2773 } 2774 2775 default: 2776 return sglrReferenceContext.nullAccess(); 2777 } 2778 }; 2779 2780 /** 2781 * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 2782 */ 2783 sglrReferenceContext.ReferenceContext.prototype.getReadColorbuffer = function() { 2784 if (this.m_readFramebufferBinding) 2785 return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_readFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0)); 2786 else 2787 return this.m_defaultColorbuffer; 2788 }; 2789 2790 // sglrReferenceContext.ReferenceContext.prototype.drawArrays = function(mode, first, count) { 2791 // this.drawArraysInstanced(mode, first, count, 1); 2792 // }; 2793 2794 /** 2795 * @param {number} target 2796 * @return {number} 2797 * @throws {Error} 2798 */ 2799 sglrReferenceContext.ReferenceContext.prototype.checkFramebufferStatus = function(target) { 2800 if (this.conditionalSetError(target != gl.FRAMEBUFFER && 2801 target != gl.DRAW_FRAMEBUFFER && 2802 target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM)) 2803 return 0; 2804 2805 // Select binding point. 2806 /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding; 2807 2808 // Default framebuffer is always complete. 2809 if (!framebufferBinding) 2810 return gl.FRAMEBUFFER_COMPLETE; 2811 2812 /** @type {number} */ var width = -1; 2813 /** @type {number} */ var height = -1; 2814 /** @type {boolean} */ var hasAttachment = false; 2815 /** @type {boolean} */ var attachmentComplete = true; 2816 /** @type {boolean} */ var dimensionsOk = true; 2817 2818 for (var key in sglrReferenceContext.AttachmentPoint) { 2819 /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.AttachmentPoint[key]; 2820 /** @type {sglrReferenceContext.Attachment} */ var attachment = framebufferBinding.getAttachment(point); 2821 /** @type {number} */ var attachmentWidth = 0; 2822 /** @type {number} */ var attachmentHeight = 0; 2823 /** @type {tcuTexture.TextureFormat} */ var attachmentFormat; 2824 2825 if (attachment.type == sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE) { 2826 var container = /** @type {sglrReferenceContext.TextureContainer} */ (attachment.object); 2827 /** @type {tcuTexture.ConstPixelBufferAccess} */ var level; 2828 2829 if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_2D) { 2830 DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_2D); 2831 /** @type {sglrReferenceContext.Texture2D} */ var tex2D = /** @type {sglrReferenceContext.Texture2D} */ (container.texture); 2832 2833 if (tex2D.hasLevel(attachment.level)) 2834 level = tex2D.getLevel(attachment.level); 2835 // TODO: implement CUBE_MAP, 2D_ARRAY, 3D, CUBE_MAP_ARRAY 2836 } else if (deMath.deInRange32(attachment.texTarget, sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X, 2837 sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z)) { 2838 DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_CUBE_MAP); 2839 2840 var texCube = /** @type {sglrReferenceContext.TextureCube} */ (container.texture); 2841 var face = sglrReferenceContext.texTargetToFace(attachment.texTarget); 2842 2843 if (texCube.hasFace(attachment.level, face)) 2844 level = texCube.getFace(attachment.level, face); 2845 } else if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_2D_ARRAY) { 2846 DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_2D_ARRAY); 2847 var tex2DArr = /** @type {sglrReferenceContext.Texture2DArray} */ (container.texture); 2848 2849 if (tex2DArr.hasLevel(attachment.level)) 2850 level = tex2DArr.getLevel(attachment.level); // \note Slice doesn't matter here. 2851 } else if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_3D) { 2852 DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_3D); 2853 var tex3D = /** @type {sglrReferenceContext.Texture3D} */ (container.texture); 2854 2855 if (tex3D.hasLevel(attachment.level)) 2856 level = tex3D.getLevel(attachment.level); // \note Slice doesn't matter here. 2857 // } else if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_ARRAY) { 2858 // DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY); 2859 // var texCubeArr = container.texture; 2860 // 2861 // if (texCubeArr.hasLevel(attachment.level)) 2862 // level = texCubeArr.getLevel(attachment.level); // \note Slice doesn't matter here. 2863 } else 2864 throw new Error('sglrReferenceContext.Framebuffer attached to a texture but no valid target specified.'); 2865 2866 attachmentWidth = level.getWidth(); 2867 attachmentHeight = level.getHeight(); 2868 attachmentFormat = level.getFormat(); 2869 } else if (attachment.type == sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_RENDERBUFFER) { 2870 var renderbuffer = attachment.object; 2871 2872 attachmentWidth = renderbuffer.getWidth(); 2873 attachmentHeight = renderbuffer.getHeight(); 2874 attachmentFormat = renderbuffer.getFormat(); 2875 } else 2876 continue; // Skip rest of checks. 2877 2878 if (!hasAttachment && attachmentWidth > 0 && attachmentHeight > 0) { 2879 width = attachmentWidth; 2880 height = attachmentHeight; 2881 hasAttachment = true; 2882 } else if (attachmentWidth != width || attachmentHeight != height) 2883 dimensionsOk = false; 2884 2885 // Validate attachment point compatibility. 2886 switch (attachmentFormat.order) { 2887 case tcuTexture.ChannelOrder.R: 2888 case tcuTexture.ChannelOrder.RG: 2889 case tcuTexture.ChannelOrder.RGB: 2890 case tcuTexture.ChannelOrder.RGBA: 2891 case tcuTexture.ChannelOrder.sRGB: 2892 case tcuTexture.ChannelOrder.sRGBA: 2893 if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0) 2894 attachmentComplete = false; 2895 break; 2896 2897 case tcuTexture.ChannelOrder.D: 2898 if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH) 2899 attachmentComplete = false; 2900 break; 2901 2902 case tcuTexture.ChannelOrder.S: 2903 if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL) 2904 attachmentComplete = false; 2905 break; 2906 2907 case tcuTexture.ChannelOrder.DS: 2908 if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH && 2909 point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL) 2910 attachmentComplete = false; 2911 break; 2912 2913 default: 2914 throw new Error('Unsupported attachment channel order:' + attachmentFormat.order); 2915 } 2916 } 2917 2918 if (!attachmentComplete) 2919 return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 2920 else if (!hasAttachment) 2921 return gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; 2922 else if (!dimensionsOk) 2923 return gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 2924 else 2925 return gl.FRAMEBUFFER_COMPLETE; 2926 }; 2927 2928 /** 2929 * @param {number} mode 2930 * @return {boolean} 2931 */ 2932 sglrReferenceContext.ReferenceContext.prototype.predrawErrorChecks = function(mode) { 2933 if (this.conditionalSetError(mode != gl.POINTS && 2934 mode != gl.LINE_STRIP && mode != gl.LINE_LOOP && mode != gl.LINES && 2935 mode != gl.TRIANGLE_STRIP && mode != gl.TRIANGLE_FAN && mode != gl.TRIANGLES, 2936 gl.INVALID_ENUM)) 2937 return false; 2938 2939 // \todo [jarkko] Uncomment following code when the buffer mapping support is added 2940 //for (size_t ndx = 0; ndx < vao.m_arrays.length; ++ndx) 2941 // if (vao.m_arrays[ndx].enabled && vao.m_arrays[ndx].bufferBinding && vao.m_arrays[ndx].bufferBinding->isMapped) 2942 // RC_ERROR_RET(gl.INVALID_OPERATION, RC_RET_VOID); 2943 2944 if (this.conditionalSetError(this.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE, gl.INVALID_FRAMEBUFFER_OPERATION)) 2945 return false; 2946 2947 return true; 2948 }; 2949 2950 /** 2951 * Draws quads from vertex arrays 2952 * @param {number} mode GL primitive type to draw with. 2953 * @param {number} first First vertex to begin drawing with 2954 * @param {number} count How many vertices to draw (not counting vertices before first) 2955 * @param {number} instanceCount 2956 */ 2957 sglrReferenceContext.ReferenceContext.prototype.drawArraysInstanced = function(mode, first, count, instanceCount) { 2958 if (this.conditionalSetError(first < 0 || count < 0 || instanceCount < 0, gl.INVALID_VALUE)) 2959 return; 2960 2961 if (!this.predrawErrorChecks(mode)) 2962 return; 2963 2964 // All is ok 2965 this.drawQuads(mode, first, count, instanceCount); 2966 }; 2967 2968 /** 2969 * @param {number} mode GL primitive type to draw with. 2970 * @param {number} start 2971 * @param {number} end 2972 * @param {number} count How many vertices to draw (not counting vertices before first) 2973 * @param {number} type Data type 2974 * @param {number} offset 2975 */ 2976 sglrReferenceContext.ReferenceContext.prototype.drawRangeElements = function(mode, start, end, count, type, offset) { 2977 if (this.conditionalSetError(end < start, gl.INVALID_VALUE)) 2978 return; 2979 2980 this.drawElements(mode, count, type, offset); 2981 }; 2982 2983 /** 2984 * @param {number} mode GL primitive type to draw with. 2985 * @param {number} count How many vertices to draw (not counting vertices before first) 2986 * @param {number} type Data type 2987 * @param {number} offset 2988 */ 2989 sglrReferenceContext.ReferenceContext.prototype.drawElements = function(mode, count, type, offset) { 2990 this.drawElementsInstanced(mode, count, type, offset, 1); 2991 }; 2992 2993 /** 2994 * @param {number} mode GL primitive type to draw with. 2995 * @param {number} count How many vertices to draw (not counting vertices before first) 2996 * @param {number} type Data type 2997 * @param {number} offset 2998 * @param {number} instanceCount 2999 */ 3000 sglrReferenceContext.ReferenceContext.prototype.drawElementsInstanced = function(mode, count, type, offset, instanceCount) { 3001 this.drawElementsInstancedBaseVertex(mode, count, type, offset, instanceCount, 0); 3002 }; 3003 3004 /** 3005 * @param {number} mode GL primitive type to draw with. 3006 * @param {number} count How many vertices to draw (not counting vertices before first) 3007 * @param {number} type Data type 3008 * @param {number} offset 3009 * @param {number} instanceCount 3010 * @param {number} baseVertex 3011 */ 3012 sglrReferenceContext.ReferenceContext.prototype.drawElementsInstancedBaseVertex = function(mode, count, type, offset, instanceCount, baseVertex) { 3013 var vao = this.m_vertexArrayBinding; 3014 3015 if (this.conditionalSetError(type != gl.UNSIGNED_BYTE && 3016 type != gl.UNSIGNED_SHORT && 3017 type != gl.UNSIGNED_INT, gl.INVALID_ENUM)) 3018 return; 3019 if (this.conditionalSetError(count < 0 || instanceCount < 0, gl.INVALID_VALUE)) 3020 return; 3021 3022 if (!this.predrawErrorChecks(mode)) 3023 return; 3024 3025 if (this.conditionalSetError(count > 0 && !vao.m_elementArrayBufferBinding, gl.INVALID_OPERATION)) 3026 return; 3027 // All is ok 3028 var data = vao.m_elementArrayBufferBinding.getData(); 3029 var indices = new rrRenderer.DrawIndices(data, sglrReferenceUtils.mapGLIndexType(type), offset, baseVertex); 3030 3031 this.drawQuads(mode, indices, count, instanceCount); 3032 }; 3033 3034 /** 3035 * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} access 3036 * @return {Array<number>} 3037 */ 3038 sglrReferenceContext.getBufferRect = function(access) { return [0, 0, access.raw().getHeight(), access.raw().getDepth()]; }; 3039 3040 /** 3041 * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 3042 */ 3043 sglrReferenceContext.ReferenceContext.prototype.getDrawColorbuffer = function() { 3044 if (this.m_drawFramebufferBinding) 3045 return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_drawFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0)); 3046 return this.m_defaultColorbuffer; 3047 }; 3048 3049 /** 3050 * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 3051 */ 3052 sglrReferenceContext.ReferenceContext.prototype.getDrawDepthbuffer = function() { 3053 if (this.m_drawFramebufferBinding) 3054 return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_drawFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH)); 3055 return this.m_defaultDepthbuffer; 3056 }; 3057 3058 /** 3059 * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 3060 */ 3061 sglrReferenceContext.ReferenceContext.prototype.getDrawStencilbuffer = function() { 3062 if (this.m_drawFramebufferBinding) 3063 return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_drawFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL)); 3064 return this.m_defaultStencilbuffer; 3065 }; 3066 3067 /** 3068 * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 3069 */ 3070 sglrReferenceContext.ReferenceContext.prototype.getReadDepthbuffer = function() { 3071 if (this.m_readFramebufferBinding) 3072 return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_readFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH)); 3073 return this.m_defaultDepthbuffer; 3074 }; 3075 3076 /** 3077 * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} 3078 */ 3079 sglrReferenceContext.ReferenceContext.prototype.getReadStencilbuffer = function() { 3080 if (this.m_readFramebufferBinding) 3081 return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_readFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL)); 3082 return this.m_defaultStencilbuffer; 3083 }; 3084 3085 /** 3086 * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} access 3087 * @param {number} s 3088 * @param {number} x 3089 * @param {number} y 3090 * @param {number} depth 3091 */ 3092 sglrReferenceContext.writeDepthOnly = function(access, s, x, y, depth) { access.raw().setPixDepth(depth, s, x, y); }; 3093 3094 /** 3095 * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} access 3096 * @param {number} s 3097 * @param {number} x 3098 * @param {number} y 3099 * @param {number} stencil 3100 * @param {number} writeMask 3101 */ 3102 sglrReferenceContext.writeStencilOnly = function(access, s, x, y, stencil, writeMask) { 3103 /** @type {number} */ var oldVal = access.raw().getPixelInt(s, x, y)[3]; 3104 access.raw().setPixStencil((oldVal & ~writeMask) | (stencil & writeMask), s, x, y); 3105 }; 3106 3107 /** 3108 * @param {number} bits 3109 * @param {number} s 3110 * @return {number} 3111 */ 3112 sglrReferenceContext.maskStencil = function(bits, s) { return s & ((1 << bits) - 1); }; 3113 3114 /** 3115 * @param {number} buffers 3116 */ 3117 sglrReferenceContext.ReferenceContext.prototype.clear = function(buffers) { 3118 if (this.conditionalSetError((buffers & ~(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) != 0, gl.INVALID_VALUE)) 3119 return; 3120 3121 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf0 = this.getDrawColorbuffer(); 3122 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var depthBuf = this.getDrawDepthbuffer(); 3123 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var stencilBuf = this.getDrawStencilbuffer(); 3124 /** @type {boolean} */ var hasColor0 = /** @type {!boolean} */ (colorBuf0 && !colorBuf0.isEmpty()); 3125 /** @type {boolean} */ var hasDepth = /** @type {!boolean} */ (depthBuf && !depthBuf.isEmpty()); 3126 /** @type {boolean} */ var hasStencil = /** @type {!boolean} */ (stencilBuf && !stencilBuf.isEmpty()); 3127 /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff]; 3128 3129 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access; 3130 /** @type {boolean} */ var isSharedDepthStencil; 3131 3132 if (hasColor0 && (buffers & gl.COLOR_BUFFER_BIT) != 0) { 3133 /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf0)); 3134 access = colorBuf0.getSubregion(colorArea); 3135 /** @type {boolean} */ var isSRGB = colorBuf0.raw().getFormat().isSRGB(); 3136 /** @type {Array<number>} */ var c = (isSRGB && this.m_sRGBUpdateEnabled) ? tcuTextureUtil.linearToSRGB(this.m_clearColor) : this.m_clearColor; 3137 /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3]; 3138 /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3]; 3139 3140 if (!maskUsed) 3141 access.clear(c); 3142 else if (!maskZero) { 3143 for (var y = 0; y < access.raw().getDepth(); y++) 3144 for (var x = 0; x < access.raw().getHeight(); x++) 3145 for (var s = 0; s < access.getNumSamples(); s++) 3146 access.raw().setPixel(tcuTextureUtil.select(c, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y); 3147 } 3148 // else all channels masked out 3149 } 3150 3151 if (hasDepth && (buffers & gl.DEPTH_BUFFER_BIT) != 0 && this.m_depthMask) { 3152 /** @type {Array<number>} */ var depthArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(depthBuf)); 3153 access = depthBuf.getSubregion(depthArea); 3154 isSharedDepthStencil = depthBuf.raw().getFormat().order != tcuTexture.ChannelOrder.D; 3155 3156 if (isSharedDepthStencil) { 3157 // Slow path where stencil is masked out in write. 3158 for (var y = 0; y < access.raw().getDepth(); y++) 3159 for (var x = 0; x < access.raw().getHeight(); x++) 3160 for (var s = 0; s < access.getNumSamples(); s++) 3161 sglrReferenceContext.writeDepthOnly(access, s, x, y, this.m_clearDepth); 3162 } else 3163 access.clear([this.m_clearDepth, 0, 0, 0]); 3164 } 3165 3166 if (hasStencil && (buffers & gl.STENCIL_BUFFER_BIT) != 0) { 3167 /** @type {Array<number>} */ var stencilArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(stencilBuf)); 3168 access = stencilBuf.getSubregion(stencilArea); 3169 /** @type {number} */ var stencilBits = stencilBuf.raw().getFormat().getNumStencilBits(); 3170 /** @type {number} */ var stencil = sglrReferenceContext.maskStencil(stencilBits, this.m_clearStencil); 3171 isSharedDepthStencil = stencilBuf.raw().getFormat().order != tcuTexture.ChannelOrder.S; 3172 3173 if (isSharedDepthStencil || ((this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask & ((1 << stencilBits) - 1)) != ((1 << stencilBits) - 1))) { 3174 // Slow path where depth or stencil is masked out in write. 3175 for (var y = 0; y < access.raw().getDepth(); y++) 3176 for (var x = 0; x < access.raw().getHeight(); x++) 3177 for (var s = 0; s < access.getNumSamples(); s++) 3178 sglrReferenceContext.writeStencilOnly(access, s, x, y, stencil, this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask); 3179 } else 3180 access.clear([0, 0, 0, stencil]); 3181 } 3182 }; 3183 3184 /** 3185 * @param {number} buffer 3186 * @param {number} drawbuffer 3187 * @param {Array<number>} value 3188 * @throws {Error} 3189 */ 3190 sglrReferenceContext.ReferenceContext.prototype.clearBufferiv = function(buffer, drawbuffer, value) { 3191 if (this.conditionalSetError(buffer != gl.COLOR && buffer != gl.STENCIL, gl.INVALID_ENUM)) 3192 return; 3193 if (this.conditionalSetError(drawbuffer != 0, gl.INVALID_VALUE)) 3194 return; 3195 3196 /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff]; 3197 3198 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access; 3199 3200 if (buffer == gl.COLOR) { 3201 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf = this.getDrawColorbuffer(); 3202 /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3]; 3203 /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3]; 3204 3205 if (!colorBuf.isEmpty() && !maskZero) { 3206 /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf)); 3207 access = colorBuf.getSubregion(colorArea); 3208 3209 if (!maskUsed) 3210 access.clear(value); 3211 else { 3212 for (var y = 0; y < access.raw().getDepth(); y++) 3213 for (var x = 0; x < access.raw().getHeight(); x++) 3214 for (var s = 0; s < access.getNumSamples(); s++) 3215 access.raw().setPixel(tcuTextureUtil.select(value, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y); 3216 } 3217 } 3218 } else { 3219 if (buffer !== gl.STENCIL) 3220 throw new Error('Unexpected buffer type: ' + buffer); 3221 3222 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var stencilBuf = this.getDrawStencilbuffer(); 3223 3224 if (!stencilBuf.isEmpty() && this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask != 0) { 3225 /** @type {Array<number>} */ var area = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(stencilBuf)); 3226 access = stencilBuf.getSubregion(area); 3227 /** @type {number} */ var stencil = value[0]; 3228 3229 for (var y = 0; y < access.raw().getDepth(); y++) 3230 for (var x = 0; x < access.raw().getHeight(); x++) 3231 for (var s = 0; s < access.getNumSamples(); s++) 3232 sglrReferenceContext.writeStencilOnly(access, s, x, y, stencil, this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask); 3233 } 3234 } 3235 }; 3236 3237 /** 3238 * @param {number} buffer 3239 * @param {number} drawbuffer 3240 * @param {Array<number>} value 3241 * @throws {Error} 3242 */ 3243 sglrReferenceContext.ReferenceContext.prototype.clearBufferfv = function(buffer, drawbuffer, value) { 3244 if (this.conditionalSetError(buffer != gl.COLOR && buffer != gl.DEPTH, gl.INVALID_ENUM)) 3245 return; 3246 if (this.conditionalSetError(drawbuffer != 0, gl.INVALID_VALUE)) 3247 return; 3248 3249 /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff]; 3250 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access; 3251 if (buffer == gl.COLOR) { 3252 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf = this.getDrawColorbuffer(); 3253 /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3]; 3254 /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3]; 3255 3256 if (!colorBuf.isEmpty() && !maskZero) { 3257 /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf)); 3258 access = colorBuf.getSubregion(colorArea); 3259 var color = value; 3260 3261 if (this.m_sRGBUpdateEnabled && access.raw().getFormat().isSRGB()) 3262 color = tcuTextureUtil.linearToSRGB(color); 3263 3264 if (!maskUsed) 3265 access.clear(color); 3266 else { 3267 for (var y = 0; y < access.raw().getDepth(); y++) 3268 for (var x = 0; x < access.raw().getHeight(); x++) 3269 for (var s = 0; s < access.getNumSamples(); s++) 3270 access.raw().setPixel(tcuTextureUtil.select(color, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y); 3271 } 3272 } 3273 } else { 3274 if (buffer !== gl.DEPTH) 3275 throw new Error('Unexpected buffer type: ' + buffer); 3276 3277 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var depthBuf = this.getDrawDepthbuffer(); 3278 3279 if (!depthBuf.isEmpty() && this.m_depthMask) { 3280 /** @type {Array<number>} */ var area = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(depthBuf)); 3281 access = depthBuf.getSubregion(area); 3282 /** @type {number} */ var depth = value[0]; 3283 3284 for (var y = 0; y < access.raw().getDepth(); y++) 3285 for (var x = 0; x < access.raw().getHeight(); x++) 3286 for (var s = 0; s < access.getNumSamples(); s++) 3287 sglrReferenceContext.writeDepthOnly(access, s, x, y, depth); 3288 } 3289 } 3290 }; 3291 3292 /** 3293 * @param {number} buffer 3294 * @param {number} drawbuffer 3295 * @param {Array<number>} value 3296 */ 3297 sglrReferenceContext.ReferenceContext.prototype.clearBufferuiv = function(buffer, drawbuffer, value) { 3298 if (this.conditionalSetError(buffer != gl.COLOR, gl.INVALID_ENUM)) 3299 return; 3300 if (this.conditionalSetError(drawbuffer != 0, gl.INVALID_VALUE)) 3301 return; 3302 3303 /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff]; 3304 3305 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf = this.getDrawColorbuffer(); 3306 /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3]; 3307 /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3]; 3308 3309 if (!colorBuf.isEmpty() && !maskZero) { 3310 /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf)); 3311 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access = colorBuf.getSubregion(colorArea); 3312 3313 if (!maskUsed) 3314 access.clear(value); 3315 else { 3316 for (var y = 0; y < access.raw().getDepth(); y++) 3317 for (var x = 0; x < access.raw().getHeight(); x++) 3318 for (var s = 0; s < access.getNumSamples(); s++) 3319 access.raw().setPixel(tcuTextureUtil.select(value, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y); 3320 } 3321 } 3322 }; 3323 3324 /** 3325 * @param {number} buffer 3326 * @param {number} drawbuffer 3327 * @param {number} depth 3328 * @param {number} stencil 3329 */ 3330 sglrReferenceContext.ReferenceContext.prototype.clearBufferfi = function(buffer, drawbuffer, depth, stencil) { 3331 if (this.conditionalSetError(buffer != gl.DEPTH_STENCIL, gl.INVALID_ENUM)) 3332 return; 3333 this.clearBufferfv(gl.DEPTH, drawbuffer, [depth]); 3334 this.clearBufferiv(gl.STENCIL, drawbuffer, [stencil]); 3335 }; 3336 3337 /** 3338 * @param {number} target 3339 * @param {number} attachment 3340 * @param {sglrReferenceContext.TexTarget} textarget 3341 * @param {sglrReferenceContext.TextureContainer} texture 3342 * @param {number} level 3343 * @throws {Error} 3344 */ 3345 sglrReferenceContext.ReferenceContext.prototype.framebufferTexture2D = function(target, attachment, textarget, texture, level) { 3346 if (attachment == gl.DEPTH_STENCIL_ATTACHMENT) { 3347 // Attach to both depth and stencil. 3348 this.framebufferTexture2D(target, gl.DEPTH_ATTACHMENT, textarget, texture, level); 3349 this.framebufferTexture2D(target, gl.STENCIL_ATTACHMENT, textarget, texture, level); 3350 } else { 3351 /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.mapGLAttachmentPoint(attachment); 3352 /** @type {sglrReferenceContext.TexTarget} */ var fboTexTarget = sglrReferenceContext.mapGLFboTexTarget(textarget); 3353 3354 if (this.conditionalSetError(target != gl.FRAMEBUFFER && 3355 target != gl.DRAW_FRAMEBUFFER && 3356 target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM)) 3357 return; 3358 if (this.conditionalSetError(point == undefined, gl.INVALID_ENUM)) 3359 return; 3360 3361 // Select binding point. 3362 /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding; 3363 if (this.conditionalSetError(!framebufferBinding, gl.INVALID_OPERATION)) 3364 return; 3365 3366 if (texture) { 3367 if (this.conditionalSetError(level != 0, gl.INVALID_VALUE)) 3368 return; 3369 3370 if (texture.getType() == sglrReferenceContext.TextureType.TYPE_2D) { 3371 if (this.conditionalSetError(fboTexTarget != sglrReferenceContext.TexTarget.TEXTARGET_2D, gl.INVALID_OPERATION)) 3372 return; 3373 } else { 3374 if (!texture.getType() == sglrReferenceContext.TextureType.TYPE_CUBE_MAP) 3375 throw new Error('Unsupported texture type'); 3376 if (this.conditionalSetError(!deMath.deInRange32(fboTexTarget, sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X, sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z), gl.INVALID_OPERATION)) 3377 return; 3378 } 3379 } 3380 3381 /** @type {sglrReferenceContext.Attachment} */ var fboAttachment = new sglrReferenceContext.Attachment(); 3382 3383 if (texture) { 3384 fboAttachment.type = sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE; 3385 fboAttachment.object = texture; 3386 fboAttachment.texTarget = fboTexTarget; 3387 fboAttachment.level = level; 3388 } 3389 framebufferBinding.setAttachment(point, fboAttachment); 3390 } 3391 }; 3392 3393 /** 3394 * @param {number} target 3395 * @param {number} attachment 3396 * @param {sglrReferenceContext.TextureContainer} texture 3397 * @param {number} level 3398 * @param {number} layer 3399 * @throws {Error} 3400 */ 3401 sglrReferenceContext.ReferenceContext.prototype.framebufferTextureLayer = function(target, attachment, texture, level, layer) { 3402 if (attachment == gl.DEPTH_STENCIL_ATTACHMENT) { 3403 // Attach to both depth and stencil. 3404 this.framebufferTextureLayer(target, gl.DEPTH_ATTACHMENT, texture, level, layer); 3405 this.framebufferTextureLayer(target, gl.STENCIL_ATTACHMENT, texture, level, layer); 3406 } else { 3407 /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.mapGLAttachmentPoint(attachment); 3408 3409 if (this.conditionalSetError(target != gl.FRAMEBUFFER && 3410 target != gl.DRAW_FRAMEBUFFER && 3411 target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM)) 3412 return; 3413 if (this.conditionalSetError(point === undefined, gl.INVALID_ENUM)) 3414 return; 3415 3416 // Select binding point. 3417 /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding; 3418 if (this.conditionalSetError(!framebufferBinding, gl.INVALID_OPERATION)) 3419 return; 3420 3421 if (texture) { 3422 if (this.conditionalSetError(level != 0, gl.INVALID_VALUE)) 3423 return; 3424 3425 if (this.conditionalSetError(texture.getType() != sglrReferenceContext.TextureType.TYPE_2D_ARRAY && 3426 texture.getType() != sglrReferenceContext.TextureType.TYPE_3D && 3427 texture.getType() != sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY, gl.INVALID_OPERATION)) 3428 return; 3429 3430 if (texture.getType() == sglrReferenceContext.TextureType.TYPE_2D_ARRAY || texture.getType() == sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY) { 3431 if (this.conditionalSetError((layer < 0) || (layer >= gl.MAX_ARRAY_TEXTURE_LAYERS), gl.INVALID_VALUE)) 3432 return; 3433 if (this.conditionalSetError((level < 0) || (level > Math.floor(Math.log2(gl.MAX_TEXTURE_SIZE))), gl.INVALID_VALUE)) 3434 return; 3435 } else if (texture.getType() == sglrReferenceContext.TextureType.TYPE_3D) { 3436 if (this.conditionalSetError((layer < 0) || (layer >= gl.MAX_3D_TEXTURE_SIZE), gl.INVALID_VALUE)) 3437 return; 3438 if (this.conditionalSetError((level < 0) || (level > Math.floor(Math.log2(gl.MAX_3D_TEXTURE_SIZE))), gl.INVALID_VALUE)) 3439 return; 3440 } 3441 } 3442 3443 /** @type {sglrReferenceContext.Attachment} */ var fboAttachment = new sglrReferenceContext.Attachment(); 3444 3445 if (texture) { 3446 fboAttachment.type = sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE; 3447 fboAttachment.object = texture; 3448 fboAttachment.texTarget = sglrReferenceContext.texLayeredTypeToTarget(texture.getType()); 3449 fboAttachment.level = level; 3450 fboAttachment.layer = layer; 3451 } 3452 framebufferBinding.setAttachment(point, fboAttachment); 3453 3454 } 3455 }; 3456 3457 /** 3458 * @param {number} target 3459 * @param {number} attachment 3460 * @param {number} renderbuffertarget 3461 * @param {sglrReferenceContext.Renderbuffer} renderbuffer 3462 */ 3463 sglrReferenceContext.ReferenceContext.prototype.framebufferRenderbuffer = function(target, attachment, renderbuffertarget, renderbuffer) { 3464 if (attachment == gl.DEPTH_STENCIL_ATTACHMENT) { 3465 // Attach both to depth and stencil. 3466 this.framebufferRenderbuffer(target, gl.DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer); 3467 this.framebufferRenderbuffer(target, gl.STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer); 3468 } else { 3469 /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.mapGLAttachmentPoint(attachment); 3470 3471 if (this.conditionalSetError(target != gl.FRAMEBUFFER && 3472 target != gl.DRAW_FRAMEBUFFER && 3473 target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM)) 3474 return; 3475 if (this.conditionalSetError(point == undefined, gl.INVALID_ENUM)) 3476 return; 3477 3478 // Select binding point. 3479 /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding; 3480 if (this.conditionalSetError(!framebufferBinding, gl.INVALID_OPERATION)) 3481 return; 3482 3483 if (renderbuffer) { 3484 if (this.conditionalSetError(renderbuffertarget != gl.RENDERBUFFER, gl.INVALID_ENUM)) 3485 return; 3486 } 3487 3488 /** @type {sglrReferenceContext.Attachment} */ var fboAttachment = new sglrReferenceContext.Attachment(); 3489 3490 if (renderbuffer) { 3491 fboAttachment.type = sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_RENDERBUFFER; 3492 fboAttachment.object = renderbuffer; 3493 } 3494 framebufferBinding.setAttachment(point, fboAttachment); 3495 } 3496 }; 3497 3498 /** 3499 * @param {number} target 3500 * @param {number} internalformat 3501 * @param {number} width 3502 * @param {number} height 3503 */ 3504 sglrReferenceContext.ReferenceContext.prototype.renderbufferStorage = function(target, internalformat, width, height) { 3505 /** @type {tcuTexture.TextureFormat} */ var format = gluTextureUtil.mapGLInternalFormat(internalformat); 3506 3507 if (this.conditionalSetError(target != gl.RENDERBUFFER, gl.INVALID_ENUM)) 3508 return; 3509 if (this.conditionalSetError(!this.m_renderbufferBinding, gl.INVALID_OPERATION)) 3510 return; 3511 if (this.conditionalSetError(!deMath.deInRange32(width, 0, this.m_limits.maxRenderbufferSize) || 3512 !deMath.deInRange32(height, 0, this.m_limits.maxRenderbufferSize), 3513 gl.INVALID_OPERATION)) 3514 return; 3515 if (this.conditionalSetError(!format, gl.INVALID_ENUM)) 3516 return; 3517 3518 this.m_renderbufferBinding.setStorage(format, width, height); 3519 }; 3520 3521 /** 3522 * @param {number} target 3523 * @param {number} samples 3524 * @param {number} internalformat 3525 * @param {number} width 3526 * @param {number} height 3527 */ 3528 sglrReferenceContext.ReferenceContext.prototype.renderbufferStorageMultisample = function(target, samples, internalformat, width, height) { 3529 this.renderbufferStorage(target, internalformat, width, height); 3530 }; 3531 3532 /** 3533 * @param {rrRenderer.PrimitiveType} derivedType 3534 * @return {rrRenderer.PrimitiveType} 3535 * @throws {Error} 3536 */ 3537 sglrReferenceContext.getPrimitiveBaseType = function(derivedType) { 3538 switch (derivedType) { 3539 case rrRenderer.PrimitiveType.TRIANGLES: 3540 case rrRenderer.PrimitiveType.TRIANGLE_STRIP: 3541 case rrRenderer.PrimitiveType.TRIANGLE_FAN: 3542 return rrRenderer.PrimitiveType.TRIANGLES; 3543 3544 case rrRenderer.PrimitiveType.LINES: 3545 case rrRenderer.PrimitiveType.LINE_STRIP: 3546 case rrRenderer.PrimitiveType.LINE_LOOP: 3547 return rrRenderer.PrimitiveType.LINES; 3548 3549 case rrRenderer.PrimitiveType.POINTS: 3550 return rrRenderer.PrimitiveType.POINTS; 3551 3552 default: 3553 throw new Error('Unrecognized primitive type:' + derivedType); 3554 } 3555 }; 3556 3557 /** 3558 * createProgram 3559 * @param {sglrShaderProgram.ShaderProgram} program 3560 * @return {sglrShaderProgram.ShaderProgram} 3561 */ 3562 sglrReferenceContext.ReferenceContext.prototype.createProgram = function(program) { 3563 return program; 3564 }; 3565 3566 /** 3567 * deleteProgram 3568 * @param {sglrShaderProgram.ShaderProgram} program 3569 */ 3570 sglrReferenceContext.ReferenceContext.prototype.deleteProgram = function(program) {}; 3571 3572 /** 3573 * @param {sglrShaderProgram.ShaderProgram} program 3574 */ 3575 sglrReferenceContext.ReferenceContext.prototype.useProgram = function(program) { 3576 this.m_currentProgram = program; 3577 }; 3578 3579 /** 3580 * Draws quads from vertex arrays 3581 * @param {number} primitive GL primitive type to draw with. 3582 * @param {number} first First vertex to begin drawing with 3583 * @param {number} count How many vertices to draw (not counting vertices before first) 3584 */ 3585 sglrReferenceContext.ReferenceContext.prototype.drawArrays = function(primitive, first, count) { 3586 this.drawQuads(primitive, first, count, 1); 3587 }; 3588 3589 /** 3590 * Draws quads from vertex arrays 3591 * @param {number} primitive GL primitive type to draw with. 3592 * @param {(number|rrRenderer.DrawIndices)} first First vertex to begin drawing with 3593 * @param {number} count Number of vertices 3594 * @param {number=} instances Number of instances 3595 */ 3596 sglrReferenceContext.ReferenceContext.prototype.drawQuads = function(primitive, first, count, instances) { 3597 // undefined results 3598 if (!this.m_currentProgram) 3599 return; 3600 3601 if (typeof instances === 'undefined') 3602 instances = 1; 3603 3604 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf0 = this.getDrawColorbuffer(); 3605 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var depthBuf = this.getDrawDepthbuffer(); 3606 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var stencilBuf = this.getDrawStencilbuffer(); 3607 /** @type {boolean} */ var hasStencil = /** @type {!boolean} */ (stencilBuf && !stencilBuf.isEmpty()); 3608 /** @type {number} */ var stencilBits = (hasStencil) ? stencilBuf.raw().getFormat().getNumStencilBits() : 0; 3609 3610 /** @type {rrRenderer.RenderTarget} */ var renderTarget = new rrRenderer.RenderTarget(colorBuf0, 3611 depthBuf, 3612 stencilBuf); 3613 /** @type {sglrShaderProgram.ShaderProgram} */ var program = this.m_currentProgram; 3614 3615 /*new rrRenderer.Program( 3616 * this.m_currentProgram.getVertexShader(), 3617 * this.m_currentProgram.getFragmentShader());*/ 3618 3619 /** @type {rrRenderState.ViewportState} */ var viewportState = new rrRenderState.ViewportState(colorBuf0); 3620 /** @type {rrRenderState.RenderState} */ var state = new rrRenderState.RenderState(viewportState); 3621 3622 /** @type {Array<rrVertexAttrib.VertexAttrib>} */ var vertexAttribs = []; 3623 3624 // Gen state 3625 /** @type {rrRenderer.PrimitiveType} */ var baseType = rrRenderer.PrimitiveType.TRIANGLES; 3626 /** @type {boolean} */ var polygonOffsetEnabled = 3627 (baseType == rrRenderer.PrimitiveType.TRIANGLES) ? 3628 (this.m_polygonOffsetFillEnabled) : 3629 (false); 3630 3631 //state.cullMode = m_cullMode 3632 3633 state.fragOps.scissorTestEnabled = this.m_scissorEnabled; 3634 state.fragOps.scissorRectangle = new rrRenderState.WindowRectangle(this.m_scissorBox); 3635 3636 state.fragOps.numStencilBits = stencilBits; 3637 state.fragOps.stencilTestEnabled = this.m_stencilTestEnabled; 3638 3639 for (var key in rrDefs.FaceType) { 3640 /** @type {number} */ var faceType = rrDefs.FaceType[key]; 3641 state.fragOps.stencilStates[faceType].compMask = this.m_stencil[faceType].opMask; 3642 state.fragOps.stencilStates[faceType].writeMask = this.m_stencil[faceType].writeMask; 3643 state.fragOps.stencilStates[faceType].ref = this.m_stencil[faceType].ref; 3644 state.fragOps.stencilStates[faceType].func = sglrReferenceUtils.mapGLTestFunc(this.m_stencil[faceType].func); 3645 state.fragOps.stencilStates[faceType].sFail = sglrReferenceUtils.mapGLStencilOp(this.m_stencil[faceType].opStencilFail); 3646 state.fragOps.stencilStates[faceType].dpFail = sglrReferenceUtils.mapGLStencilOp(this.m_stencil[faceType].opDepthFail); 3647 state.fragOps.stencilStates[faceType].dpPass = sglrReferenceUtils.mapGLStencilOp(this.m_stencil[faceType].opDepthPass); 3648 } 3649 3650 state.fragOps.depthTestEnabled = this.m_depthTestEnabled; 3651 state.fragOps.depthFunc = sglrReferenceUtils.mapGLTestFunc(this.m_depthFunc); 3652 state.fragOps.depthMask = this.m_depthMask; 3653 3654 state.fragOps.blendMode = this.m_blendEnabled ? rrRenderState.BlendMode.STANDARD : rrRenderState.BlendMode.NONE; 3655 state.fragOps.blendRGBState.equation = sglrReferenceUtils.mapGLBlendEquation(this.m_blendModeRGB); 3656 state.fragOps.blendRGBState.srcFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorSrcRGB); 3657 state.fragOps.blendRGBState.dstFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorDstRGB); 3658 state.fragOps.blendAState.equation = sglrReferenceUtils.mapGLBlendEquation(this.m_blendModeAlpha); 3659 state.fragOps.blendAState.srcFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorSrcAlpha); 3660 state.fragOps.blendAState.dstFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorDstAlpha); 3661 state.fragOps.blendColor = this.m_blendColor; 3662 3663 state.fragOps.colorMask = this.m_colorMask; 3664 3665 state.viewport.rect = new rrRenderState.WindowRectangle(this.m_viewport); 3666 state.viewport.zn = this.m_depthRangeNear; 3667 state.viewport.zf = this.m_depthRangeFar; 3668 3669 //state.point.pointSize = this.m_pointSize; 3670 state.line.lineWidth = this.m_lineWidth; 3671 3672 state.fragOps.polygonOffsetEnabled = polygonOffsetEnabled; 3673 state.fragOps.polygonOffsetFactor = this.m_polygonOffsetFactor; 3674 state.fragOps.polygonOffsetUnits = this.m_polygonOffsetUnits; 3675 3676 state.provokingVertexConvention = (this.m_provokingFirstVertexConvention) ? (rrDefs.ProvokingVertex.PROVOKINGVERTEX_FIRST) : (rrDefs.ProvokingVertex.PROVOKINGVERTEX_LAST); 3677 3678 // gen attributes 3679 /** @type {sglrReferenceContext.VertexArray} */ var vao = this.m_vertexArrayBinding; 3680 for (var ndx = 0; ndx < vao.m_arrays.length; ++ndx) { 3681 vertexAttribs[ndx] = new rrVertexAttrib.VertexAttrib(); 3682 if (!vao.m_arrays[ndx].enabled) { 3683 vertexAttribs[ndx].type = rrVertexAttrib.VertexAttribType.DONT_CARE; // reading with wrong type is allowed, but results are undefined 3684 vertexAttribs[ndx].generic = this.m_currentAttribs[ndx]; 3685 } else { 3686 vertexAttribs[ndx].type = (vao.m_arrays[ndx].integer) ? 3687 (sglrReferenceUtils.mapGLPureIntegerVertexAttributeType(vao.m_arrays[ndx].type)) : 3688 (sglrReferenceUtils.mapGLFloatVertexAttributeType(vao.m_arrays[ndx].type, vao.m_arrays[ndx].normalized, vao.m_arrays[ndx].size)); 3689 vertexAttribs[ndx].size = sglrReferenceUtils.mapGLSize(vao.m_arrays[ndx].size); 3690 vertexAttribs[ndx].stride = vao.m_arrays[ndx].stride; 3691 vertexAttribs[ndx].instanceDivisor = vao.m_arrays[ndx].divisor; 3692 vertexAttribs[ndx].pointer = vao.m_arrays[ndx].bufferBinding.getData(); 3693 vertexAttribs[ndx].offset = vao.m_arrays[ndx].offset; 3694 vertexAttribs[ndx].componentCount = vao.m_arrays[ndx].size; 3695 } 3696 } 3697 3698 // Set shader samplers 3699 for (var uniformNdx = 0; uniformNdx < this.m_currentProgram.m_uniforms.length; ++uniformNdx) { 3700 /** @type {number} */ var texNdx = this.m_currentProgram.m_uniforms[uniformNdx].value[0]; 3701 3702 switch (this.m_currentProgram.m_uniforms[uniformNdx].type) { 3703 case gluShaderUtil.DataType.SAMPLER_2D: 3704 case gluShaderUtil.DataType.UINT_SAMPLER_2D: 3705 case gluShaderUtil.DataType.INT_SAMPLER_2D: { 3706 /** @type {sglrReferenceContext.Texture2D} */ var tex; 3707 3708 if (texNdx >= 0 && texNdx < this.m_textureUnits.length) 3709 tex = /** @type {sglrReferenceContext.Texture2D} */ (this.m_textureUnits[texNdx].tex2DBinding.texture); 3710 3711 if (tex && tex.isComplete()) { 3712 tex.updateView(); 3713 this.m_currentProgram.m_uniforms[uniformNdx].sampler = tex; 3714 } else 3715 this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTex2D.texture; 3716 3717 break; 3718 } 3719 case gluShaderUtil.DataType.SAMPLER_CUBE: 3720 case gluShaderUtil.DataType.UINT_SAMPLER_CUBE: 3721 case gluShaderUtil.DataType.INT_SAMPLER_CUBE: { 3722 /** @type {sglrReferenceContext.TextureCube} */ var texCube; 3723 3724 if (texNdx >= 0 && texNdx < this.m_textureUnits.length) 3725 texCube = /** @type {sglrReferenceContext.TextureCube} */ (this.m_textureUnits[texNdx].texCubeBinding.texture); 3726 3727 if (texCube && texCube.isComplete()) { 3728 texCube.updateView(); 3729 this.m_currentProgram.m_uniforms[uniformNdx].sampler = texCube; 3730 } else 3731 this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTexCube.texture; 3732 3733 break; 3734 } 3735 case gluShaderUtil.DataType.SAMPLER_2D_ARRAY: 3736 case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY: 3737 case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY: { 3738 /** @type {sglrReferenceContext.Texture2DArray} */ var tex2DArray; 3739 3740 if (texNdx >= 0 && texNdx < this.m_textureUnits.length) 3741 tex2DArray = /** @type {sglrReferenceContext.Texture2DArray} */ (this.m_textureUnits[texNdx].tex2DArrayBinding.texture); 3742 3743 if (tex2DArray && tex2DArray.isComplete()) { 3744 tex2DArray.updateView(); 3745 this.m_currentProgram.m_uniforms[uniformNdx].sampler = tex2DArray; 3746 } else 3747 this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTex2DArray.texture; 3748 3749 break; 3750 } 3751 case gluShaderUtil.DataType.SAMPLER_3D: 3752 case gluShaderUtil.DataType.UINT_SAMPLER_3D: 3753 case gluShaderUtil.DataType.INT_SAMPLER_3D: { 3754 /** @type {sglrReferenceContext.Texture3D} */ var tex3D; 3755 3756 if (texNdx >= 0 && texNdx < this.m_textureUnits.length) 3757 tex3D = /** @type {sglrReferenceContext.Texture3D} */ (this.m_textureUnits[texNdx].tex3DBinding.texture); 3758 3759 if (tex3D && tex3D.isComplete()) { 3760 tex3D.updateView(); 3761 this.m_currentProgram.m_uniforms[uniformNdx].sampler = tex3D; 3762 } else 3763 this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTex3D.texture; 3764 3765 break; 3766 } 3767 /* TODO: Port 3768 case gluShaderUtil.DataType.SAMPLER_CUBE_ARRAY: 3769 case gluShaderUtil.DataType.UINT_SAMPLER_CUBE_ARRAY: 3770 case gluShaderUtil.DataType.INT_SAMPLER_CUBE_ARRAY:{ 3771 rc::TextureCubeArray* tex = DE_NULL; 3772 3773 if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.length) 3774 tex = (this.m_textureUnits[texNdx].texCubeArrayBinding) ? (this.m_textureUnits[texNdx].texCubeArrayBinding) : (&this.m_textureUnits[texNdx].defaultCubeArrayTex); 3775 3776 if (tex && tex.isComplete()) { 3777 tex.updateView(); 3778 this.m_currentProgram.m_uniforms[uniformNdx].sampler.texCubeArray = tex; 3779 } else 3780 this.m_currentProgram.m_uniforms[uniformNdx].sampler.texCubeArray = &this.m_emptyTexCubeArray; 3781 3782 break; 3783 } 3784 */ 3785 default: 3786 // nothing 3787 break; 3788 } 3789 } 3790 3791 var primitiveType = sglrReferenceUtils.mapGLPrimitiveType(primitive); 3792 3793 var renderFunction = rrRenderer.drawTriangles; 3794 if (primitiveType == rrRenderer.PrimitiveType.LINES || 3795 primitiveType == rrRenderer.PrimitiveType.LINE_STRIP || 3796 primitiveType == rrRenderer.PrimitiveType.LINE_LOOP) 3797 renderFunction = rrRenderer.drawLines; 3798 else if (primitiveType == rrRenderer.PrimitiveType.POINTS) 3799 renderFunction = rrRenderer.drawPoints; 3800 3801 for (var instanceID = 0; instanceID < instances; instanceID++) 3802 renderFunction(state, renderTarget, program, vertexAttribs, primitiveType, first, count, instanceID); 3803 }; 3804 3805 /** 3806 * @param {Array<number>} rect 3807 * @return {boolean} 3808 */ 3809 sglrReferenceContext.isEmpty = function(rect) { return rect[2] == 0 || rect[3] == 0; }; 3810 3811 /** 3812 * @param {number} mask 3813 * @param {Array<number>} srcRect 3814 * @param {Array<number>} dstRect 3815 * @param {boolean} flipX 3816 * @param {boolean} flipY 3817 * @throws {Error} 3818 */ 3819 sglrReferenceContext.ReferenceContext.prototype.blitResolveMultisampleFramebuffer = function(mask, srcRect, dstRect, flipX, flipY) { 3820 throw new Error('Unimplemented'); 3821 }; 3822 3823 /** 3824 * @param {number} srcX0 3825 * @param {number} srcY0 3826 * @param {number} srcX1 3827 * @param {number} srcY1 3828 * @param {number} dstX0 3829 * @param {number} dstY0 3830 * @param {number} dstX1 3831 * @param {number} dstY1 3832 * @param {number} mask 3833 * @param {number} filter 3834 */ 3835 sglrReferenceContext.ReferenceContext.prototype.blitFramebuffer = function(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) { 3836 // p0 in inclusive, p1 exclusive. 3837 // Negative width/height means swap. 3838 /** @type {boolean} */ var swapSrcX = srcX1 < srcX0; 3839 /** @type {boolean} */ var swapSrcY = srcY1 < srcY0; 3840 /** @type {boolean} */ var swapDstX = dstX1 < dstX0; 3841 /** @type {boolean} */ var swapDstY = dstY1 < dstY0; 3842 /** @type {number} */ var srcW = Math.abs(srcX1 - srcX0); 3843 /** @type {number} */ var srcH = Math.abs(srcY1 - srcY0); 3844 /** @type {number} */ var dstW = Math.abs(dstX1 - dstX0); 3845 /** @type {number} */ var dstH = Math.abs(dstY1 - dstY0); 3846 /** @type {boolean} */ var scale = srcW != dstW || srcH != dstH; 3847 /** @type {number} */ var srcOriginX = swapSrcX ? srcX1 : srcX0; 3848 /** @type {number} */ var srcOriginY = swapSrcY ? srcY1 : srcY0; 3849 /** @type {number} */ var dstOriginX = swapDstX ? dstX1 : dstX0; 3850 /** @type {number} */ var dstOriginY = swapDstY ? dstY1 : dstY0; 3851 /** @type {Array<number>} */ var srcRect = [srcOriginX, srcOriginY, srcW, srcH]; 3852 /** @type {Array<number>} */ var dstRect = [dstOriginX, dstOriginY, dstW, dstH]; 3853 3854 if (this.conditionalSetError(filter != gl.NEAREST && filter != gl.LINEAR, gl.INVALID_ENUM)) 3855 return; 3856 if (this.conditionalSetError((mask & (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) != 0 && filter != gl.NEAREST, gl.INVALID_OPERATION)) 3857 return; 3858 3859 // Validate that both targets are complete. 3860 if (this.conditionalSetError(this.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE || 3861 this.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE, gl.INVALID_OPERATION)) 3862 return; 3863 3864 // Check samples count is valid 3865 if (this.conditionalSetError(this.getDrawColorbuffer().getNumSamples() != 1, gl.INVALID_OPERATION)) 3866 return; 3867 3868 // Check size restrictions of multisampled case 3869 if (this.getReadColorbuffer().getNumSamples() != 1) { 3870 // Src and Dst rect dimensions must be the same 3871 if (this.conditionalSetError(srcW != dstW || srcH != dstH, gl.INVALID_OPERATION)) 3872 return; 3873 3874 // sglrReferenceContext.Framebuffer formats must match 3875 if (mask & gl.COLOR_BUFFER_BIT) 3876 if (this.conditionalSetError(this.getReadColorbuffer().raw().getFormat() != this.getDrawColorbuffer().raw().getFormat(), gl.INVALID_OPERATION)) 3877 return; 3878 if (mask & gl.DEPTH_BUFFER_BIT) 3879 if (this.conditionalSetError(this.getReadDepthbuffer().raw().getFormat() != this.getDrawDepthbuffer().raw().getFormat(), gl.INVALID_OPERATION)) 3880 return; 3881 if (mask & gl.STENCIL_BUFFER_BIT) 3882 if (this.conditionalSetError(this.getReadStencilbuffer().raw().getFormat() != this.getDrawStencilbuffer().raw().getFormat(), gl.INVALID_OPERATION)) 3883 return; 3884 } 3885 3886 // Compute actual source rect. 3887 srcRect = (mask & gl.COLOR_BUFFER_BIT) ? deMath.intersect(srcRect, sglrReferenceContext.getBufferRect(this.getReadColorbuffer())) : srcRect; 3888 srcRect = (mask & gl.DEPTH_BUFFER_BIT) ? deMath.intersect(srcRect, sglrReferenceContext.getBufferRect(this.getReadDepthbuffer())) : srcRect; 3889 srcRect = (mask & gl.STENCIL_BUFFER_BIT) ? deMath.intersect(srcRect, sglrReferenceContext.getBufferRect(this.getReadStencilbuffer())) : srcRect; 3890 3891 // Compute destination rect. 3892 dstRect = (mask & gl.COLOR_BUFFER_BIT) ? deMath.intersect(dstRect, sglrReferenceContext.getBufferRect(this.getDrawColorbuffer())) : dstRect; 3893 dstRect = (mask & gl.DEPTH_BUFFER_BIT) ? deMath.intersect(dstRect, sglrReferenceContext.getBufferRect(this.getDrawDepthbuffer())) : dstRect; 3894 dstRect = (mask & gl.STENCIL_BUFFER_BIT) ? deMath.intersect(dstRect, sglrReferenceContext.getBufferRect(this.getDrawStencilbuffer())) : dstRect; 3895 dstRect = this.m_scissorEnabled ? deMath.intersect(dstRect, this.m_scissorBox) : dstRect; 3896 3897 if (sglrReferenceContext.isEmpty(srcRect) || sglrReferenceContext.isEmpty(dstRect)) 3898 return; // Don't attempt copy. 3899 3900 // Multisampled read buffer is a special case 3901 if (this.getReadColorbuffer().getNumSamples() != 1) { 3902 /** @type {boolean} */ var swapX = swapSrcX ^ swapDstX ? true : false; 3903 /** @type {boolean} */ var swapY = swapSrcY ^ swapDstY ? true : false; 3904 var error = this.blitResolveMultisampleFramebuffer(mask, srcRect, dstRect, swapX, swapY); 3905 3906 if (error != gl.NO_ERROR) 3907 this.setError(error); 3908 3909 return; 3910 } 3911 3912 // \note Multisample pixel buffers can now be accessed like non-multisampled because multisample read buffer case is already handled. => sample count must be 1 3913 3914 // Coordinate transformation: 3915 // Dst offset space -> dst rectangle space -> src rectangle space -> src offset space. 3916 /** @type {tcuMatrix.Matrix} */ var matrix = tcuMatrixUtil.translationMatrix([srcX0 - srcRect[0], srcY0 - srcRect[1]]); 3917 matrix = tcuMatrix.multiply(matrix, tcuMatrix.matrixFromVector(3, 3, [(srcX1 - srcX0) / (dstX1 - dstX0), (srcY1 - srcY0) / (dstY1 - dstY0), 1])); 3918 matrix = tcuMatrix.multiply(matrix, tcuMatrixUtil.translationMatrix([dstRect[0] - dstX0, dstRect[1] - dstY0])); 3919 3920 /** 3921 * @param {number} x 3922 * @param {number} y 3923 * @return {number} 3924 */ 3925 var transform = function(x, y) { return matrix.get(x, y); }; 3926 3927 /** @type {number} */ var dX; 3928 /** @type {number} */ var dY; 3929 /** @type {number} */ var sX; 3930 /** @type {number} */ var sY; 3931 /** @type {tcuTexture.PixelBufferAccess|rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src; 3932 /** @type {tcuTexture.PixelBufferAccess|rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var dst; 3933 3934 if (mask & gl.COLOR_BUFFER_BIT) { 3935 src = tcuTextureUtil.getSubregion(this.getReadColorbuffer().toSinglesampleAccess(), srcRect[0], srcRect[1], 0, srcRect[2], srcRect[3], 1); 3936 dst = tcuTextureUtil.getSubregion(this.getDrawColorbuffer().toSinglesampleAccess(), dstRect[0], dstRect[1], 0, dstRect[2], dstRect[3], 1); 3937 /** @type {tcuTexture.TextureChannelClass} */ var dstClass = tcuTexture.getTextureChannelClass(dst.getFormat().type); 3938 /** @type {boolean} */ var dstIsFloat = dstClass == tcuTexture.TextureChannelClass.FLOATING_POINT || 3939 dstClass == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT || 3940 dstClass == tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT; 3941 /** @type {tcuTexture.FilterMode} */ var sFilter = (scale && filter == gl.LINEAR) ? tcuTexture.FilterMode.LINEAR : tcuTexture.FilterMode.NEAREST; 3942 /** @type {tcuTexture.Sampler} */ var sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, 3943 sFilter, sFilter, 0.0 /* lod threshold */, false /* non-normalized coords */); 3944 /** @type {boolean} */ var srcIsSRGB = src.getFormat().order == tcuTexture.ChannelOrder.sRGB || src.getFormat().order == tcuTexture.ChannelOrder.sRGBA; 3945 /** @type {boolean} */ var dstIsSRGB = dst.getFormat().order == tcuTexture.ChannelOrder.sRGB || dst.getFormat().order == tcuTexture.ChannelOrder.sRGBA; 3946 /** @type {boolean} */ var convertSRGB = this.m_sRGBUpdateEnabled; 3947 3948 // \note We don't check for unsupported conversions, unlike spec requires. 3949 3950 for (var yo = 0; yo < dstRect[3]; yo++) { 3951 for (var xo = 0; xo < dstRect[2]; xo++) { 3952 dX = xo + 0.5; 3953 dY = yo + 0.5; 3954 3955 // \note Only affine part is used. 3956 sX = transform(0, 0) * dX + transform(0, 1) * dY + transform(0, 2); 3957 sY = transform(1, 0) * dX + transform(1, 1) * dY + transform(1, 2); 3958 3959 // do not copy pixels outside the modified source region (modified by buffer intersection) 3960 if (sX < 0.0 || sX >= srcRect[2] || 3961 sY < 0.0 || sY >= srcRect[3]) 3962 continue; 3963 3964 if (dstIsFloat || srcIsSRGB || filter == tcuTexture.FilterMode.LINEAR) { 3965 /** @type {Array<number>} */ var p = src.sample2D(sampler, sampler.minFilter, sX, sY, 0); 3966 dst.setPixel((dstIsSRGB && convertSRGB) ? tcuTextureUtil.linearToSRGB(p) : p, xo, yo); 3967 } else 3968 dst.setPixelInt(src.getPixelInt(Math.floor(sX), Math.floor(sY)), xo, yo); 3969 } 3970 } 3971 } 3972 3973 if ((mask & gl.DEPTH_BUFFER_BIT) && this.m_depthMask) { 3974 src = this.getReadDepthbuffer().getSubregion(srcRect); 3975 dst = this.getDrawDepthbuffer().getSubregion(dstRect); 3976 3977 for (var yo = 0; yo < dstRect[3]; yo++) { 3978 for (var xo = 0; xo < dstRect[2]; xo++) { 3979 var sampleNdx = 0; // multisample read buffer case is already handled 3980 3981 dX = xo + 0.5; 3982 dY = yo + 0.5; 3983 sX = transform(0, 0) * dX + transform(0, 1) * dY + transform(0, 2); 3984 sY = transform(1, 0) * dX + transform(1, 1) * dY + transform(1, 2); 3985 3986 sglrReferenceContext.writeDepthOnly(dst, sampleNdx, xo, yo, src.raw().getPixel(sampleNdx, Math.floor(sX), Math.floor(sY))[0]); 3987 } 3988 } 3989 } 3990 3991 if (mask & gl.STENCIL_BUFFER_BIT) { 3992 src = this.getReadStencilbuffer().getSubregion(srcRect); 3993 dst = this.getDrawStencilbuffer().getSubregion(dstRect); 3994 3995 for (var yo = 0; yo < dstRect[3]; yo++) { 3996 for (var xo = 0; xo < dstRect[2]; xo++) { 3997 var sampleNdx = 0; // multisample read buffer case is already handled 3998 3999 dX = xo + 0.5; 4000 dY = yo + 0.5; 4001 sX = transform(0, 0) * dX + transform(0, 1) * dY + transform(0, 2); 4002 sY = transform(1, 0) * dX + transform(1, 1) * dY + transform(1, 2); 4003 4004 sglrReferenceContext.writeStencilOnly(dst, sampleNdx, xo, yo, src.raw().getPixelInt(sampleNdx, Math.floor(sX), Math.floor(sY))[3], this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask); 4005 } 4006 } 4007 } 4008 }; 4009 4010 /** 4011 * @param {number} internalFormat 4012 * @return {tcuTexture.TextureFormat} 4013 */ 4014 sglrReferenceContext.mapInternalFormat = function(internalFormat) { 4015 switch (internalFormat) { 4016 case gl.ALPHA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.A, tcuTexture.ChannelType.UNORM_INT8); 4017 case gl.LUMINANCE: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.L, tcuTexture.ChannelType.UNORM_INT8); 4018 case gl.LUMINANCE_ALPHA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.LA, tcuTexture.ChannelType.UNORM_INT8); 4019 case gl.RGB: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8); 4020 case gl.RGBA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8); 4021 4022 default: 4023 return gluTextureUtil.mapGLInternalFormat(internalFormat); 4024 } 4025 }; 4026 4027 /** 4028 * @param {tcuTexture.PixelBufferAccess} dst 4029 * @param {tcuTexture.ConstPixelBufferAccess} src 4030 */ 4031 sglrReferenceContext.depthValueFloatClampCopy = function(dst, src) { 4032 /** @type {number} */ var width = dst.getWidth(); 4033 /** @type {number} */ var height = dst.getHeight(); 4034 /** @type {number} */ var depth = dst.getDepth(); 4035 4036 DE_ASSERT(src.getWidth() == width && src.getHeight() == height && src.getDepth() == depth); 4037 4038 // clamping copy 4039 for (var z = 0; z < depth; z++) 4040 for (var y = 0; y < height; y++) 4041 for (var x = 0; x < width; x++) { 4042 /** @type {Array<number>} */ var data = src.getPixel(x, y, z); 4043 dst.setPixel([deMath.clamp(data[0], 0.0, 1.0), data[1], data[2], data[3]], x, y, z); 4044 } 4045 }; 4046 4047 /** 4048 * @param {number} target 4049 * @param {number} level 4050 * @param {number} internalFormat 4051 * @param {number} width 4052 * @param {number} height 4053 */ 4054 sglrReferenceContext.ReferenceContext.prototype.texImage2DDelegate = function (target, level, internalFormat, width, height) { 4055 var format; 4056 var dataType; 4057 4058 switch (internalFormat) 4059 { 4060 case gl.ALPHA: 4061 case gl.LUMINANCE: 4062 case gl.LUMINANCE_ALPHA: 4063 case gl.RGB: 4064 case gl.RGBA: 4065 format = internalFormat; 4066 dataType = GL.UNSIGNED_BYTE; 4067 break; 4068 default: 4069 { 4070 var transferFmt = gluTextureUtil.getTransferFormat(gluTextureUtil.mapGLInternalFormat(internalFormat)); 4071 format = transferFmt.format; 4072 dataType = transferFmt.dataType; 4073 break; 4074 } 4075 } 4076 this.texImage2D(target, level, internalFormat, width, height, 0, format, dataType, null); 4077 }; 4078 4079 /** 4080 * @param {number} target 4081 * @param {number} level 4082 * @param {number} internalFormat 4083 * @param {number} width 4084 * @param {number} height 4085 * @param {number} border 4086 * @param {number} format 4087 * @param {number} type 4088 * @param {number} pixels 4089 */ 4090 sglrReferenceContext.ReferenceContext.prototype.texImage2D = function(target, level, internalFormat, width, height, border, format, type, pixels) { 4091 this.texImage3D(target, level, internalFormat, width, height, 1, border, format, type, pixels); 4092 }; 4093 4094 sglrReferenceContext.ReferenceContext.prototype.texImage3D = function(target, level, internalFormat, width, height, depth, border, format, type, pixels) { 4095 /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture]; 4096 /** @type {ArrayBuffer} */ var data = null; 4097 /** @type {number} */ var offset = 0; 4098 /** @type {tcuTexture.PixelBufferAccess} */ var dst; 4099 /** @type {tcuTexture.ConstPixelBufferAccess} */ var src; 4100 if (this.m_pixelUnpackBufferBinding) { 4101 if (this.conditionalSetError(typeof pixels !== 'number', gl.INVALID_VALUE)) 4102 return; 4103 data = this.m_pixelUnpackBufferBinding.getData(); 4104 offset = pixels; 4105 } else if (pixels) { 4106 if (pixels instanceof ArrayBuffer) { 4107 data = pixels; 4108 offset = 0; 4109 } else { 4110 data = pixels.buffer; 4111 offset = pixels.byteOffset; 4112 } 4113 } 4114 /** @type {boolean} */ var isDstFloatDepthFormat = (internalFormat == gl.DEPTH_COMPONENT32F || internalFormat == gl.DEPTH32F_STENCIL8); // depth components are limited to [0,1] range 4115 4116 if (this.conditionalSetError(border != 0, gl.INVALID_VALUE)) 4117 return; 4118 if (this.conditionalSetError(width < 0 || height < 0 || depth < 0 || level < 0, gl.INVALID_VALUE)) 4119 return; 4120 4121 // Map storage format. 4122 /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat); 4123 if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM)) 4124 return; 4125 4126 // Map transfer format. 4127 /** @type {tcuTexture.TextureFormat} */ var transferFmt = gluTextureUtil.mapGLTransferFormat(format, type); 4128 if (this.conditionalSetError(!transferFmt, gl.INVALID_ENUM)) 4129 return; 4130 4131 if (target == gl.TEXTURE_2D) { 4132 // Validate size and level. 4133 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize || depth != 1, gl.INVALID_VALUE)) 4134 return; 4135 if (this.conditionalSetError(level > Math.log2(this.m_limits.maxTexture2DSize), gl.INVALID_VALUE)) 4136 return; 4137 4138 /** @type {sglrReferenceContext.Texture2D} */ 4139 var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture); 4140 4141 if (texture.isImmutable()) { 4142 if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_OPERATION)) 4143 return; 4144 4145 //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level)); 4146 dst = texture.getLevel(level); 4147 4148 if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) || 4149 width != dst.getWidth() || 4150 height != dst.getHeight(), gl.INVALID_OPERATION)) 4151 return; 4152 } else 4153 texture.allocLevel(level, storageFmt, width, height); 4154 4155 if (data) { 4156 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4157 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4158 var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4159 src = new tcuTexture.ConstPixelBufferAccess({ 4160 format: transferFmt, 4161 width: width, 4162 height: height, 4163 rowPitch: rowPitch, 4164 data: data, 4165 offset: offset + skip}); 4166 4167 //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level)); 4168 dst = texture.getLevel(level); 4169 4170 if (isDstFloatDepthFormat) 4171 sglrReferenceContext.depthValueFloatClampCopy(dst, src); 4172 else 4173 tcuTextureUtil.copy(dst, src); 4174 } else { 4175 // No data supplied, clear to black. 4176 4177 //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level)); 4178 dst = texture.getLevel(level); 4179 dst.clear([0.0, 0.0, 0.0, 1.0]); 4180 } 4181 } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X || 4182 target == gl.TEXTURE_CUBE_MAP_POSITIVE_X || 4183 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || 4184 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y || 4185 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z || 4186 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) { 4187 // Validate size and level. 4188 if (this.conditionalSetError(width != height || width > this.m_limits.maxTextureCubeSize || depth != 1, gl.INVALID_VALUE)) 4189 return; 4190 if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTextureCubeSize)), gl.INVALID_VALUE)) 4191 return; 4192 4193 var textureCube = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture); 4194 4195 var face = sglrReferenceContext.mapGLCubeFace(target); 4196 4197 if (textureCube.isImmutable()) { 4198 if (this.conditionalSetError(!textureCube.hasFace(level, face), gl.INVALID_OPERATION)) 4199 return; 4200 4201 dst = textureCube.getFace(level, face); 4202 4203 if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) || 4204 width != dst.getWidth() || 4205 height != dst.getHeight(), gl.INVALID_OPERATION)) 4206 return; 4207 } else 4208 textureCube.allocLevel(level, face, storageFmt, width, height); 4209 4210 if (data) { 4211 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4212 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4213 var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4214 src = new tcuTexture.ConstPixelBufferAccess({ 4215 format: transferFmt, 4216 width: width, 4217 height: height, 4218 rowPitch: rowPitch, 4219 data: data, 4220 offset: offset + skip}); 4221 4222 dst = textureCube.getFace(level, face); 4223 4224 if (isDstFloatDepthFormat) 4225 sglrReferenceContext.depthValueFloatClampCopy(dst, src); 4226 else 4227 tcuTextureUtil.copy(dst, src); 4228 } else { 4229 // No data supplied, clear to black. 4230 dst = textureCube.getFace(level, face); 4231 dst.clear([0.0, 0.0, 0.0, 1.0]); 4232 } 4233 } else if (target == gl.TEXTURE_2D_ARRAY) { 4234 // Validate size and level. 4235 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || 4236 height > this.m_limits.maxTexture2DSize || 4237 depth > this.m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE)) 4238 return; 4239 if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture2DSize)), gl.INVALID_VALUE)) 4240 return; 4241 4242 /** @type {sglrReferenceContext.Texture2DArray} */ 4243 var texture2DArray = /** @type {sglrReferenceContext.Texture2DArray} */ (unit.tex2DArrayBinding.texture); 4244 4245 if (texture2DArray.isImmutable()) { 4246 if (this.conditionalSetError(!texture2DArray.hasLevel(level), gl.INVALID_OPERATION)) 4247 return; 4248 4249 dst = texture2DArray.getLevel(level); 4250 if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) || 4251 width != dst.getWidth() || 4252 height != dst.getHeight() || 4253 depth != dst.getDepth(), gl.INVALID_OPERATION)) 4254 return; 4255 } else 4256 texture2DArray.allocLevel(level, storageFmt, width, height, depth); 4257 4258 if (data) { 4259 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4260 var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height; 4261 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4262 var slicePitch = imageHeight * rowPitch; 4263 var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch + 4264 this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4265 src = new tcuTexture.ConstPixelBufferAccess({ 4266 format: transferFmt, 4267 width: width, 4268 height: height, 4269 depth: depth, 4270 rowPitch: rowPitch, 4271 slicePitch: slicePitch, 4272 data: data, 4273 offset: offset + skip}); 4274 4275 dst = texture2DArray.getLevel(level); 4276 4277 if (isDstFloatDepthFormat) 4278 sglrReferenceContext.depthValueFloatClampCopy(dst, src); 4279 else 4280 tcuTextureUtil.copy(dst, src); 4281 } else { 4282 // No data supplied, clear to black. 4283 dst = texture2DArray.getLevel(level); 4284 dst.clear([0.0, 0.0, 0.0, 1.0]); 4285 } 4286 } else if (target == gl.TEXTURE_3D) { 4287 // Validate size and level. 4288 if (this.conditionalSetError(width > this.m_limits.maxTexture3DSize || 4289 height > this.m_limits.maxTexture3DSize || 4290 depth > this.m_limits.maxTexture3DSize, gl.INVALID_VALUE)) 4291 return; 4292 if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture3DSize)), gl.INVALID_VALUE)) 4293 return; 4294 4295 var texture3D = /** @type {sglrReferenceContext.Texture3D} */ (unit.tex3DBinding.texture); 4296 4297 if (texture3D.isImmutable()) { 4298 if (this.conditionalSetError(!texture3D.hasLevel(level), gl.INVALID_OPERATION)) 4299 return; 4300 4301 dst = texture3D.getLevel(level); 4302 if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) || 4303 width != dst.getWidth() || 4304 height != dst.getHeight() || 4305 depth != dst.getDepth(), gl.INVALID_OPERATION)) 4306 return; 4307 } else 4308 texture3D.allocLevel(level, storageFmt, width, height, depth); 4309 4310 if (data) { 4311 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4312 var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height; 4313 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4314 var slicePitch = imageHeight * rowPitch; 4315 var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch + 4316 this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4317 src = new tcuTexture.ConstPixelBufferAccess({ 4318 format: transferFmt, 4319 width: width, 4320 height: height, 4321 depth: depth, 4322 rowPitch: rowPitch, 4323 slicePitch: slicePitch, 4324 data: data, 4325 offset: offset + skip}); 4326 4327 dst = texture3D.getLevel(level); 4328 4329 if (isDstFloatDepthFormat) 4330 sglrReferenceContext.depthValueFloatClampCopy(dst, src); 4331 else 4332 tcuTextureUtil.copy(dst, src); 4333 4334 } else { 4335 // No data supplied, clear to black. 4336 dst = texture3D.getLevel(level); 4337 dst.clear([0.0, 0.0, 0.0, 1.0]); 4338 } 4339 } 4340 // else if (target == gl.TEXTURE_CUBE_MAP_ARRAY) 4341 // { 4342 // // Validate size and level. 4343 // RC_IF_ERROR(width != height || 4344 // width > m_limits.maxTexture2DSize || 4345 // depth % 6 != 0 || 4346 // depth > m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE, RC_RET_VOID); 4347 // RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), gl.INVALID_VALUE, RC_RET_VOID); 4348 4349 // TextureCubeArray* texture = unit.texCubeArrayBinding ? unit.texCubeArrayBinding : &unit.defaultCubeArrayTex; 4350 4351 // if (texture->isImmutable()) 4352 // { 4353 // RC_IF_ERROR(!texture->hasLevel(level), gl.INVALID_OPERATION, RC_RET_VOID); 4354 4355 // ConstPixelBufferAccess dst(texture->getLevel(level)); 4356 // RC_IF_ERROR(storageFmt != dst.getFormat() || 4357 // width != dst.getWidth() || 4358 // height != dst.getHeight() || 4359 // depth != dst.getDepth(), gl.INVALID_OPERATION, RC_RET_VOID); 4360 // } 4361 // else 4362 // texture->allocLevel(level, storageFmt, width, height, depth); 4363 4364 // if (unpackPtr) 4365 // { 4366 // ConstPixelBufferAccess src = getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr); 4367 // PixelBufferAccess dst (texture->getLevel(level)); 4368 4369 // if (isDstFloatDepthFormat) 4370 // sglrReferenceContext.depthValueFloatClampCopy(dst, src); 4371 // else 4372 // tcu::copy(dst, src); 4373 // } 4374 // else 4375 // { 4376 // // No data supplied, clear to black. 4377 // PixelBufferAccess dst = texture->getLevel(level); 4378 // tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 4379 // } 4380 // } /**/ 4381 else 4382 this.setError(gl.INVALID_ENUM); 4383 }; 4384 4385 sglrReferenceContext.ReferenceContext.prototype.texSubImage2D = function(target, level, xoffset, yoffset, width, height, format, type, pixels) { 4386 this.texSubImage3D(target, level, xoffset, yoffset, 0, width, height, 1, format, type, pixels); 4387 }; 4388 4389 sglrReferenceContext.ReferenceContext.prototype.texSubImage3D = function(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) { 4390 /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture]; 4391 /** @type {ArrayBuffer} */ var data = null; 4392 /** @type {number} */ var offset = 0; 4393 /** @type {tcuTexture.PixelBufferAccess} */ var dst; 4394 /** @type {tcuTexture.PixelBufferAccess} */ var sub; 4395 /** @type {tcuTexture.ConstPixelBufferAccess} */ var src; 4396 /** @type {boolean} */ var isDstFloatDepthFormat; 4397 if (this.m_pixelUnpackBufferBinding) { 4398 if (this.conditionalSetError(typeof pixels !== 'number', gl.INVALID_VALUE)) 4399 return; 4400 data = this.m_pixelUnpackBufferBinding.getData(); 4401 offset = pixels; 4402 } else if (pixels) { 4403 if (pixels instanceof ArrayBuffer) { 4404 data = pixels; 4405 offset = 0; 4406 } else { 4407 data = pixels.buffer; 4408 offset = pixels.byteOffset; 4409 } 4410 } 4411 4412 if (this.conditionalSetError(xoffset < 0 || yoffset < 0 || zoffset < 0, gl.INVALID_VALUE)) 4413 return; 4414 if (this.conditionalSetError(width < 0 || height < 0 || depth < 0 || level < 0, gl.INVALID_VALUE)) 4415 return; 4416 4417 // Map transfer format. 4418 /** @type {tcuTexture.TextureFormat} */ var transferFmt = gluTextureUtil.mapGLTransferFormat(format, type); 4419 if (this.conditionalSetError(!transferFmt, gl.INVALID_ENUM)) 4420 return; 4421 4422 if (target == gl.TEXTURE_2D) { 4423 // Validate size and level. 4424 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize || depth != 1, gl.INVALID_VALUE)) 4425 return; 4426 if (this.conditionalSetError(level > Math.log2(this.m_limits.maxTexture2DSize), gl.INVALID_VALUE)) 4427 return; 4428 4429 /** @type {sglrReferenceContext.Texture2D} */ 4430 var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture); 4431 4432 if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_OPERATION)) 4433 return; 4434 4435 //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level)); 4436 dst = texture.getLevel(level); 4437 4438 if (this.conditionalSetError(xoffset + width > dst.getWidth() || 4439 yoffset + height > dst.getHeight() || 4440 zoffset + depth > dst.getDepth(), 4441 gl.INVALID_VALUE)) 4442 return; 4443 4444 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4445 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4446 var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4447 src = new tcuTexture.ConstPixelBufferAccess({ 4448 format: transferFmt, 4449 width: width, 4450 height: height, 4451 rowPitch: rowPitch, 4452 data: data, 4453 offset: offset + skip}); 4454 4455 sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth); 4456 isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range 4457 4458 if (isDstFloatDepthFormat) 4459 sglrReferenceContext.depthValueFloatClampCopy(sub, src); 4460 else 4461 tcuTextureUtil.copy(sub, src); 4462 } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X || 4463 target == gl.TEXTURE_CUBE_MAP_POSITIVE_X || 4464 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || 4465 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y || 4466 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z || 4467 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) { 4468 var textureCube = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture); 4469 4470 var face = sglrReferenceContext.mapGLCubeFace(target); 4471 4472 if (this.conditionalSetError(!textureCube.hasFace(level, face), gl.INVALID_OPERATION)) 4473 return; 4474 4475 dst = textureCube.getFace(level, face); 4476 4477 if (this.conditionalSetError(xoffset + width > dst.getWidth() || 4478 yoffset + height > dst.getHeight() || 4479 zoffset + depth > dst.getDepth(), 4480 gl.INVALID_VALUE)) 4481 return; 4482 4483 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4484 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4485 var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4486 src = new tcuTexture.ConstPixelBufferAccess({ 4487 format: transferFmt, 4488 width: width, 4489 height: height, 4490 rowPitch: rowPitch, 4491 slicePitach: slicePitch, 4492 data: data, 4493 offset: offset + skip}); 4494 4495 sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth); 4496 isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range 4497 4498 if (isDstFloatDepthFormat) 4499 sglrReferenceContext.depthValueFloatClampCopy(sub, src); 4500 else 4501 tcuTextureUtil.copy(sub, src); 4502 } else if (target == gl.TEXTURE_2D_ARRAY) { 4503 // Validate size and level. 4504 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || 4505 height > this.m_limits.maxTexture2DSize || 4506 depth > this.m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE)) 4507 return; 4508 if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture2DSize)), gl.INVALID_VALUE)) 4509 return; 4510 4511 /** @type {sglrReferenceContext.Texture2DArray} */ 4512 var texture2DArray = /** @type {sglrReferenceContext.Texture2DArray} */ (unit.tex2DArrayBinding.texture); 4513 4514 if (this.conditionalSetError(!texture2DArray.hasLevel(level), gl.INVALID_OPERATION)) 4515 return; 4516 4517 dst = texture2DArray.getLevel(level); 4518 if (this.conditionalSetError(xoffset + width > dst.getWidth() || 4519 yoffset + height > dst.getHeight() || 4520 zoffset + depth > dst.getDepth(), 4521 gl.INVALID_VALUE)) 4522 return; 4523 4524 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4525 var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height; 4526 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4527 var slicePitch = imageHeight * rowPitch; 4528 var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch + 4529 this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4530 src = new tcuTexture.ConstPixelBufferAccess({ 4531 format: transferFmt, 4532 width: width, 4533 height: height, 4534 depth: depth, 4535 rowPitch: rowPitch, 4536 slicePitch: slicePitch, 4537 data: data, 4538 offset: offset + skip}); 4539 4540 sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth); 4541 isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range 4542 4543 if (isDstFloatDepthFormat) 4544 sglrReferenceContext.depthValueFloatClampCopy(sub, src); 4545 else 4546 tcuTextureUtil.copy(sub, src); 4547 } else if (target == gl.TEXTURE_3D) { 4548 // Validate size and level. 4549 if (this.conditionalSetError(width > this.m_limits.maxTexture3DSize || 4550 height > this.m_limits.maxTexture3DSize || 4551 depth > this.m_limits.maxTexture3DSize, gl.INVALID_VALUE)) 4552 return; 4553 if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture3DSize)), gl.INVALID_VALUE)) 4554 return; 4555 4556 var texture3D = /** @type {sglrReferenceContext.Texture3D} */ (unit.tex3DBinding.texture); 4557 4558 if (this.conditionalSetError(!texture3D.hasLevel(level), gl.INVALID_OPERATION)) 4559 return; 4560 4561 dst = texture3D.getLevel(level); 4562 if (this.conditionalSetError(xoffset + width > dst.getWidth() || 4563 yoffset + height > dst.getHeight() || 4564 zoffset + depth > dst.getDepth(), 4565 gl.INVALID_VALUE)) 4566 return; 4567 4568 var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width; 4569 var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height; 4570 var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment); 4571 var slicePitch = imageHeight * rowPitch; 4572 var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch + 4573 this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize(); 4574 src = new tcuTexture.ConstPixelBufferAccess({ 4575 format: transferFmt, 4576 width: width, 4577 height: height, 4578 depth: depth, 4579 rowPitch: rowPitch, 4580 slicePitch: slicePitch, 4581 data: data, 4582 offset: offset + skip}); 4583 4584 sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth); 4585 4586 isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range 4587 if (isDstFloatDepthFormat) 4588 sglrReferenceContext.depthValueFloatClampCopy(sub, src); 4589 else 4590 tcuTextureUtil.copy(sub, src); 4591 } else 4592 this.setError(gl.INVALID_ENUM); 4593 }; 4594 4595 /** 4596 * @param {number} target 4597 * @param {number} level 4598 * @param {number} internalFormat 4599 * @param {number} x 4600 * @param {number} y 4601 * @param {number} width 4602 * @param {number} height 4603 * @param {number} border 4604 */ 4605 sglrReferenceContext.ReferenceContext.prototype.copyTexImage2D = function(target, level, internalFormat, x, y, width, height, border) { 4606 /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture]; 4607 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src = this.getReadColorbuffer(); 4608 4609 if (this.conditionalSetError(border != 0, gl.INVALID_VALUE)) 4610 return; 4611 if (this.conditionalSetError(width < 0 || height < 0 || level < 0, gl.INVALID_VALUE)) 4612 return; 4613 if (this.conditionalSetError(src.isEmpty(), gl.INVALID_OPERATION)) 4614 return; 4615 4616 // Map storage format. 4617 /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat); 4618 if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM)) 4619 return; 4620 4621 if (target == gl.TEXTURE_2D) { 4622 // Validate size and level. 4623 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize, gl.INVALID_VALUE)) 4624 return; 4625 if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture2DSize)), gl.INVALID_VALUE)) 4626 return; 4627 4628 /** @type {sglrReferenceContext.Texture2D} */ 4629 var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture); 4630 4631 if (texture.isImmutable()) { 4632 if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_OPERATION)) 4633 return; 4634 4635 /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getLevel(level); 4636 if (this.conditionalSetError(storageFmt != dst.getFormat() || width != dst.getWidth() || height != dst.getHeight(), gl.INVALID_OPERATION)) 4637 return; 4638 } else { 4639 texture.allocLevel(level, storageFmt, width, height); 4640 } 4641 4642 // Copy from current framebuffer. 4643 /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getLevel(level); 4644 for (var yo = 0; yo < height; yo++) { 4645 for (var xo = 0; xo < width; xo++) { 4646 if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth())) 4647 continue; // Undefined pixel. 4648 4649 dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo, yo); 4650 } 4651 } 4652 } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X || 4653 target == gl.TEXTURE_CUBE_MAP_POSITIVE_X || 4654 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || 4655 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y || 4656 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z || 4657 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) { 4658 // Validate size and level. 4659 if (this.conditionalSetError(width != height || width > this.m_limits.maxTextureCubeSize, gl.INVALID_VALUE)) 4660 return; 4661 if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTextureCubeSize)), gl.INVALID_VALUE)) 4662 return; 4663 4664 /** @type {sglrReferenceContext.TextureCube} */ 4665 var texture = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture); 4666 var face = sglrReferenceContext.mapGLCubeFace(target); 4667 4668 if (texture.isImmutable()) { 4669 if (this.conditionalSetError(!texture.hasFace(level, face), gl.INVALID_OPERATION)) 4670 return; 4671 4672 /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getFace(level, face); 4673 if (this.conditionalSetError(storageFmt != dst.getFormat() || width != dst.getWidth() || height != dst.getHeight(), gl.INVALID_OPERATION)) 4674 return; 4675 } else { 4676 texture.allocLevel(level, face, storageFmt, width, height); 4677 } 4678 4679 // Copy from current framebuffer. 4680 /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getFace(level, face); 4681 for (var yo = 0; yo < height; yo++) { 4682 for (var xo = 0; xo < width; xo++) { 4683 if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth())) 4684 continue; // Undefined pixel. 4685 4686 dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo, yo); 4687 } 4688 } 4689 } else { 4690 this.setError(gl.INVALID_ENUM); 4691 } 4692 } 4693 4694 /** 4695 * @param {number} target 4696 * @param {number} level 4697 * @param {number} xoffset 4698 * @param {number} yoffset 4699 * @param {number} x 4700 * @param {number} y 4701 * @param {number} width 4702 * @param {number} height 4703 */ 4704 sglrReferenceContext.ReferenceContext.prototype.copyTexSubImage2D = function(target, level, xoffset, yoffset, x, y, width, height) { 4705 /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture]; 4706 /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src = this.getReadColorbuffer(); 4707 4708 if (this.conditionalSetError(xoffset < 0 || yoffset < 0, gl.INVALID_VALUE)) 4709 return; 4710 if (this.conditionalSetError(width < 0 || height < 0 || level < 0, gl.INVALID_VALUE)) 4711 return; 4712 if (this.conditionalSetError(src.isEmpty(), gl.INVALID_OPERATION)) 4713 return; 4714 4715 if (target == gl.TEXTURE_2D) { 4716 /** @type {sglrReferenceContext.Texture2D} */ 4717 var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture); 4718 4719 if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_VALUE)) 4720 return; 4721 4722 /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getLevel(level); 4723 4724 if (this.conditionalSetError(xoffset + width > dst.getWidth() || yoffset + height > dst.getHeight(), gl.INVALID_VALUE)) 4725 return; 4726 4727 for (var yo = 0; yo < height; yo++) { 4728 for (var xo = 0; xo < width; xo++) { 4729 if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth())) 4730 continue; 4731 4732 dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo+xoffset, yo+yoffset); 4733 } 4734 } 4735 } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X || 4736 target == gl.TEXTURE_CUBE_MAP_POSITIVE_X || 4737 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || 4738 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y || 4739 target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z || 4740 target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) { 4741 /** @type {sglrReferenceContext.TextureCube} */ 4742 var texture = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture); 4743 var face = sglrReferenceContext.mapGLCubeFace(target); 4744 4745 if (this.conditionalSetError(!texture.hasFace(level, face), gl.INVALID_VALUE)) 4746 return; 4747 4748 /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getFace(level, face); 4749 4750 if (this.conditionalSetError(xoffset + width > dst.getWidth() || yoffset + height > dst.getHeight(), gl.INVALID_VALUE)) 4751 return; 4752 4753 for (var yo = 0; yo < height; yo++) { 4754 for (var xo = 0; xo < width; xo++) { 4755 if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth())) 4756 continue; 4757 4758 dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo+xoffset, yo+yoffset); 4759 } 4760 } 4761 } else { 4762 this.setError(gl.INVALID_ENUM); 4763 } 4764 } 4765 4766 sglrReferenceContext.ReferenceContext.prototype.texStorage3D = function(target, levels, internalFormat, width, height, depth) { 4767 /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture]; 4768 4769 if (this.conditionalSetError(width <= 0 || height <= 0, gl.INVALID_VALUE)) 4770 return; 4771 if (this.conditionalSetError(levels < 1 || levels > Math.floor(Math.log2(Math.max(width, height))) + 1, gl.INVALID_VALUE)) 4772 return; 4773 4774 // Map storage format. 4775 /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat); 4776 if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM)) 4777 return; 4778 4779 if (target == gl.TEXTURE_2D_ARRAY) { 4780 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || 4781 height > this.m_limits.maxTexture2DSize || 4782 depth >= this.m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE)) 4783 return; 4784 4785 /** @type {sglrReferenceContext.Texture2DArray} */ 4786 var textureArray = /** @type {sglrReferenceContext.Texture2DArray} */ (unit.tex2DArrayBinding.texture); 4787 if (this.conditionalSetError(textureArray.isImmutable(), gl.INVALID_OPERATION)) 4788 return; 4789 4790 textureArray.clearLevels(); 4791 textureArray.setImmutable(); 4792 4793 for (var level = 0; level < levels; level++) { 4794 var levelW = Math.max(1, width >> level); 4795 var levelH = Math.max(1, height >> level); 4796 4797 textureArray.allocLevel(level, storageFmt, levelW, levelH, depth); 4798 } 4799 } else if (target == gl.TEXTURE_3D) { 4800 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || 4801 height > this.m_limits.maxTexture2DSize || 4802 depth >= this.m_limits.maxTexture3DSize, gl.INVALID_VALUE)) 4803 return; 4804 4805 /** @type {sglrReferenceContext.Texture3D} */ 4806 var texture3D = /** @type {sglrReferenceContext.Texture3D} */ (unit.tex3DBinding.texture); 4807 if (this.conditionalSetError(texture3D.isImmutable(), gl.INVALID_OPERATION)) 4808 return; 4809 4810 texture3D.clearLevels(); 4811 texture3D.setImmutable(); 4812 4813 for (var level = 0; level < levels; level++) { 4814 var levelW = Math.max(1, width >> level); 4815 var levelH = Math.max(1, height >> level); 4816 var levelD = Math.max(1, depth >> level); 4817 4818 texture3D.allocLevel(level, storageFmt, levelW, levelH, levelD); 4819 } 4820 } else 4821 this.setError(gl.INVALID_ENUM); 4822 }; 4823 4824 sglrReferenceContext.ReferenceContext.prototype.texStorage2D = function(target, levels, internalFormat, width, height) { 4825 /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture]; 4826 4827 if (this.conditionalSetError(width <= 0 || height <= 0, gl.INVALID_VALUE)) 4828 return; 4829 if (this.conditionalSetError(levels < 1 || levels > Math.floor(Math.log2(Math.max(width, height))) + 1, gl.INVALID_VALUE)) 4830 return; 4831 4832 // Map storage format. 4833 /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat); 4834 if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM)) 4835 return; 4836 4837 if (target == gl.TEXTURE_2D) { 4838 if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize, gl.INVALID_VALUE)) 4839 return; 4840 4841 /** @type {sglrReferenceContext.Texture2D} */ 4842 var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture); 4843 if (this.conditionalSetError(texture.isImmutable(), gl.INVALID_OPERATION)) 4844 return; 4845 4846 texture.clearLevels(); 4847 texture.setImmutable(); 4848 4849 for (var level = 0; level < levels; level++) { 4850 var levelW = Math.max(1, width >> level); 4851 var levelH = Math.max(1, height >> level); 4852 4853 texture.allocLevel(level, storageFmt, levelW, levelH); 4854 } 4855 } else if (target == gl.TEXTURE_CUBE_MAP) { 4856 if (this.conditionalSetError(width != height || width > this.m_limits.maxTextureCubeSize, gl.INVALID_VALUE)) 4857 return; 4858 var textureCube = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture); 4859 if (this.conditionalSetError(textureCube.isImmutable(), gl.INVALID_OPERATION)) 4860 return; 4861 4862 textureCube.clearLevels(); 4863 textureCube.setImmutable(); 4864 4865 for (var level = 0; level < levels; level++) { 4866 var levelW = Math.max(1, width >> level); 4867 var levelH = Math.max(1, height >> level); 4868 4869 for (var face in tcuTexture.CubeFace) 4870 textureCube.allocLevel(level, tcuTexture.CubeFace[face], storageFmt, levelW, levelH); 4871 } 4872 } else 4873 this.setError(gl.INVALID_ENUM); 4874 }; 4875 4876 /** 4877 * @param {number} value 4878 * @return {?tcuTexture.WrapMode} 4879 */ 4880 sglrReferenceContext.mapGLWrapMode = function(value) { 4881 switch (value) { 4882 case gl.CLAMP_TO_EDGE: return tcuTexture.WrapMode.CLAMP_TO_EDGE; 4883 case gl.REPEAT: return tcuTexture.WrapMode.REPEAT_GL; 4884 case gl.MIRRORED_REPEAT: return tcuTexture.WrapMode.MIRRORED_REPEAT_GL; 4885 } 4886 return null; 4887 }; 4888 4889 /** 4890 * @param {number} value 4891 * @return {?tcuTexture.FilterMode} 4892 */ 4893 sglrReferenceContext.mapGLFilterMode = function(value) { 4894 switch (value) { 4895 case gl.NEAREST: return tcuTexture.FilterMode.NEAREST; 4896 case gl.LINEAR: return tcuTexture.FilterMode.LINEAR; 4897 case gl.NEAREST_MIPMAP_NEAREST: return tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST; 4898 case gl.NEAREST_MIPMAP_LINEAR: return tcuTexture.FilterMode.NEAREST_MIPMAP_LINEAR; 4899 case gl.LINEAR_MIPMAP_NEAREST: return tcuTexture.FilterMode.LINEAR_MIPMAP_NEAREST; 4900 case gl.LINEAR_MIPMAP_LINEAR: return tcuTexture.FilterMode.LINEAR_MIPMAP_LINEAR; 4901 } 4902 return null; 4903 }; 4904 4905 /** 4906 * @param {number} target 4907 * @param {number} pname 4908 * @param {number} value 4909 */ 4910 sglrReferenceContext.ReferenceContext.prototype.texParameteri = function(target, pname, value) { 4911 /** @type {sglrReferenceContext.TextureUnit} */ var unit = this.m_textureUnits[this.m_activeTexture]; 4912 /** @type {sglrReferenceContext.TextureContainer} */ var container = null; 4913 4914 switch (target) { 4915 case gl.TEXTURE_2D: container = unit.tex2DBinding; break; 4916 case gl.TEXTURE_CUBE_MAP: container = unit.texCubeBinding; break; 4917 case gl.TEXTURE_2D_ARRAY: container = unit.tex2DArrayBinding; break; 4918 case gl.TEXTURE_3D: container = unit.tex3DBinding; break; 4919 4920 default: this.setError(gl.INVALID_ENUM); 4921 } 4922 4923 if (!container) 4924 return; 4925 4926 /** @type {sglrReferenceContext.Texture} */ 4927 var texture = container.texture; 4928 4929 switch (pname) { 4930 case gl.TEXTURE_WRAP_S: { 4931 /** @type {?tcuTexture.WrapMode} */ var wrapS = sglrReferenceContext.mapGLWrapMode(value); 4932 if (this.conditionalSetError(null == wrapS, gl.INVALID_VALUE)) 4933 return; 4934 texture.getSampler().wrapS = /** @type {tcuTexture.WrapMode} */ (wrapS); 4935 break; 4936 } 4937 4938 case gl.TEXTURE_WRAP_T: { 4939 /** @type {?tcuTexture.WrapMode} */ var wrapT = sglrReferenceContext.mapGLWrapMode(value); 4940 if (this.conditionalSetError(null == wrapT, gl.INVALID_VALUE)) 4941 return; 4942 texture.getSampler().wrapT = /** @type {tcuTexture.WrapMode} */ (wrapT); 4943 break; 4944 } 4945 4946 case gl.TEXTURE_WRAP_R: { 4947 /** @type {?tcuTexture.WrapMode} */ var wrapR = sglrReferenceContext.mapGLWrapMode(value); 4948 if (this.conditionalSetError(null == wrapR, gl.INVALID_VALUE)) 4949 return; 4950 texture.getSampler().wrapR = /** @type {tcuTexture.WrapMode} */ (wrapR); 4951 break; 4952 } 4953 4954 case gl.TEXTURE_MIN_FILTER: { 4955 /** @type {?tcuTexture.FilterMode} */ var minMode = sglrReferenceContext.mapGLFilterMode(value); 4956 if (this.conditionalSetError(null == minMode, gl.INVALID_VALUE)) 4957 return; 4958 texture.getSampler().minFilter = /** @type {tcuTexture.FilterMode} */ (minMode); 4959 break; 4960 } 4961 4962 case gl.TEXTURE_MAG_FILTER: { 4963 /** @type {?tcuTexture.FilterMode} */ var magMode = sglrReferenceContext.mapGLFilterMode(value); 4964 if (this.conditionalSetError(null == magMode, gl.INVALID_VALUE)) 4965 return; 4966 texture.getSampler().magFilter = /** @type {tcuTexture.FilterMode} */ (magMode); 4967 break; 4968 } 4969 4970 case gl.TEXTURE_MAX_LEVEL: { 4971 if (this.conditionalSetError(value < 0, gl.INVALID_VALUE)) 4972 return; 4973 texture.setMaxLevel(value); 4974 break; 4975 } 4976 4977 default: 4978 this.setError(gl.INVALID_ENUM); 4979 return; 4980 } 4981 }; 4982 4983 sglrReferenceContext.ReferenceContext.prototype.invalidateFramebuffer = function(target, attachments) {}; 4984 sglrReferenceContext.ReferenceContext.prototype.invalidateSubFramebuffer = function(target, attachments, x, y, width, height) {}; 4985 4986 });