summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js510
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluObjectWrapper.js117
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluPixelTransfer.js55
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js488
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderUtil.js795
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluStrUtil.js166
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTexture.js380
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTextureUtil.js1025
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarType.js814
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarTypeUtil.js693
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/00_test_list.txt1
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/referencecontext.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrGLContext.js231
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContext.js4986
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContextTest.js834
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceUtils.js317
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrShaderProgram.js336
17 files changed, 11780 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js
new file mode 100644
index 0000000000..baa05a9708
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js
@@ -0,0 +1,510 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+
+var gluDrawUtil = framework.opengl.gluDrawUtil;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+/**
+ * Description of a vertex array binding
+ * @constructor
+ * @param {number} type GL gluDrawUtil.Type of data
+ * @param {(number|undefined)} location Binding location
+ * @param {number} components Number of components per vertex
+ * @param {number} elements Number of elements in the array
+ * @param {Array<number>} data Source data
+ * @param {number=} stride
+ * @param {number=} offset
+ */
+gluDrawUtil.VertexArrayBinding = function(type, location, components, elements, data, stride, offset) {
+ this.type = type;
+ this.location = location === undefined ? -1 : location;
+ this.components = components;
+ this.elements = elements;
+ this.data = data;
+ /** @type {?string} */ this.name = null;
+ this.stride = stride || 0;
+ this.offset = offset || 0;
+};
+
+/**
+ * Description of a vertex array binding
+ * @param {gluDrawUtil.BindingPoint} binding
+ * @param {gluDrawUtil.VertexArrayPointer} pointer
+ * @param {number=} dataType GL Data Type
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.vabFromBindingPointAndArrayPointer = function(binding, pointer, dataType) {
+ var type = dataType === undefined ? gl.FLOAT : dataType;
+ var location = binding.location;
+ var components = pointer.numComponents;
+ var elements = pointer.numElements;
+ var data = pointer.data;
+ var vaBinding = new gluDrawUtil.VertexArrayBinding(type, location, components, elements, data);
+ vaBinding.componentType = pointer.componentType;
+ vaBinding.name = binding.name;
+ vaBinding.convert = pointer.convert;
+ vaBinding.stride = pointer.stride;
+ return vaBinding;
+};
+
+/**
+ * ! Lower named bindings to locations and eliminate bindings that are not used by program.
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {WebGLProgram} program
+ * @param {Array} inputArray - Array with the named binding locations
+ * @param {Array=} outputArray - Array with the lowered locations
+ * @return {Array} outputArray
+ */
+gluDrawUtil.namedBindingsToProgramLocations = function(gl, program, inputArray, outputArray) {
+ outputArray = outputArray || [];
+
+ for (var i = 0; i < inputArray.length; i++) {
+ var cur = inputArray[i];
+ if (cur.name) {
+ //assert(binding.location >= 0);
+ var location = gl.getAttribLocation(program, cur.name);
+ if (location >= 0) {
+ if (cur.location >= 0)
+ location += cur.location;
+ // Add binding.location as an offset to accomodate matrices.
+ outputArray.push(new gluDrawUtil.VertexArrayBinding(cur.type, location, cur.components, cur.elements, cur.data, cur.stride, cur.offset));
+ }
+ } else {
+ outputArray.push(cur);
+ }
+ }
+
+ return outputArray;
+};
+
+/**
+ * Creates vertex buffer, binds it and draws elements
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {WebGLProgram} program ID, vertexProgramID
+ * @param {Array<gluDrawUtil.VertexArrayBinding>} vertexArrays
+ * @param {gluDrawUtil.PrimitiveList} primitives to gluDrawUtil.draw
+ * @param { {beforeDrawCall:function(), afterDrawCall:function()}=} callback
+ */
+gluDrawUtil.draw = function(gl, program, vertexArrays, primitives, callback) {
+ /** TODO: finish implementation */
+ /** @type {Array<WebGLBuffer>} */ var objects = [];
+
+ // Lower bindings to locations
+ vertexArrays = gluDrawUtil.namedBindingsToProgramLocations(gl, program, vertexArrays);
+
+ for (var i = 0; i < vertexArrays.length; i++) {
+ /** @type {WebGLBuffer} */ var buffer = gluDrawUtil.vertexBuffer(gl, vertexArrays[i]);
+ objects.push(buffer);
+ }
+
+ if (primitives.indices) {
+ /** @type {WebGLBuffer} */ var elemBuffer = gluDrawUtil.indexBuffer(gl, primitives);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elemBuffer);
+
+ if (callback)
+ callback.beforeDrawCall();
+
+ gluDrawUtil.drawIndexed(gl, primitives, 0);
+
+ if (callback)
+ callback.afterDrawCall();
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ } else {
+ if (callback)
+ callback.beforeDrawCall();
+
+ gl.drawArrays(gluDrawUtil.getPrimitiveGLType(gl, primitives.type), 0, primitives.numElements);
+
+ if (callback)
+ callback.afterDrawCall();
+ }
+
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'drawArrays', false, true);
+ for (var i = 0; i < vertexArrays.length; i++) {
+ gl.disableVertexAttribArray(vertexArrays[i].location);
+ }
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+};
+
+/**
+ * Creates vertex buffer, binds it and draws elements
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.PrimitiveList} primitives Primitives to gluDrawUtil.draw
+ * @param {number} offset
+ */
+gluDrawUtil.drawIndexed = function(gl, primitives, offset) {
+/** @type {number} */ var mode = gluDrawUtil.getPrimitiveGLType(gl, primitives.type);
+ /** TODO: C++ implementation supports different index types, we use only int16.
+ Could it cause any issues?
+
+ deUint32 indexGLType = getIndexGLType(primitives.indexType);
+ */
+
+ gl.drawElements(mode, primitives.indices.length, gl.UNSIGNED_SHORT, offset);
+};
+
+/**
+ * Enums for primitive types
+ * @enum
+ */
+gluDrawUtil.primitiveType = {
+ TRIANGLES: 0,
+ TRIANGLE_STRIP: 1,
+ TRIANGLE_FAN: 2,
+
+ LINES: 3,
+ LINE_STRIP: 4,
+ LINE_LOOP: 5,
+
+ POINTS: 6,
+
+ PATCHES: 7
+};
+
+/**
+ * get GL type from primitive type
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.primitiveType} type gluDrawUtil.primitiveType
+ * @return {number} GL primitive type
+ */
+gluDrawUtil.getPrimitiveGLType = function(gl, type) {
+ switch (type) {
+ case gluDrawUtil.primitiveType.TRIANGLES: return gl.TRIANGLES;
+ case gluDrawUtil.primitiveType.TRIANGLE_STRIP: return gl.TRIANGLE_STRIP;
+ case gluDrawUtil.primitiveType.TRIANGLE_FAN: return gl.TRIANGLE_FAN;
+ case gluDrawUtil.primitiveType.LINES: return gl.LINES;
+ case gluDrawUtil.primitiveType.LINE_STRIP: return gl.LINE_STRIP;
+ case gluDrawUtil.primitiveType.LINE_LOOP: return gl.LINE_LOOP;
+ case gluDrawUtil.primitiveType.POINTS: return gl.POINTS;
+// case gluDrawUtil.primitiveType.PATCHES: return gl.PATCHES;
+ default:
+ throw new Error('Unknown primitive type ' + type);
+ }
+};
+
+/**
+ * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Points
+ * @param {number} numElements
+ */
+gluDrawUtil.pointsFromElements = function(numElements) {
+ return new gluDrawUtil.PrimitiveList(gluDrawUtil.primitiveType.POINTS, numElements);
+};
+
+/**
+ * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Triangles
+ * @param {Array<number>} indices
+ */
+gluDrawUtil.triangles = function(indices) {
+ return gluDrawUtil.newPrimitiveListFromIndices(gluDrawUtil.primitiveType.TRIANGLES, indices);
+};
+
+/**
+ * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Patches
+ * @param {Array<number>} indices
+ */
+gluDrawUtil.patches = function(indices) {
+ return gluDrawUtil.newPrimitiveListFromIndices(gluDrawUtil.primitiveType.PATCHES, indices);
+};
+
+/**
+ * Creates primitive list for Triangles or Patches, depending on type
+ * @param {gluDrawUtil.primitiveType} type gluDrawUtil.primitiveType
+ * @param {number} numElements
+ * @constructor
+ */
+gluDrawUtil.PrimitiveList = function(type, numElements) {
+ this.type = type;
+ this.indices = 0;
+ this.numElements = numElements;
+};
+
+/**
+ * @param {gluDrawUtil.primitiveType} type
+ * @param {Array<number>} indices
+ * @return {gluDrawUtil.PrimitiveList}
+ */
+gluDrawUtil.newPrimitiveListFromIndices = function(type, indices) {
+ /** @type {gluDrawUtil.PrimitiveList} */ var primitiveList = new gluDrawUtil.PrimitiveList(type, 0);
+ primitiveList.indices = indices;
+ return primitiveList;
+};
+
+/**
+ * Create Element Array Buffer
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.PrimitiveList} primitives to construct the buffer from
+ * @return {WebGLBuffer} indexObject buffer with elements
+ */
+gluDrawUtil.indexBuffer = function(gl, primitives) {
+ /** @type {WebGLBuffer} */ var indexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bindBuffer', false, true);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(primitives.indices), gl.STATIC_DRAW);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bufferData', false, true);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ return indexObject;
+};
+
+/**
+ * Create Array Buffer
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.VertexArrayBinding} vertexArray primitives, Array buffer descriptor
+ * @return {WebGLBuffer} buffer of vertices
+ */
+gluDrawUtil.vertexBuffer = function(gl, vertexArray) {
+ /** @type {goog.TypedArray} */ var typedArray;
+ switch (vertexArray.type) {
+ case gl.BYTE: typedArray = new Int8Array(vertexArray.data); break;
+ case gl.UNSIGNED_BYTE: typedArray = new Uint8Array(vertexArray.data); break;
+ case gl.SHORT: typedArray = new Int16Array(vertexArray.data); break;
+ case gl.UNSIGNED_SHORT: typedArray = new Uint16Array(vertexArray.data); break;
+ case gl.INT: typedArray = new Int32Array(vertexArray.data); break;
+ case gl.UNSIGNED_INT: typedArray = new Uint32Array(vertexArray.data); break;
+ default: typedArray = new Float32Array(vertexArray.data); break;
+ }
+
+ /** @type {WebGLBuffer} */ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bindBuffer', false, true);
+ gl.bufferData(gl.ARRAY_BUFFER, typedArray, gl.STATIC_DRAW);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bufferData', false, true);
+ gl.enableVertexAttribArray(vertexArray.location);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'enableVertexAttribArray', false, true);
+ if (vertexArray.type === gl.FLOAT) {
+ gl.vertexAttribPointer(vertexArray.location, vertexArray.components, vertexArray.type, false, vertexArray.stride, vertexArray.offset);
+ } else {
+ gl.vertexAttribIPointer(vertexArray.location, vertexArray.components, vertexArray.type, vertexArray.stride, vertexArray.offset);
+ }
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'vertexAttribPointer', false, true);
+ return buffer;
+};
+
+/**
+ * @param {Array<number>} rgba
+ * @constructor
+ */
+gluDrawUtil.Pixel = function(rgba) {
+ this.rgba = rgba;
+};
+
+gluDrawUtil.Pixel.prototype.getRed = function() {
+ return this.rgba[0];
+};
+gluDrawUtil.Pixel.prototype.getGreen = function() {
+ return this.rgba[1];
+};
+gluDrawUtil.Pixel.prototype.getBlue = function() {
+ return this.rgba[2];
+};
+gluDrawUtil.Pixel.prototype.getAlpha = function() {
+ return this.rgba[3];
+};
+gluDrawUtil.Pixel.prototype.equals = function(otherPixel) {
+ return this.rgba[0] == otherPixel.rgba[0] &&
+ this.rgba[1] == otherPixel.rgba[1] &&
+ this.rgba[2] == otherPixel.rgba[2] &&
+ this.rgba[3] == otherPixel.rgba[3];
+};
+
+/**
+ * @constructor
+ */
+gluDrawUtil.Surface = function() {
+};
+
+gluDrawUtil.Surface.prototype.readSurface = function(gl, x, y, width, height) {
+ this.buffer = new Uint8Array(width * height * 4);
+ gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, this.buffer);
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ return this.buffer;
+};
+
+gluDrawUtil.Surface.prototype.getPixel = function(x, y) {
+ /** @type {number} */ var base = (x + y * this.width) * 4;
+ /** @type {Array<number>} */
+ var rgba = [
+ this.buffer[base],
+ this.buffer[base + 1],
+ this.buffer[base + 2],
+ this.buffer[base + 3]
+ ];
+ return new gluDrawUtil.Pixel(rgba);
+};
+
+gluDrawUtil.Surface.prototype.getPixelUintRGB8 = function(x, y) {
+ /** @type {number} */ var base = (x + y * this.width) * 4;
+ /** @type {number} */
+ return (this.buffer[base] << 16) +
+ (this.buffer[base + 1] << 8) +
+ this.buffer[base + 2];
+};
+
+/**
+ * @enum
+ */
+gluDrawUtil.VertexComponentType = {
+ // Standard types: all conversion types apply.
+ VTX_COMP_UNSIGNED_INT8: 0,
+ VTX_COMP_UNSIGNED_INT16: 1,
+ VTX_COMP_UNSIGNED_INT32: 2,
+ VTX_COMP_SIGNED_INT8: 3,
+ VTX_COMP_SIGNED_INT16: 4,
+ VTX_COMP_SIGNED_INT32: 5,
+
+ // Special types: only CONVERT_NONE is allowed.
+ VTX_COMP_FIXED: 6,
+ VTX_COMP_HALF_FLOAT: 7,
+ VTX_COMP_FLOAT: 8
+};
+
+/**
+ * @enum
+ */
+gluDrawUtil.VertexComponentConversion = {
+ VTX_COMP_CONVERT_NONE: 0, //!< No conversion: integer types, or floating-point values.
+ VTX_COMP_CONVERT_NORMALIZE_TO_FLOAT: 1, //!< Normalize integers to range [0,1] or [-1,1] depending on type.
+ VTX_COMP_CONVERT_CAST_TO_FLOAT: 2 //!< Convert to floating-point directly.
+};
+
+/**
+ * gluDrawUtil.VertexArrayPointer
+ * @constructor
+ * @param {gluDrawUtil.VertexComponentType} componentType_
+ * @param {gluDrawUtil.VertexComponentConversion} convert_
+ * @param {number} numComponents_
+ * @param {number} numElements_
+ * @param {number} stride_
+ * @const @param {Array<number>} data_
+ */
+gluDrawUtil.VertexArrayPointer = function(componentType_, convert_, numComponents_, numElements_, stride_, data_) {
+ this.componentType = componentType_;
+ this.convert = convert_;
+ this.numComponents = numComponents_;
+ this.numElements = numElements_;
+ this.stride = stride_;
+ this.data = data_;
+};
+
+/**
+ * gluDrawUtil.BindingPoint
+ * @constructor
+ * @param {string} name
+ * @param {number} location
+ * @param {number=} offset
+ */
+gluDrawUtil.BindingPoint = function(name, location, offset) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.location = location;
+ /** @type {number} */ this.offset = offset || 0;
+};
+
+/**
+ * bindingPointFromLocation
+ * @param {number} location
+ * return {gluDrawUtil.BindingPoint}
+ */
+gluDrawUtil.bindingPointFromLocation = function(location) {
+ return new gluDrawUtil.BindingPoint('', location);
+};
+
+/**
+ * bindingPointFromName
+ * @param {string} name
+ * @param {number=} location
+ * return {gluDrawUtil.BindingPoint}
+ */
+gluDrawUtil.bindingPointFromName = function(name, location) {
+ location = location === undefined ? -1 : location;
+ return new gluDrawUtil.BindingPoint(name, location);
+};
+
+/**
+ * @param {string} name
+ * @param {number} numComponents
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newInt32VertexArrayBinding = function(name, numComponents, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_SIGNED_INT32,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer, gl.INT);
+};
+
+/**
+ * @param {string} name
+ * @param {number} numComponents
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newUint32VertexArrayBinding = function(name, numComponents, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_UNSIGNED_INT32,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer, gl.UNSIGNED_INT);
+};
+
+/**
+ * @param {string} name
+ * @param {number} numComponents
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newFloatVertexArrayBinding = function(name, numComponents, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_FLOAT,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer);
+};
+
+/**
+ * @param {string} name
+ * @param {number} column
+ * @param {number} rows
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newFloatColumnVertexArrayBinding = function(name, column, rows, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ bindingPoint.location = column;
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_FLOAT,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, rows, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer);
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluObjectWrapper.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluObjectWrapper.js
new file mode 100644
index 0000000000..38f8a28f9c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluObjectWrapper.js
@@ -0,0 +1,117 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+
+goog.provide('framework.opengl.gluObjectWrapper');
+
+goog.scope(function() {
+ var gluObjectWrapper = framework.opengl.gluObjectWrapper;
+
+ /**
+ * @typedef {function(this:WebGLRenderingContextBase): WebGLObject}
+ */
+ gluObjectWrapper.funcGenT;
+
+ /**
+ * @typedef {function(this:WebGLRenderingContextBase, WebGLObject)}
+ */
+ gluObjectWrapper.funcDelT;
+
+ /**
+ * @typedef {{name: string, funcGen: !gluObjectWrapper.funcGenT, funcDel: !gluObjectWrapper.funcDelT}}
+ */
+ gluObjectWrapper.traitsT;
+
+ /**
+ * Returns an object containing a configuration for an ObjectWrapper
+ * @param {string} name
+ * @param {gluObjectWrapper.funcGenT} funcGen
+ * @param {gluObjectWrapper.funcDelT} funcDel
+ * @return {gluObjectWrapper.traitsT}
+ */
+ gluObjectWrapper.traits = function(name, funcGen, funcDel) {
+ return {
+ name: name,
+ funcGen: funcGen,
+ funcDel: funcDel
+ };
+ };
+
+ /**
+ * @constructor
+ * @param {WebGLRenderingContextBase} gl
+ * @param {gluObjectWrapper.traitsT} traits
+ */
+ gluObjectWrapper.ObjectWrapper = function(gl, traits) {
+ /**
+ * @protected
+ * @type {WebGLRenderingContextBase}
+ */
+ this.m_gl = gl;
+
+ /**
+ * @protected
+ * @type {gluObjectWrapper.traitsT}
+ */
+ this.m_traits = traits;
+
+ /**
+ * @protected
+ * @type {WebGLObject}
+ */
+ this.m_object = this.m_traits.funcGen.call(gl);
+
+ };
+
+ /**
+ * Destorys the WebGLObject associated with this object.
+ */
+ gluObjectWrapper.ObjectWrapper.prototype.clear = function() {
+ this.m_traits.funcDel.call(this.m_gl, this.m_object);
+ };
+
+ /**
+ * Returns the WebGLObject associated with this object.
+ * @return {WebGLObject}
+ */
+ gluObjectWrapper.ObjectWrapper.prototype.get = function() {
+ return this.m_object;
+ };
+
+ /**
+ * @constructor
+ * @extends {gluObjectWrapper.ObjectWrapper}
+ * @param {WebGLRenderingContextBase} gl
+ */
+ gluObjectWrapper.Framebuffer = function(gl) {
+ gluObjectWrapper.ObjectWrapper.call(this, gl, gluObjectWrapper.traits(
+ 'framebuffer',
+ /** @type {gluObjectWrapper.funcGenT} */(gl.createFramebuffer),
+ /** @type {gluObjectWrapper.funcDelT} */(gl.deleteFramebuffer)
+ ));
+ };
+ gluObjectWrapper.Framebuffer.prototype = Object.create(gluObjectWrapper.ObjectWrapper.prototype);
+ gluObjectWrapper.Framebuffer.prototype.constructor = gluObjectWrapper.Framebuffer;
+
+ /**
+ * @return {WebGLFramebuffer}
+ */
+ gluObjectWrapper.Framebuffer.prototype.get;
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluPixelTransfer.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluPixelTransfer.js
new file mode 100644
index 0000000000..04b81a2a1a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluPixelTransfer.js
@@ -0,0 +1,55 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluPixelTransfer');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluTextureUtil');
+
+goog.scope(function() {
+
+var gluPixelTransfer = framework.opengl.gluPixelTransfer;
+var tcuTexture = framework.common.tcuTexture;
+var deMath = framework.delibs.debase.deMath;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+
+gluPixelTransfer.getTransferAlignment = function(format) {
+ var pixelSize = format.getPixelSize();
+ if (deMath.deIsPowerOfTwo32(pixelSize))
+ return Math.min(pixelSize, 8);
+ else
+ return 1;
+};
+
+gluPixelTransfer.readPixels = function(ctx, x, y, format, dst) {
+ var width = dst.getWidth();
+ var height = dst.getHeight();
+ var arrayType = tcuTexture.getTypedArray(format.type);
+ var transferFormat = gluTextureUtil.getTransferFormat(format);
+ ctx.pixelStorei(ctx.PACK_ALIGNMENT, gluPixelTransfer.getTransferAlignment(format));
+ var resultPixel = dst.getAccess().getDataPtr();
+ resultPixel = new arrayType(dst.getAccess().getBuffer());
+ ctx.readPixels(x, y, width, height, transferFormat.format, transferFormat.dataType, resultPixel);
+};
+
+/* TODO: implement other functions in C++ file */
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js
new file mode 100644
index 0000000000..0c340ee380
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js
@@ -0,0 +1,488 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality gluShaderProgram.Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+/**
+ * gluShaderProgram.Shader type enum
+ * @enum {number}
+ */
+gluShaderProgram.shaderType = {
+ VERTEX: 0,
+ FRAGMENT: 1
+};
+
+/**
+ * gluShaderProgram.Shader type enum name
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @return {string}
+ */
+gluShaderProgram.getShaderTypeName = function(shaderType) {
+ var s_names =
+ [
+ 'vertex',
+ 'fragment'
+ ];
+
+ return s_names[shaderType];
+};
+
+/**
+ * Get GL shader type from gluShaderProgram.shaderType
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluShaderProgram.shaderType} type gluShaderProgram.Shader Type
+ * @return {number} GL shader type
+ */
+gluShaderProgram.getGLShaderType = function(gl, type) {
+ var _glShaderType;
+ switch (type) {
+ case gluShaderProgram.shaderType.VERTEX: _glShaderType = gl.VERTEX_SHADER; break;
+ case gluShaderProgram.shaderType.FRAGMENT: _glShaderType = gl.FRAGMENT_SHADER; break;
+ default:
+ throw new Error('Unknown shader type ' + type);
+ }
+ return _glShaderType;
+};
+
+/**
+ * Declares shader information
+ * @constructor
+ * @param {gluShaderProgram.shaderType} type
+ * @param {string=} source
+ */
+gluShaderProgram.ShaderInfo = function(type, source) {
+ this.type = type; /** gluShaderProgram.Shader type. */
+ this.source = source; /** gluShaderProgram.Shader source. */
+ this.infoLog; /** Compile info log. */
+ this.compileOk = false; /** Did compilation succeed? */
+ this.compileTimeUs = 0; /** Compile time in microseconds (us). */
+};
+
+/**
+ * Generates vertex shader info from source
+ * @param {string} source
+ * @return {gluShaderProgram.ShaderInfo} vertex shader info
+ */
+gluShaderProgram.genVertexSource = function(source) {
+/** @type {gluShaderProgram.ShaderInfo} */ var shader = new gluShaderProgram.ShaderInfo(gluShaderProgram.shaderType.VERTEX, source);
+ return shader;
+};
+
+/**
+ * Generates fragment shader info from source
+ * @param {string} source
+ * @return {gluShaderProgram.ShaderInfo} fragment shader info
+ */
+gluShaderProgram.genFragmentSource = function(source) {
+/** @type {gluShaderProgram.ShaderInfo} */ var shader = new gluShaderProgram.ShaderInfo(gluShaderProgram.shaderType.FRAGMENT, source);
+ return shader;
+};
+
+/**
+ * Generates shader from WebGL context and type
+ * @constructor
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluShaderProgram.shaderType} type gluShaderProgram.Shader Type
+ */
+gluShaderProgram.Shader = function(gl, type) {
+ this.gl = gl;
+ this.info = new gluShaderProgram.ShaderInfo(type); /** Client-side clone of state for debug / perf reasons. */
+ this.shader = gl.createShader(gluShaderProgram.getGLShaderType(gl, type));
+ assertMsgOptions(gl.getError() == gl.NO_ERROR, 'gl.createShader()', false, true);
+
+ this.setSources = function(source) {
+ this.gl.shaderSource(this.shader, source);
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'glshaderSource()', false, true);
+ this.info.source = source;
+ };
+
+ this.getCompileStatus = function() {
+ return this.info.compileOk;
+ };
+
+ this.compile = function() {
+ this.info.compileOk = false;
+ this.info.compileTimeUs = 0;
+ this.info.infoLog = '';
+
+ /** @type {Date} */ var compileStart = new Date();
+ this.gl.compileShader(this.shader);
+ /** @type {Date} */ var compileEnd = new Date();
+ this.info.compileTimeUs = 1000 * (compileEnd.getTime() - compileStart.getTime());
+
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.compileShader()', false, true);
+
+ var compileStatus = this.gl.getShaderParameter(this.shader, this.gl.COMPILE_STATUS);
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'glGetShaderParameter()', false, true);
+
+ this.info.compileOk = compileStatus;
+ this.info.infoLog = this.gl.getShaderInfoLog(this.shader);
+ };
+
+ this.getShader = function() {
+ return this.shader;
+ };
+
+ this.destroy = function() {
+ this.gl.deleteShader(this.shader);
+ };
+
+};
+/**
+ * Creates gluShaderProgram.ProgramInfo
+ * @constructor
+ */
+gluShaderProgram.ProgramInfo = function() {
+ /** @type {string} */ this.infoLog = ''; /** Link info log. */
+ /** @type {boolean} */ this.linkOk = false; /** Did link succeed? */
+ /** @type {number} */ this.linkTimeUs = 0; /** Link time in microseconds (us). */
+};
+
+/**
+ * Creates program.
+ * Inner methods: attach shaders, bind attributes location, link program and transform Feedback Varyings
+ * @constructor
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {WebGLProgram=} programID
+ */
+gluShaderProgram.Program = function(gl, programID) {
+ this.gl = gl;
+ this.program = programID || null;
+ this.info = new gluShaderProgram.ProgramInfo();
+
+ if (!programID) {
+ this.program = gl.createProgram();
+ assertMsgOptions(gl.getError() == gl.NO_ERROR, 'gl.createProgram()', false, true);
+ }
+};
+
+/**
+ * @return {WebGLProgram}
+ */
+gluShaderProgram.Program.prototype.getProgram = function() { return this.program; };
+
+/**
+ * @return {gluShaderProgram.ProgramInfo}
+ */
+gluShaderProgram.Program.prototype.getInfo = function() { return this.info; };
+
+/**
+ * @param {WebGLShader} shader
+ */
+gluShaderProgram.Program.prototype.attachShader = function(shader) {
+ this.gl.attachShader(this.program, shader);
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.attachShader()', false, true);
+};
+
+/**
+ * @param {WebGLShader} shader
+ */
+gluShaderProgram.Program.prototype.detachShader = function(shader) {
+ this.gl.detachShader(this.program, shader);
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.detachShader()', false, true);
+};
+
+/**
+ * @param {number} location
+ * @param {string} name
+ */
+gluShaderProgram.Program.prototype.bindAttribLocation = function(location, name) {
+ this.gl.bindAttribLocation(this.program, location, name);
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.bindAttribLocation()', false, true);
+};
+
+gluShaderProgram.Program.prototype.link = function() {
+ this.info.linkOk = false;
+ this.info.linkTimeUs = 0;
+ this.info.infoLog = '';
+
+ /** @type {Date} */ var linkStart = new Date();
+ this.gl.linkProgram(this.program);
+ /** @type {Date} */ var linkEnd = new Date();
+ this.info.linkTimeUs = 1000 * (linkEnd.getTime() - linkStart.getTime());
+
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.linkProgram()', false, true);
+
+ var linkStatus = this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS);
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.getProgramParameter()', false, true);
+ this.info.linkOk = linkStatus;
+ this.info.infoLog = this.gl.getProgramInfoLog(this.program);
+ if (!this.info.linkOk)
+ bufferedLogToConsole("program linking: " + this.info.infoLog);
+};
+
+/**
+ * return {boolean}
+ */
+gluShaderProgram.Program.prototype.getLinkStatus = function() {
+ return this.info.linkOk;
+};
+
+/**
+ * @param {Array<string>} varyings
+ * @param {number} bufferMode
+ */
+gluShaderProgram.Program.prototype.transformFeedbackVaryings = function(varyings, bufferMode) {
+ this.gl.transformFeedbackVaryings(this.program, varyings, bufferMode);
+ assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.transformFeedbackVaryings()', false, true);
+};
+
+/**
+ * Assigns gl WebGL context and programSources. Declares array of shaders and new program()
+ * @constructor
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluShaderProgram.ProgramSources} programSources
+ */
+gluShaderProgram.ShaderProgram = function(gl, programSources) {
+ this.gl = gl;
+ this.programSources = programSources;
+ this.shaders = [];
+ this.program = new gluShaderProgram.Program(gl);
+
+ /** @type {boolean} */ this.shadersOK = true;
+
+ for (var i = 0; i < programSources.sources.length; i++) {
+ /** @type {gluShaderProgram.Shader} */ var shader = new gluShaderProgram.Shader(gl, programSources.sources[i].type);
+ shader.setSources(programSources.sources[i].source);
+ shader.compile();
+ this.shaders.push(shader);
+ this.shadersOK = this.shadersOK && shader.getCompileStatus();
+ if (!shader.getCompileStatus()) {
+ bufferedLogToConsole('gluShaderProgram.Shader:\n' + programSources.sources[i].source);
+ bufferedLogToConsole('Compile status: ' + shader.getCompileStatus());
+ bufferedLogToConsole('Shader infoLog: ' + shader.info.infoLog);
+ }
+ }
+
+ if (this.shadersOK) {
+ for (var i = 0; i < this.shaders.length; i++)
+ this.program.attachShader(this.shaders[i].getShader());
+
+ for (var attrib in programSources.attribLocationBindings)
+ this.program.bindAttribLocation(programSources.attribLocationBindings[attrib], attrib);
+
+ if (programSources.transformFeedbackBufferMode)
+ if (programSources.transformFeedbackBufferMode === gl.NONE)
+ assertMsgOptions(programSources.transformFeedbackVaryings.length === 0, 'Transform feedback sanity check', false, true);
+ else
+ this.program.transformFeedbackVaryings(programSources.transformFeedbackVaryings, programSources.transformFeedbackBufferMode);
+
+ /* TODO: GLES 3.1: set separable flag */
+
+ this.program.link();
+
+ }
+};
+
+/**
+ * return {WebGLProgram}
+ */
+gluShaderProgram.ShaderProgram.prototype.getProgram = function() {
+ return this.program.program;
+ };
+
+/**
+ * @return {gluShaderProgram.ProgramInfo}
+ */
+gluShaderProgram.ShaderProgram.prototype.getProgramInfo = function() {
+ return this.program.info;
+};
+
+gluShaderProgram.ShaderProgram.prototype.isOk = function() {
+ return this.shadersOK && this.program.getLinkStatus();
+};
+
+gluShaderProgram.containerTypes = {
+ ATTRIB_LOCATION_BINDING: 0,
+ TRANSFORM_FEEDBACK_MODE: 1,
+ TRANSFORM_FEEDBACK_VARYING: 2,
+ TRANSFORM_FEEDBACK_VARYINGS: 3,
+ SHADER_SOURCE: 4,
+ PROGRAM_SEPARABLE: 5,
+ PROGRAM_SOURCES: 6,
+
+ CONTAINER_TYPE_LAST: 7,
+ ATTACHABLE_BEGIN: 0, // ATTRIB_LOCATION_BINDING
+ ATTACHABLE_END: 5 + 1 // PROGRAM_SEPARABLE + 1
+};
+
+/**
+ * @constructor
+ */
+gluShaderProgram.AttribLocationBinding = function(name, location) {
+ this.name = name;
+ this.location = location;
+
+ this.getContainerType = function() {
+ return gluShaderProgram.containerTypes.ATTRIB_LOCATION_BINDING;
+ };
+};
+
+/**
+ * @constructor
+ */
+gluShaderProgram.TransformFeedbackMode = function(mode) {
+ this.mode = mode;
+
+ this.getContainerType = function() {
+ return gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_MODE;
+ };
+};
+
+/**
+ * @constructor
+ * @param {string} name
+ */
+gluShaderProgram.TransformFeedbackVarying = function(name) {
+ /** @type {string} */ this.name = name;
+
+ this.getContainerType = function() {
+ return gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYING;
+ };
+};
+
+/**
+ * @constructor
+ * @param {Array<string>} array
+ */
+gluShaderProgram.TransformFeedbackVaryings = function(array) {
+ /** @type {Array<string>} */ this.array = array;
+
+ this.getContainerType = function() {
+ return gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYINGS;
+ };
+};
+
+/**
+ * @constructor
+ */
+gluShaderProgram.ProgramSeparable = function(separable) {
+ this.separable = separable;
+
+ this.getContainerType = function() {
+ return gluShaderProgram.containerTypes.PROGRAM_SEPARABLE;
+ };
+};
+
+/**
+ * @constructor
+ */
+gluShaderProgram.VertexSource = function(str) {
+ this.shaderType = gluShaderProgram.shaderType.VERTEX;
+ this.source = str;
+
+ this.getContainerType = function() {
+ return gluShaderProgram.containerTypes.SHADER_SOURCE;
+ };
+};
+
+/**
+ * @constructor
+ */
+gluShaderProgram.FragmentSource = function(str) {
+ this.shaderType = gluShaderProgram.shaderType.FRAGMENT;
+ this.source = str;
+
+ this.getContainerType = function() {
+ return gluShaderProgram.containerTypes.SHADER_SOURCE;
+ };
+};
+
+/**
+ * Create gluShaderProgram.ProgramSources.
+ * @constructor
+ */
+gluShaderProgram.ProgramSources = function() {
+ /** @type {Array<gluShaderProgram.ShaderInfo>} */ this.sources = [];
+ this.attribLocationBindings = [];
+ /** @type {Array<string>} */ this.transformFeedbackVaryings = [];
+ this.transformFeedbackBufferMode = 0;
+ this.separable = false;
+};
+
+gluShaderProgram.ProgramSources.prototype.getContainerType = function() {
+ return gluShaderProgram.containerTypes.PROGRAM_SOURCES;
+};
+
+gluShaderProgram.ProgramSources.prototype.add = function(item) {
+ var type = undefined;
+ if (typeof(item.getContainerType) == 'function') {
+ type = item.getContainerType();
+ if (
+ typeof(type) != 'number' ||
+ type < gluShaderProgram.containerTypes.ATTACHABLE_BEGIN ||
+ type >= gluShaderProgram.containerTypes.ATTACHABLE_END
+ ) {
+ type = undefined;
+ }
+ }
+
+ switch (type) {
+ case gluShaderProgram.containerTypes.ATTRIB_LOCATION_BINDING:
+ this.attribLocationBindings.push(item);
+ break;
+
+ case gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_MODE:
+ this.transformFeedbackBufferMode = item.mode;
+ break;
+
+ case gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYING:
+ this.transformFeedbackVaryings.push(item.name);
+ break;
+
+ case gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYINGS:
+ this.transformFeedbackVaryings = this.transformFeedbackVaryings.concat(item.array);
+ break;
+
+ case gluShaderProgram.containerTypes.SHADER_SOURCE:
+ this.sources.push(new gluShaderProgram.ShaderInfo(item.shaderType, item.source));
+ break;
+
+ case gluShaderProgram.containerTypes.PROGRAM_SEPARABLE:
+ this.separable = item.separable;
+ break;
+
+ default:
+ throw new Error('Type \"' + type + '\" cannot be added to gluShaderProgram.ProgramSources.');
+ break;
+ }
+
+ return this;
+};
+
+/**
+ * //! Helper for constructing vertex-fragment source pair.
+ * @param {string} vertexSrc
+ * @param {string} fragmentSrc
+ * @return {gluShaderProgram.ProgramSources}
+ */
+gluShaderProgram.makeVtxFragSources = function(vertexSrc, fragmentSrc) {
+ /** @type  {gluShaderProgram.ProgramSources} */ var sources = new gluShaderProgram.ProgramSources();
+ sources.sources.push(gluShaderProgram.genVertexSource(vertexSrc));
+ sources.sources.push(gluShaderProgram.genFragmentSource(fragmentSrc));
+ return sources;
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderUtil.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderUtil.js
new file mode 100644
index 0000000000..1604dbc613
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderUtil.js
@@ -0,0 +1,795 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluShaderUtil');
+goog.require('framework.delibs.debase.deMath');
+
+goog.scope(function() {
+
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var deMath = framework.delibs.debase.deMath;
+
+/**
+ * ShadingLanguageVersion
+ * @enum
+ */
+gluShaderUtil.GLSLVersion = {
+ V100_ES: 0, //!< GLSL ES 1.0
+ V300_ES: 1 //!< GLSL ES 3.0
+};
+
+/**
+ * gluShaderUtil.glslVersionUsesInOutQualifiers
+ * @param {gluShaderUtil.GLSLVersion} version
+ * @return {boolean}
+ */
+gluShaderUtil.glslVersionUsesInOutQualifiers = function(version) {
+ return version == gluShaderUtil.GLSLVersion.V300_ES;
+};
+
+/**
+ * gluShaderUtil.isGLSLVersionSupported
+ * @param {WebGL2RenderingContext|WebGLRenderingContextBase} ctx
+ * @param {gluShaderUtil.GLSLVersion} version
+ * @return {boolean}
+ */
+gluShaderUtil.isGLSLVersionSupported = function(ctx, version) {
+ return version <= gluShaderUtil.getGLSLVersion(ctx);
+};
+
+/**
+ * gluShaderUtil.getGLSLVersion - Returns a gluShaderUtil.GLSLVersion based on a given webgl context.
+ * @param {WebGL2RenderingContext|WebGLRenderingContextBase} gl
+ * @return {gluShaderUtil.GLSLVersion}
+ */
+gluShaderUtil.getGLSLVersion = function(gl) {
+ var glslversion = gl.getParameter(gl.SHADING_LANGUAGE_VERSION);
+
+ // TODO: Versions are not yet well implemented... Firefox returns GLSL ES 1.0 in some cases,
+ // and Chromium returns GLSL ES 2.0 in some cases. Returning the right version for
+ // testing.
+ // return gluShaderUtil.GLSLVersion.V300_ES;
+
+ if (glslversion.indexOf('WebGL GLSL ES 1.0') != -1) return gluShaderUtil.GLSLVersion.V100_ES;
+ if (glslversion.indexOf('WebGL GLSL ES 3.0') != -1) return gluShaderUtil.GLSLVersion.V300_ES;
+
+ throw new Error('Invalid WebGL version');
+};
+
+/**
+ * gluShaderUtil.getGLSLVersionDeclaration - Returns a string declaration for the glsl version in a shader.
+ * @param {gluShaderUtil.GLSLVersion} version
+ * @return {string}
+ */
+gluShaderUtil.getGLSLVersionDeclaration = function(version) {
+ /** @type {Array<string>} */ var s_decl =
+ [
+ '#version 100',
+ '#version 300 es'
+ ];
+
+ if (version > s_decl.length - 1)
+ throw new Error('Unsupported GLSL version.');
+
+ return s_decl[version];
+};
+
+/**
+ * gluShaderUtil.getGLSLVersionString - Returns the same thing as
+ * getGLSLVersionDeclaration() but without the substring '#version'
+ * @param {gluShaderUtil.GLSLVersion} version
+ * @return {string}
+ */
+gluShaderUtil.getGLSLVersionString = function(version) {
+ /** @type {Array<string>} */ var s_decl =
+ [
+ '100',
+ '300 es'
+ ];
+
+ if (version > s_decl.length - 1)
+ throw new Error('Unsupported GLSL version.');
+
+ return s_decl[version];
+};
+
+/**
+ * @enum
+ */
+gluShaderUtil.precision = {
+ PRECISION_LOWP: 0,
+ PRECISION_MEDIUMP: 1,
+ PRECISION_HIGHP: 2
+};
+
+gluShaderUtil.getPrecisionName = function(prec) {
+ var s_names = [
+ 'lowp',
+ 'mediump',
+ 'highp'
+ ];
+
+ return s_names[prec];
+};
+
+/**
+ * The Type constants
+ * @enum {number}
+ */
+gluShaderUtil.DataType = {
+ INVALID: 0,
+
+ FLOAT: 1,
+ FLOAT_VEC2: 2,
+ FLOAT_VEC3: 3,
+ FLOAT_VEC4: 4,
+ FLOAT_MAT2: 5,
+ FLOAT_MAT2X3: 6,
+ FLOAT_MAT2X4: 7,
+ FLOAT_MAT3X2: 8,
+ FLOAT_MAT3: 9,
+ FLOAT_MAT3X4: 10,
+ FLOAT_MAT4X2: 11,
+ FLOAT_MAT4X3: 12,
+ FLOAT_MAT4: 13,
+
+ INT: 14,
+ INT_VEC2: 15,
+ INT_VEC3: 16,
+ INT_VEC4: 17,
+
+ UINT: 18,
+ UINT_VEC2: 19,
+ UINT_VEC3: 20,
+ UINT_VEC4: 21,
+
+ BOOL: 22,
+ BOOL_VEC2: 23,
+ BOOL_VEC3: 24,
+ BOOL_VEC4: 25,
+
+ SAMPLER_2D: 26,
+ SAMPLER_CUBE: 27,
+ SAMPLER_2D_ARRAY: 28,
+ SAMPLER_3D: 29,
+
+ SAMPLER_2D_SHADOW: 30,
+ SAMPLER_CUBE_SHADOW: 31,
+ SAMPLER_2D_ARRAY_SHADOW: 32,
+
+ INT_SAMPLER_2D: 33,
+ INT_SAMPLER_CUBE: 34,
+ INT_SAMPLER_2D_ARRAY: 35,
+ INT_SAMPLER_3D: 36,
+
+ UINT_SAMPLER_2D: 37,
+ UINT_SAMPLER_CUBE: 38,
+ UINT_SAMPLER_2D_ARRAY: 39,
+ UINT_SAMPLER_3D: 40
+};
+
+/**
+ * Returns type of float scalars
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {string} type of float scalar
+ */
+gluShaderUtil.getDataTypeFloatScalars = function(dataType) {
+
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT: return 'float';
+ case gluShaderUtil.DataType.FLOAT_VEC2: return 'vec2';
+ case gluShaderUtil.DataType.FLOAT_VEC3: return 'vec3';
+ case gluShaderUtil.DataType.FLOAT_VEC4: return 'vec4';
+ case gluShaderUtil.DataType.FLOAT_MAT2: return 'mat2';
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return 'mat2x3';
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return 'mat2x4';
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return 'mat3x2';
+ case gluShaderUtil.DataType.FLOAT_MAT3: return 'mat3';
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return 'mat3x4';
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return 'mat4x2';
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return 'mat4x3';
+ case gluShaderUtil.DataType.FLOAT_MAT4: return 'mat4';
+ case gluShaderUtil.DataType.INT: return 'float';
+ case gluShaderUtil.DataType.INT_VEC2: return 'vec2';
+ case gluShaderUtil.DataType.INT_VEC3: return 'vec3';
+ case gluShaderUtil.DataType.INT_VEC4: return 'vec4';
+ case gluShaderUtil.DataType.UINT: return 'float';
+ case gluShaderUtil.DataType.UINT_VEC2: return 'vec2';
+ case gluShaderUtil.DataType.UINT_VEC3: return 'vec3';
+ case gluShaderUtil.DataType.UINT_VEC4: return 'vec4';
+ case gluShaderUtil.DataType.BOOL: return 'float';
+ case gluShaderUtil.DataType.BOOL_VEC2: return 'vec2';
+ case gluShaderUtil.DataType.BOOL_VEC3: return 'vec3';
+ case gluShaderUtil.DataType.BOOL_VEC4: return 'vec4';
+ }
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+ * gluShaderUtil.getDataTypeVector
+ * @param {gluShaderUtil.DataType} scalarType
+ * @param {number} size
+ * @return {gluShaderUtil.DataType}
+ */
+gluShaderUtil.getDataTypeVector = function(scalarType, size) {
+ var floats = [gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4];
+ var ints = [gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4];
+ var uints = [gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4];
+ var bools = [gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL_VEC2,
+ gluShaderUtil.DataType.BOOL_VEC3,
+ gluShaderUtil.DataType.BOOL_VEC4];
+
+ switch (scalarType) {
+ case gluShaderUtil.DataType.FLOAT: return floats[size - 1];
+ case gluShaderUtil.DataType.INT: return ints[size - 1];
+ case gluShaderUtil.DataType.UINT: return uints[size - 1];
+ case gluShaderUtil.DataType.BOOL: return bools[size - 1];
+ default:
+ throw new Error('Scalar type is not a vectoe:' + scalarType);
+ }
+};
+
+/**
+ * gluShaderUtil.getDataTypeFloatVec
+ * @param {number} vecSize
+ * @return {gluShaderUtil.DataType}
+ */
+gluShaderUtil.getDataTypeFloatVec = function(vecSize) {
+ return gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.FLOAT, vecSize);
+};
+
+/**
+ * gluShaderUtil.isDataTypeBoolOrBVec
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {boolean}
+ */
+gluShaderUtil.isDataTypeBoolOrBVec = function(dataType) {
+ return (dataType >= gluShaderUtil.DataType.BOOL) && (dataType <= gluShaderUtil.DataType.BOOL_VEC4);
+};
+
+/**
+ * Returns type of scalar
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {string} type of scalar type
+ */
+gluShaderUtil.getDataTypeScalarType = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT: return 'float';
+ case gluShaderUtil.DataType.FLOAT_VEC2: return 'float';
+ case gluShaderUtil.DataType.FLOAT_VEC3: return 'float';
+ case gluShaderUtil.DataType.FLOAT_VEC4: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT2: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT3: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return 'float';
+ case gluShaderUtil.DataType.FLOAT_MAT4: return 'float';
+ case gluShaderUtil.DataType.INT: return 'int';
+ case gluShaderUtil.DataType.INT_VEC2: return 'int';
+ case gluShaderUtil.DataType.INT_VEC3: return 'int';
+ case gluShaderUtil.DataType.INT_VEC4: return 'int';
+ case gluShaderUtil.DataType.UINT: return 'uint';
+ case gluShaderUtil.DataType.UINT_VEC2: return 'uint';
+ case gluShaderUtil.DataType.UINT_VEC3: return 'uint';
+ case gluShaderUtil.DataType.UINT_VEC4: return 'uint';
+ case gluShaderUtil.DataType.BOOL: return 'bool';
+ case gluShaderUtil.DataType.BOOL_VEC2: return 'bool';
+ case gluShaderUtil.DataType.BOOL_VEC3: return 'bool';
+ case gluShaderUtil.DataType.BOOL_VEC4: return 'bool';
+ case gluShaderUtil.DataType.SAMPLER_2D: return 'sampler2D';
+ case gluShaderUtil.DataType.SAMPLER_CUBE: return 'samplerCube';
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY: return 'sampler2DArray';
+ case gluShaderUtil.DataType.SAMPLER_3D: return 'sampler3D';
+ case gluShaderUtil.DataType.SAMPLER_2D_SHADOW: return 'sampler2DShadow';
+ case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW: return 'samplerCubeShadow';
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW: return 'sampler2DArrayShadow';
+ case gluShaderUtil.DataType.INT_SAMPLER_2D: return 'isampler2D';
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE: return 'isamplerCube';
+ case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY: return 'isampler2DArray';
+ case gluShaderUtil.DataType.INT_SAMPLER_3D: return 'isampler3D';
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D: return 'usampler2D';
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE: return 'usamplerCube';
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY: return 'usampler2DArray';
+ case gluShaderUtil.DataType.UINT_SAMPLER_3D: return 'usampler3D';
+ }
+ throw new Error('Unrecognized datatype:' + dataType);
+};
+
+/**
+ * Returns type of scalar
+ * @param {?gluShaderUtil.DataType} dataType shader
+ * @return {gluShaderUtil.DataType} type of scalar type
+ */
+gluShaderUtil.getDataTypeScalarTypeAsDataType = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_VEC2: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_VEC3: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_VEC4: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT2: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT3: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.FLOAT_MAT4: return gluShaderUtil.DataType.FLOAT;
+ case gluShaderUtil.DataType.INT: return gluShaderUtil.DataType.INT;
+ case gluShaderUtil.DataType.INT_VEC2: return gluShaderUtil.DataType.INT;
+ case gluShaderUtil.DataType.INT_VEC3: return gluShaderUtil.DataType.INT;
+ case gluShaderUtil.DataType.INT_VEC4: return gluShaderUtil.DataType.INT;
+ case gluShaderUtil.DataType.UINT: return gluShaderUtil.DataType.UINT;
+ case gluShaderUtil.DataType.UINT_VEC2: return gluShaderUtil.DataType.UINT;
+ case gluShaderUtil.DataType.UINT_VEC3: return gluShaderUtil.DataType.UINT;
+ case gluShaderUtil.DataType.UINT_VEC4: return gluShaderUtil.DataType.UINT;
+ case gluShaderUtil.DataType.BOOL: return gluShaderUtil.DataType.BOOL;
+ case gluShaderUtil.DataType.BOOL_VEC2: return gluShaderUtil.DataType.BOOL;
+ case gluShaderUtil.DataType.BOOL_VEC3: return gluShaderUtil.DataType.BOOL;
+ case gluShaderUtil.DataType.BOOL_VEC4: return gluShaderUtil.DataType.BOOL;
+ case gluShaderUtil.DataType.SAMPLER_2D:
+ case gluShaderUtil.DataType.SAMPLER_CUBE:
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.SAMPLER_3D:
+ case gluShaderUtil.DataType.SAMPLER_2D_SHADOW:
+ case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW:
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW:
+ case gluShaderUtil.DataType.INT_SAMPLER_2D:
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE:
+ case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.INT_SAMPLER_3D:
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D:
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE:
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.UINT_SAMPLER_3D:
+ return dataType;
+ }
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+ * Checks if dataType is integer or vectors of integers
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType integer or integer vector
+ */
+gluShaderUtil.isDataTypeIntOrIVec = function(dataType) {
+ /** @type {boolean} */ var retVal = false;
+ switch (dataType) {
+ case gluShaderUtil.DataType.INT:
+ case gluShaderUtil.DataType.INT_VEC2:
+ case gluShaderUtil.DataType.INT_VEC3:
+ case gluShaderUtil.DataType.INT_VEC4:
+ retVal = true;
+ }
+
+ return retVal;
+};
+
+/**
+ * Checks if dataType is unsigned integer or vectors of unsigned integers
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType unsigned integer or unsigned integer vector
+ */
+gluShaderUtil.isDataTypeUintOrUVec = function(dataType) {
+ /** @type {boolean} */ var retVal = false;
+ switch (dataType) {
+ case gluShaderUtil.DataType.UINT:
+ case gluShaderUtil.DataType.UINT_VEC2:
+ case gluShaderUtil.DataType.UINT_VEC3:
+ case gluShaderUtil.DataType.UINT_VEC4:
+ retVal = true;
+ }
+
+ return retVal;
+};
+
+/**
+* Returns type of scalar size
+* @param {gluShaderUtil.DataType} dataType shader
+* @return {number} with size of the type of scalar
+*/
+gluShaderUtil.getDataTypeScalarSize = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT: return 1;
+ case gluShaderUtil.DataType.FLOAT_VEC2: return 2;
+ case gluShaderUtil.DataType.FLOAT_VEC3: return 3;
+ case gluShaderUtil.DataType.FLOAT_VEC4: return 4;
+ case gluShaderUtil.DataType.FLOAT_MAT2: return 4;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return 6;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return 8;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return 6;
+ case gluShaderUtil.DataType.FLOAT_MAT3: return 9;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return 12;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return 8;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return 12;
+ case gluShaderUtil.DataType.FLOAT_MAT4: return 16;
+ case gluShaderUtil.DataType.INT: return 1;
+ case gluShaderUtil.DataType.INT_VEC2: return 2;
+ case gluShaderUtil.DataType.INT_VEC3: return 3;
+ case gluShaderUtil.DataType.INT_VEC4: return 4;
+ case gluShaderUtil.DataType.UINT: return 1;
+ case gluShaderUtil.DataType.UINT_VEC2: return 2;
+ case gluShaderUtil.DataType.UINT_VEC3: return 3;
+ case gluShaderUtil.DataType.UINT_VEC4: return 4;
+ case gluShaderUtil.DataType.BOOL: return 1;
+ case gluShaderUtil.DataType.BOOL_VEC2: return 2;
+ case gluShaderUtil.DataType.BOOL_VEC3: return 3;
+ case gluShaderUtil.DataType.BOOL_VEC4: return 4;
+ case gluShaderUtil.DataType.SAMPLER_2D: return 1;
+ case gluShaderUtil.DataType.SAMPLER_CUBE: return 1;
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY: return 1;
+ case gluShaderUtil.DataType.SAMPLER_3D: return 1;
+ case gluShaderUtil.DataType.SAMPLER_2D_SHADOW: return 1;
+ case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW: return 1;
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW: return 1;
+ case gluShaderUtil.DataType.INT_SAMPLER_2D: return 1;
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE: return 1;
+ case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY: return 1;
+ case gluShaderUtil.DataType.INT_SAMPLER_3D: return 1;
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D: return 1;
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE: return 1;
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY: return 1;
+ case gluShaderUtil.DataType.UINT_SAMPLER_3D: return 1;
+ }
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+ * Checks if dataType is float or vector
+ * @param {?gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType float or vector
+ */
+gluShaderUtil.isDataTypeFloatOrVec = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT:
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ return true;
+ }
+ return false;
+};
+
+/**
+ * Checks if dataType is a matrix
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType matrix or not
+ */
+gluShaderUtil.isDataTypeMatrix = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT_MAT2:
+ case gluShaderUtil.DataType.FLOAT_MAT2X3:
+ case gluShaderUtil.DataType.FLOAT_MAT2X4:
+ case gluShaderUtil.DataType.FLOAT_MAT3X2:
+ case gluShaderUtil.DataType.FLOAT_MAT3:
+ case gluShaderUtil.DataType.FLOAT_MAT3X4:
+ case gluShaderUtil.DataType.FLOAT_MAT4X2:
+ case gluShaderUtil.DataType.FLOAT_MAT4X3:
+ case gluShaderUtil.DataType.FLOAT_MAT4:
+ return true;
+ }
+ return false;
+};
+
+/**
+ * Checks if dataType is a vector
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType vector or not
+ */
+gluShaderUtil.isDataTypeScalar = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT:
+ case gluShaderUtil.DataType.INT:
+ case gluShaderUtil.DataType.UINT:
+ case gluShaderUtil.DataType.BOOL:
+ return true;
+ }
+ return false;
+};
+
+/**
+ * Checks if dataType is a vector
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType vector or not
+ */
+gluShaderUtil.isDataTypeVector = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ case gluShaderUtil.DataType.INT_VEC2:
+ case gluShaderUtil.DataType.INT_VEC3:
+ case gluShaderUtil.DataType.INT_VEC4:
+ case gluShaderUtil.DataType.UINT_VEC2:
+ case gluShaderUtil.DataType.UINT_VEC3:
+ case gluShaderUtil.DataType.UINT_VEC4:
+ case gluShaderUtil.DataType.BOOL_VEC2:
+ case gluShaderUtil.DataType.BOOL_VEC3:
+ case gluShaderUtil.DataType.BOOL_VEC4:
+ return true;
+ }
+ return false;
+};
+
+/**
+ * Checks if dataType is a vector or a scalar type
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType vector or scalar or not
+ */
+gluShaderUtil.isDataTypeScalarOrVector = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT:
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ case gluShaderUtil.DataType.INT:
+ case gluShaderUtil.DataType.INT_VEC2:
+ case gluShaderUtil.DataType.INT_VEC3:
+ case gluShaderUtil.DataType.INT_VEC4:
+ case gluShaderUtil.DataType.UINT:
+ case gluShaderUtil.DataType.UINT_VEC2:
+ case gluShaderUtil.DataType.UINT_VEC3:
+ case gluShaderUtil.DataType.UINT_VEC4:
+ case gluShaderUtil.DataType.BOOL:
+ case gluShaderUtil.DataType.BOOL_VEC2:
+ case gluShaderUtil.DataType.BOOL_VEC3:
+ case gluShaderUtil.DataType.BOOL_VEC4:
+ return true;
+ }
+ return false;
+};
+
+/**
+ * Checks if dataType is a sampler
+ * @param {gluShaderUtil.DataType} dataType shader
+ * @return {boolean} Is dataType vector or scalar or not
+ */
+gluShaderUtil.isDataTypeSampler = function(dataType) {
+ return (dataType >= gluShaderUtil.DataType.SAMPLER_2D) && (dataType <= gluShaderUtil.DataType.UINT_SAMPLER_3D);
+};
+
+/**
+ * Returns a gluShaderUtil.DataType based on given rows and columns
+ * @param {number} numCols
+ * @param {number} numRows
+ * @return {gluShaderUtil.DataType}
+ */
+gluShaderUtil.getDataTypeMatrix = function(numCols, numRows) {
+ if (!(deMath.deInRange32(numCols, 2, 4) && deMath.deInRange32(numRows, 2, 4)))
+ throw new Error('Out of bounds: (' + numCols + ',' + numRows + ')');
+
+ var size = numCols.toString() + 'x' + numRows.toString();
+ var datatypes = {
+ '2x2': gluShaderUtil.DataType.FLOAT_MAT2,
+ '2x3': gluShaderUtil.DataType.FLOAT_MAT2X3,
+ '2x4': gluShaderUtil.DataType.FLOAT_MAT2X4,
+ '3x2': gluShaderUtil.DataType.FLOAT_MAT3X2,
+ '3x3': gluShaderUtil.DataType.FLOAT_MAT3,
+ '3x4': gluShaderUtil.DataType.FLOAT_MAT3X4,
+ '4x2': gluShaderUtil.DataType.FLOAT_MAT4X2,
+ '4x3': gluShaderUtil.DataType.FLOAT_MAT4X3,
+ '4x4': gluShaderUtil.DataType.FLOAT_MAT4
+ };
+ return datatypes[size];
+};
+
+/**
+* Returns number of rows of a gluShaderUtil.DataType Matrix
+* @param {gluShaderUtil.DataType} dataType shader
+* @return {number} with number of rows depending on gluShaderUtil.DataType Matrix
+*/
+gluShaderUtil.getDataTypeMatrixNumRows = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT_MAT2: return 2;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return 3;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return 4;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return 2;
+ case gluShaderUtil.DataType.FLOAT_MAT3: return 3;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return 4;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return 2;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return 3;
+ case gluShaderUtil.DataType.FLOAT_MAT4: return 4;
+ }
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+* Returns number of columns of a gluShaderUtil.DataType Matrix
+* @param {gluShaderUtil.DataType} dataType shader
+* @return {number} with number of columns depending on gluShaderUtil.DataType Matrix
+*/
+gluShaderUtil.getDataTypeMatrixNumColumns = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT_MAT2: return 2;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return 2;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return 2;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return 3;
+ case gluShaderUtil.DataType.FLOAT_MAT3: return 3;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return 3;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return 4;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return 4;
+ case gluShaderUtil.DataType.FLOAT_MAT4: return 4;
+ }
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {number}
+ */
+gluShaderUtil.getDataTypeNumLocations = function(dataType) {
+ if (gluShaderUtil.isDataTypeScalarOrVector(dataType))
+ return 1;
+ else if (gluShaderUtil.isDataTypeMatrix(dataType))
+ return gluShaderUtil.getDataTypeMatrixNumColumns(dataType);
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {number}
+ */
+gluShaderUtil.getDataTypeNumComponents = function(dataType) {
+ if (gluShaderUtil.isDataTypeScalarOrVector(dataType))
+ return gluShaderUtil.getDataTypeScalarSize(dataType);
+ else if (gluShaderUtil.isDataTypeMatrix(dataType))
+ return gluShaderUtil.getDataTypeMatrixNumRows(dataType);
+
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+ * Returns name of the dataType
+ * @param {?gluShaderUtil.DataType} dataType shader
+ * @return {string} dataType name
+ */
+gluShaderUtil.getDataTypeName = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.INVALID: return 'invalid';
+
+ case gluShaderUtil.DataType.FLOAT: return 'float';
+ case gluShaderUtil.DataType.FLOAT_VEC2: return 'vec2';
+ case gluShaderUtil.DataType.FLOAT_VEC3: return 'vec3';
+ case gluShaderUtil.DataType.FLOAT_VEC4: return 'vec4';
+ case gluShaderUtil.DataType.FLOAT_MAT2: return 'mat2';
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return 'mat2x3';
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return 'mat2x4';
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return 'mat3x2';
+ case gluShaderUtil.DataType.FLOAT_MAT3: return 'mat3';
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return 'mat3x4';
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return 'mat4x2';
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return 'mat4x3';
+ case gluShaderUtil.DataType.FLOAT_MAT4: return 'mat4';
+
+ case gluShaderUtil.DataType.INT: return 'int';
+ case gluShaderUtil.DataType.INT_VEC2: return 'ivec2';
+ case gluShaderUtil.DataType.INT_VEC3: return 'ivec3';
+ case gluShaderUtil.DataType.INT_VEC4: return 'ivec4';
+
+ case gluShaderUtil.DataType.UINT: return 'uint';
+ case gluShaderUtil.DataType.UINT_VEC2: return 'uvec2';
+ case gluShaderUtil.DataType.UINT_VEC3: return 'uvec3';
+ case gluShaderUtil.DataType.UINT_VEC4: return 'uvec4';
+
+ case gluShaderUtil.DataType.BOOL: return 'bool';
+ case gluShaderUtil.DataType.BOOL_VEC2: return 'bvec2';
+ case gluShaderUtil.DataType.BOOL_VEC3: return 'bvec3';
+ case gluShaderUtil.DataType.BOOL_VEC4: return 'bvec4';
+
+ case gluShaderUtil.DataType.SAMPLER_2D: return 'sampler2D';
+ case gluShaderUtil.DataType.SAMPLER_CUBE: return 'samplerCube';
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY: return 'sampler2DArray';
+ case gluShaderUtil.DataType.SAMPLER_3D: return 'sampler3D';
+
+ case gluShaderUtil.DataType.SAMPLER_2D_SHADOW: return 'sampler2DShadow';
+ case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW: return 'samplerCubeShadow';
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW: return 'sampler2DArrayShadow';
+
+ case gluShaderUtil.DataType.INT_SAMPLER_2D: return 'isampler2D';
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE: return 'isamplerCube';
+ case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY: return 'isampler2DArray';
+ case gluShaderUtil.DataType.INT_SAMPLER_3D: return 'isampler3D';
+
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D: return 'usampler2D';
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE: return 'usamplerCube';
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY: return 'usampler2DArray';
+ case gluShaderUtil.DataType.UINT_SAMPLER_3D: return 'usampler3D';
+ }
+ throw Error('Unrecognized dataType ' + dataType);
+};
+
+/**
+ * Returns the gluShaderUtil.DataType from the GL type
+ * @param {number} glType
+ * @return {gluShaderUtil.DataType}
+ */
+gluShaderUtil.getDataTypeFromGLType = function(glType) {
+ switch (glType) {
+ case gl.FLOAT: return gluShaderUtil.DataType.FLOAT;
+ case gl.FLOAT_VEC2: return gluShaderUtil.DataType.FLOAT_VEC2;
+ case gl.FLOAT_VEC3: return gluShaderUtil.DataType.FLOAT_VEC3;
+ case gl.FLOAT_VEC4: return gluShaderUtil.DataType.FLOAT_VEC4;
+
+ case gl.FLOAT_MAT2: return gluShaderUtil.DataType.FLOAT_MAT2;
+ case gl.FLOAT_MAT2x3: return gluShaderUtil.DataType.FLOAT_MAT2X3;
+ case gl.FLOAT_MAT2x4: return gluShaderUtil.DataType.FLOAT_MAT2X4;
+
+ case gl.FLOAT_MAT3x2: return gluShaderUtil.DataType.FLOAT_MAT3X2;
+ case gl.FLOAT_MAT3: return gluShaderUtil.DataType.FLOAT_MAT3;
+ case gl.FLOAT_MAT3x4: return gluShaderUtil.DataType.FLOAT_MAT3X4;
+
+ case gl.FLOAT_MAT4x2: return gluShaderUtil.DataType.FLOAT_MAT4X2;
+ case gl.FLOAT_MAT4x3: return gluShaderUtil.DataType.FLOAT_MAT4X3;
+ case gl.FLOAT_MAT4: return gluShaderUtil.DataType.FLOAT_MAT4;
+
+ case gl.INT: return gluShaderUtil.DataType.INT;
+ case gl.INT_VEC2: return gluShaderUtil.DataType.INT_VEC2;
+ case gl.INT_VEC3: return gluShaderUtil.DataType.INT_VEC3;
+ case gl.INT_VEC4: return gluShaderUtil.DataType.INT_VEC4;
+
+ case gl.UNSIGNED_INT: return gluShaderUtil.DataType.UINT;
+ case gl.UNSIGNED_INT_VEC2: return gluShaderUtil.DataType.UINT_VEC2;
+ case gl.UNSIGNED_INT_VEC3: return gluShaderUtil.DataType.UINT_VEC3;
+ case gl.UNSIGNED_INT_VEC4: return gluShaderUtil.DataType.UINT_VEC4;
+
+ case gl.BOOL: return gluShaderUtil.DataType.BOOL;
+ case gl.BOOL_VEC2: return gluShaderUtil.DataType.BOOL_VEC2;
+ case gl.BOOL_VEC3: return gluShaderUtil.DataType.BOOL_VEC3;
+ case gl.BOOL_VEC4: return gluShaderUtil.DataType.BOOL_VEC4;
+
+ case gl.SAMPLER_2D: return gluShaderUtil.DataType.SAMPLER_2D;
+ case gl.SAMPLER_CUBE: return gluShaderUtil.DataType.SAMPLER_CUBE;
+ case gl.SAMPLER_2D_ARRAY: return gluShaderUtil.DataType.SAMPLER_2D_ARRAY;
+ case gl.SAMPLER_3D: return gluShaderUtil.DataType.SAMPLER_3D;
+
+ case gl.SAMPLER_2D_SHADOW: return gluShaderUtil.DataType.SAMPLER_2D_SHADOW;
+ case gl.SAMPLER_CUBE_SHADOW: return gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW;
+ case gl.SAMPLER_2D_ARRAY_SHADOW: return gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW;
+
+ case gl.INT_SAMPLER_2D: return gluShaderUtil.DataType.INT_SAMPLER_2D;
+ case gl.INT_SAMPLER_CUBE: return gluShaderUtil.DataType.INT_SAMPLER_CUBE;
+ case gl.INT_SAMPLER_2D_ARRAY: return gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY;
+ case gl.INT_SAMPLER_3D: return gluShaderUtil.DataType.INT_SAMPLER_3D;
+
+ case gl.UNSIGNED_INT_SAMPLER_2D: return gluShaderUtil.DataType.UINT_SAMPLER_2D;
+ case gl.UNSIGNED_INT_SAMPLER_CUBE: return gluShaderUtil.DataType.UINT_SAMPLER_CUBE;
+ case gl.UNSIGNED_INT_SAMPLER_2D_ARRAY: return gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY;
+ case gl.UNSIGNED_INT_SAMPLER_3D: return gluShaderUtil.DataType.UINT_SAMPLER_3D;
+
+ default:
+ throw new Error('Unrecognized GL type:' + glType);
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluStrUtil.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluStrUtil.js
new file mode 100644
index 0000000000..b554db047a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluStrUtil.js
@@ -0,0 +1,166 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluStrUtil');
+
+goog.scope(function() {
+
+var gluStrUtil = framework.opengl.gluStrUtil;
+
+gluStrUtil.getPixelFormatName = function(value) {
+ switch (value) {
+ case gl.LUMINANCE: return 'gl.LUMINANCE';
+ case gl.LUMINANCE_ALPHA: return 'gl.LUMINANCE_ALPHA';
+ case gl.ALPHA: return 'gl.ALPHA';
+ case gl.RGB: return 'gl.RGB';
+ case gl.RGBA: return 'gl.RGBA';
+ case gl.RGBA4: return 'gl.RGBA4';
+ case gl.RGB5_A1: return 'gl.RGB5_A1';
+ case gl.RGB565: return 'gl.RGB565';
+ case gl.DEPTH_COMPONENT16: return 'gl.DEPTH_COMPONENT16';
+ case gl.STENCIL_INDEX8: return 'gl.STENCIL_INDEX8';
+ case gl.RG: return 'gl.RG';
+ case gl.RED: return 'gl.RED';
+ case gl.RGBA_INTEGER: return 'gl.RGBA_INTEGER';
+ case gl.RGB_INTEGER: return 'gl.RGB_INTEGER';
+ case gl.RG_INTEGER: return 'gl.RG_INTEGER';
+ case gl.RED_INTEGER: return 'gl.RED_INTEGER';
+ case gl.DEPTH_COMPONENT: return 'gl.DEPTH_COMPONENT';
+ case gl.DEPTH_STENCIL: return 'gl.DEPTH_STENCIL';
+ case gl.RGBA32F: return 'gl.RGBA32F';
+ case gl.RGBA32I: return 'gl.RGBA32I';
+ case gl.RGBA32UI: return 'gl.RGBA32UI';
+ // case gl.RGBA16: return 'gl.RGBA16';
+ // case gl.RGBA16_SNORM: return 'gl.RGBA16_SNORM';
+ case gl.RGBA16F: return 'gl.RGBA16F';
+ case gl.RGBA16I: return 'gl.RGBA16I';
+ case gl.RGBA16UI: return 'gl.RGBA16UI';
+ case gl.RGBA8: return 'gl.RGBA8';
+ case gl.RGBA8I: return 'gl.RGBA8I';
+ case gl.RGBA8UI: return 'gl.RGBA8UI';
+ case gl.SRGB8_ALPHA8: return 'gl.SRGB8_ALPHA8';
+ case gl.RGB10_A2: return 'gl.RGB10_A2';
+ case gl.RGB10_A2UI: return 'gl.RGB10_A2UI';
+ case gl.RGBA8_SNORM: return 'gl.RGBA8_SNORM';
+ case gl.RGB8: return 'gl.RGB8';
+ case gl.R11F_G11F_B10F: return 'gl.R11F_G11F_B10F';
+ case gl.RGB32F: return 'gl.RGB32F';
+ case gl.RGB32I: return 'gl.RGB32I';
+ case gl.RGB32UI: return 'gl.RGB32UI';
+ // case gl.RGB16: return 'gl.RGB16';
+ // case gl.RGB16_SNORM: return 'gl.RGB16_SNORM';
+ case gl.RGB16F: return 'gl.RGB16F';
+ case gl.RGB16I: return 'gl.RGB16I';
+ case gl.RGB16UI: return 'gl.RGB16UI';
+ case gl.RGB8_SNORM: return 'gl.RGB8_SNORM';
+ case gl.RGB8I: return 'gl.RGB8I';
+ case gl.RGB8UI: return 'gl.RGB8UI';
+ case gl.SRGB8: return 'gl.SRGB8';
+ case gl.RGB9_E5: return 'gl.RGB9_E5';
+ case gl.RG32F: return 'gl.RG32F';
+ case gl.RG32I: return 'gl.RG32I';
+ case gl.RG32UI: return 'gl.RG32UI';
+ // case gl.RG16: return 'gl.RG16';
+ // case gl.RG16_SNORM: return 'gl.RG16_SNORM';
+ case gl.RG16F: return 'gl.RG16F';
+ case gl.RG16I: return 'gl.RG16I';
+ case gl.RG16UI: return 'gl.RG16UI';
+ case gl.RG8: return 'gl.RG8';
+ case gl.RG8I: return 'gl.RG8I';
+ case gl.RG8UI: return 'gl.RG8UI';
+ case gl.RG8_SNORM: return 'gl.RG8_SNORM';
+ case gl.R32F: return 'gl.R32F';
+ case gl.R32I: return 'gl.R32I';
+ case gl.R32UI: return 'gl.R32UI';
+ // case gl.R16: return 'gl.R16';
+ // case gl.R16_SNORM: return 'gl.R16_SNORM';
+ case gl.R16F: return 'gl.R16F';
+ case gl.R16I: return 'gl.R16I';
+ case gl.R16UI: return 'gl.R16UI';
+ case gl.R8: return 'gl.R8';
+ case gl.R8I: return 'gl.R8I';
+ case gl.R8UI: return 'gl.R8UI';
+ case gl.R8_SNORM: return 'gl.R8_SNORM';
+ case gl.DEPTH_COMPONENT32F: return 'gl.DEPTH_COMPONENT32F';
+ case gl.DEPTH_COMPONENT24: return 'gl.DEPTH_COMPONENT24';
+ case gl.DEPTH32F_STENCIL8: return 'gl.DEPTH32F_STENCIL8';
+ case gl.DEPTH24_STENCIL8: return 'gl.DEPTH24_STENCIL8';
+ // case gl.RGB10: return 'gl.RGB10';
+ // case gl.DEPTH_COMPONENT32: return 'gl.DEPTH_COMPONENT32';
+ case gl.SRGB: return 'gl.SRGB';
+ // case gl.SRGB_ALPHA: return 'gl.SRGB_ALPHA';
+ default: return '';
+ }
+};
+
+gluStrUtil.getTypeName = function(value) {
+ switch (value) {
+ case gl.BYTE: return 'gl.BYTE';
+ case gl.UNSIGNED_BYTE: return 'gl.UNSIGNED_BYTE';
+ case gl.SHORT: return 'gl.SHORT';
+ case gl.UNSIGNED_SHORT: return 'gl.UNSIGNED_SHORT';
+ case gl.INT: return 'gl.INT';
+ case gl.UNSIGNED_INT: return 'gl.UNSIGNED_INT';
+ case gl.FLOAT: return 'gl.FLOAT';
+ // case gl.FIXED: return 'gl.FIXED';
+ case gl.UNSIGNED_SHORT_5_6_5: return 'gl.UNSIGNED_SHORT_5_6_5';
+ case gl.UNSIGNED_SHORT_4_4_4_4: return 'gl.UNSIGNED_SHORT_4_4_4_4';
+ case gl.UNSIGNED_SHORT_5_5_5_1: return 'gl.UNSIGNED_SHORT_5_5_5_1';
+ case gl.HALF_FLOAT: return 'gl.HALF_FLOAT';
+ case gl.INT_2_10_10_10_REV: return 'gl.INT_2_10_10_10_REV';
+ case gl.UNSIGNED_INT_2_10_10_10_REV: return 'gl.UNSIGNED_INT_2_10_10_10_REV';
+ case gl.UNSIGNED_INT_10F_11F_11F_REV: return 'gl.UNSIGNED_INT_10F_11F_11F_REV';
+ case gl.UNSIGNED_INT_5_9_9_9_REV: return 'gl.UNSIGNED_INT_5_9_9_9_REV';
+ case gl.UNSIGNED_INT_24_8: return 'gl.UNSIGNED_INT_24_8';
+ case gl.FLOAT_32_UNSIGNED_INT_24_8_REV: return 'gl.FLOAT_32_UNSIGNED_INT_24_8_REV';
+ case gl.SIGNED_NORMALIZED: return 'gl.SIGNED_NORMALIZED';
+ case gl.UNSIGNED_NORMALIZED: return 'gl.UNSIGNED_NORMALIZED';
+ // case gl.HALF_FLOAT_OES: return 'gl.HALF_FLOAT_OES';
+ default: return '';
+ }
+};
+
+gluStrUtil.getErrorName = function(value) {
+ switch (value) {
+ case gl.NO_ERROR: return 'gl.NO_ERROR';
+ case gl.INVALID_ENUM: return 'gl.INVALID_ENUM';
+ case gl.INVALID_VALUE: return 'gl.INVALID_VALUE';
+ case gl.INVALID_OPERATION: return 'gl.INVALID_OPERATION';
+ case gl.OUT_OF_MEMORY: return 'gl.OUT_OF_MEMORY';
+ // case gl.INVALID_FRAMEBUFFER_OPERATION: return 'gl.INVALID_FRAMEBUFFER_OPERATION';
+ default: return '';
+ }
+};
+
+gluStrUtil.getFramebufferStatusName = function(value) {
+ switch (value) {
+ case gl.FRAMEBUFFER_COMPLETE: return 'gl.FRAMEBUFFER_COMPLETE';
+ case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return 'gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT';
+ case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return 'gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT';
+ case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: return 'gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS';
+ case gl.FRAMEBUFFER_UNSUPPORTED: return 'gl.FRAMEBUFFER_UNSUPPORTED';
+ case gl.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: return 'gl.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE';
+ // case: gl.FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: return 'gl.FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS';
+ default: return '';
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTexture.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTexture.js
new file mode 100644
index 0000000000..fcc33588e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTexture.js
@@ -0,0 +1,380 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluTexture');
+goog.require('framework.common.tcuCompressedTexture');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluTextureUtil');
+
+goog.scope(function() {
+
+var gluTexture = framework.opengl.gluTexture;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuTexture = framework.common.tcuTexture;
+var tcuCompressedTexture = framework.common.tcuCompressedTexture;
+var deMath = framework.delibs.debase.deMath;
+
+var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+};
+
+/** @enum {number} */
+gluTexture.Type = {
+ TYPE_NONE: 0,
+ TYPE_2D: 1,
+ TYPE_CUBE_MAP: 2,
+ TYPE_2D_ARRAY: 3,
+ TYPE_3D: 4
+};
+
+/**
+ * @constructor
+ */
+gluTexture.Texture2D = function(gl, format, isCompressed, refTexture) {
+ this.gl = gl;
+ this.m_glTexture = gl.createTexture();
+ this.m_isCompressed = isCompressed;
+ this.m_format = format; // Internal format
+ this.m_refTexture = refTexture;
+ this.m_type = gluTexture.Type.TYPE_2D;
+};
+
+gluTexture.Texture2D.prototype.getType = function() {
+ return this.m_type;
+};
+
+gluTexture.Texture2D.prototype.getRefTexture = function() {
+ return this.m_refTexture;
+};
+
+gluTexture.Texture2D.prototype.getGLTexture = function() {
+ return this.m_glTexture;
+};
+
+gluTexture.texture2DFromFormat = function(gl, format, dataType, width, height) {
+ var tex = new gluTexture.Texture2D(gl, format, false, new tcuTexture.Texture2D(gluTextureUtil.mapGLTransferFormat(format, dataType), width, height));
+ return tex;
+};
+
+gluTexture.texture2DFromInternalFormat = function(gl, internalFormat, width, height) {
+ var tex = new gluTexture.Texture2D(gl, internalFormat, false, new tcuTexture.Texture2D(gluTextureUtil.mapGLInternalFormat(internalFormat), width, height));
+ return tex;
+};
+
+/**
+ * @param {number} numLevels
+ * @param {Array<tcuCompressedTexture.CompressedTexture>} levels
+ * @return {gluTexture.Texture2D}
+ */
+gluTexture.texture2DFromCompressedTexture = function(gl, numLevels, levels) {
+ var level = levels[0];
+ var format = gluTextureUtil.getGLFormat(level.getFormat());
+ var refTex = new tcuTexture.Texture2D(level.getUncompressedFormat(), level.getWidth(), level.getHeight());
+ /** @type {gluTexture.Texture2D} */ var tex2d = new gluTexture.Texture2D(gl, format, true, refTex);
+
+ tex2d.loadCompressed(numLevels, levels);
+
+ return tex2d;
+};
+/**
+ * @param {number} numLevels
+ * @param {Array<tcuCompressedTexture.CompressedTexture>} levels
+ */
+gluTexture.Texture2D.prototype.loadCompressed = function(numLevels, levels) {
+ /** @type {number} */ var compressedFormat = gluTextureUtil.getGLFormat(levels[0].getFormat());
+
+ assertMsgOptions(this.m_glTexture, 'm_glTexture not defined', false, true);
+ gl.bindTexture(gl.TEXTURE_2D, this.m_glTexture);
+
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ /** @type {tcuCompressedTexture.CompressedTexture} */ var level = levels[levelNdx];
+
+ // Decompress to reference texture.
+ this.m_refTexture.allocLevel(levelNdx);
+ /** @type {tcuTexture.PixelBufferAccess} */ var refLevelAccess = this.m_refTexture.getLevel(levelNdx);
+ assertMsgOptions(level.getWidth() == refLevelAccess.getWidth() && level.getHeight() == refLevelAccess.getHeight(), 'level and reference sizes not equal', false, true);
+ level.decompress(refLevelAccess);
+
+ // Upload to GL texture in compressed form.
+ gl.compressedTexImage2D(gl.TEXTURE_2D, levelNdx, compressedFormat,
+ level.getWidth(), level.getHeight(), 0, level.getData());
+ }
+};
+
+gluTexture.computePixelStore = function(/*const tcu::TextureFormat&*/ format) {
+ var pixelSize = format.getPixelSize();
+ if (deMath.deIsPowerOfTwo32(pixelSize))
+ return Math.min(pixelSize, 8);
+ else
+ return 1;
+};
+
+gluTexture.cubeFaceToGLFace = function(/*tcu::CubeFace*/ face) {
+ switch (face) {
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: return gl.TEXTURE_CUBE_MAP_NEGATIVE_X;
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: return gl.TEXTURE_CUBE_MAP_POSITIVE_X;
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: return gl.TEXTURE_CUBE_MAP_NEGATIVE_Y;
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: return gl.TEXTURE_CUBE_MAP_POSITIVE_Y;
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: return gl.TEXTURE_CUBE_MAP_NEGATIVE_Z;
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: return gl.TEXTURE_CUBE_MAP_POSITIVE_Z;
+ }
+ throw new Error('Unrecognized face: ' + face);
+};
+
+gluTexture.Texture2D.prototype.upload = function() {
+ DE_ASSERT(!this.m_isCompressed);
+
+ if (this.m_glTexture == null)
+ testFailedOptions('Failed to create GL texture', true);
+
+ gl.bindTexture(gl.TEXTURE_2D, this.m_glTexture);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, gluTexture.computePixelStore(this.m_refTexture.getFormat()));
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Setting pixel store failed', false, true);
+
+ var transferFormat = gluTextureUtil.getTransferFormat(this.m_refTexture.getFormat());
+
+ for (var levelNdx = 0; levelNdx < this.m_refTexture.getNumLevels(); levelNdx++) {
+ if (this.m_refTexture.isLevelEmpty(levelNdx))
+ continue; // Don't upload.
+
+ var access = this.m_refTexture.getLevel(levelNdx);
+ DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize() * access.getWidth());
+ var data = access.getDataPtr();
+ gl.texImage2D(gl.TEXTURE_2D, levelNdx, this.m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
+ }
+
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+};
+
+/**
+ * @constructor
+ * @extends {gluTexture.Texture2D}
+ */
+gluTexture.TextureCube = function(gl, format, isCompressed, refTexture) {
+ gluTexture.Texture2D.call(this, gl, format, isCompressed, refTexture);
+ this.m_type = gluTexture.Type.TYPE_CUBE_MAP;
+};
+
+gluTexture.TextureCube.prototype = Object.create(gluTexture.Texture2D.prototype);
+gluTexture.TextureCube.prototype.constructor = gluTexture.TextureCube;
+
+gluTexture.TextureCube.prototype.upload = function() {
+ DE_ASSERT(!this.m_isCompressed);
+
+ if (this.m_glTexture == null)
+ testFailedOptions('Failed to create GL texture', true);
+
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.m_glTexture);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, gluTexture.computePixelStore(this.m_refTexture.getFormat()));
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Setting pixel store failed', false, true);
+
+ var transferFormat = gluTextureUtil.getTransferFormat(this.m_refTexture.getFormat());
+
+ for (var face in tcuTexture.CubeFace) {
+ for (var levelNdx = 0; levelNdx < this.m_refTexture.getNumLevels(); levelNdx++) {
+ if (this.m_refTexture.isLevelEmpty(tcuTexture.CubeFace[face], levelNdx))
+ continue; // Don't upload.
+
+ /*tcu::ConstPixelBufferAccess*/ var access = this.m_refTexture.getLevelFace(levelNdx, tcuTexture.CubeFace[face]);
+ DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize() * access.getWidth());
+ gl.texImage2D(gluTexture.cubeFaceToGLFace(tcuTexture.CubeFace[face]), levelNdx, this.m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
+ }
+ }
+
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+};
+
+gluTexture.cubeFromFormat = function(gl, format, dataType, size) {
+ var tex = new gluTexture.TextureCube(gl, format, false, new tcuTexture.TextureCube(gluTextureUtil.mapGLTransferFormat(format, dataType), size));
+ return tex;
+};
+
+gluTexture.cubeFromInternalFormat = function(gl, internalFormat, size) {
+ var tex = new gluTexture.TextureCube(gl, internalFormat, false, new tcuTexture.TextureCube(gluTextureUtil.mapGLInternalFormat(internalFormat), size));
+ return tex;
+};
+
+/**
+ * @constructor
+ * @extends {gluTexture.Texture2D}
+ */
+gluTexture.Texture2DArray = function(gl, format, isCompressed, refTexture) {
+ gluTexture.Texture2D.call(this, gl, format, isCompressed, refTexture);
+ this.m_type = gluTexture.Type.TYPE_2D_ARRAY;
+};
+
+gluTexture.Texture2DArray.prototype = Object.create(gluTexture.Texture2D.prototype);
+gluTexture.Texture2DArray.prototype.constructor = gluTexture.Texture2DArray;
+
+gluTexture.Texture2DArray.prototype.upload = function() {
+ if (!gl.texImage3D)
+ throw new Error('gl.TexImage3D() is not supported');
+
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.m_glTexture);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, gluTexture.computePixelStore(this.m_refTexture.getFormat()));
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+
+ var transferFormat = gluTextureUtil.getTransferFormat(this.m_refTexture.getFormat());
+
+ for (var levelNdx = 0; levelNdx < this.m_refTexture.getNumLevels(); levelNdx++) {
+ if (this.m_refTexture.isLevelEmpty(levelNdx))
+ continue; // Don't upload.
+
+ /*tcu::ConstPixelBufferAccess*/ var access = this.m_refTexture.getLevel(levelNdx);
+ DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize() * access.getWidth());
+ DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize() * access.getWidth() * access.getHeight());
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, levelNdx, this.m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
+ }
+
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+};
+
+gluTexture.texture2DArrayFromFormat = function(gl, format, dataType, width, height, numLayers) {
+ var tex = new gluTexture.Texture2DArray(gl, format, false, new tcuTexture.Texture2DArray(gluTextureUtil.mapGLTransferFormat(format, dataType), width, height, numLayers));
+ return tex;
+};
+
+gluTexture.texture2DArrayFromInternalFormat = function(gl, internalFormat, width, height, numLayers) {
+ var tex = new gluTexture.Texture2DArray(gl, internalFormat, false, new tcuTexture.Texture2DArray(gluTextureUtil.mapGLInternalFormat(internalFormat), width, height, numLayers));
+ return tex;
+};
+
+/**
+ * @constructor
+ * @extends {gluTexture.Texture2D}
+ */
+gluTexture.Texture3D = function(gl, format, isCompressed, refTexture) {
+ gluTexture.Texture2D.call(this, gl, format, isCompressed, refTexture);
+ this.m_type = gluTexture.Type.TYPE_3D;
+};
+
+gluTexture.Texture3D.prototype = Object.create(gluTexture.Texture2D.prototype);
+gluTexture.Texture3D.prototype.constructor = gluTexture.Texture3D;
+
+gluTexture.Texture3D.prototype.upload = function() {
+ if (!gl.texImage3D)
+ throw new Error('gl.TexImage3D() is not supported');
+
+ gl.bindTexture(gl.TEXTURE_3D, this.m_glTexture);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, gluTexture.computePixelStore(this.m_refTexture.getFormat()));
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+
+ var transferFormat = gluTextureUtil.getTransferFormat(this.m_refTexture.getFormat());
+
+ for (var levelNdx = 0; levelNdx < this.m_refTexture.getNumLevels(); levelNdx++) {
+ if (this.m_refTexture.isLevelEmpty(levelNdx))
+ continue; // Don't upload.
+
+ /*tcu::ConstPixelBufferAccess*/ var access = this.m_refTexture.getLevel(levelNdx);
+ DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize() * access.getWidth());
+ DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize() * access.getWidth() * access.getHeight());
+ gl.texImage3D(gl.TEXTURE_3D, levelNdx, this.m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
+ }
+
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+};
+
+gluTexture.texture3DFromFormat = function(gl, format, dataType, width, height, depth) {
+ var tex = new gluTexture.Texture3D(gl, format, false, new tcuTexture.Texture3D(gluTextureUtil.mapGLTransferFormat(format, dataType), width, height, depth));
+ return tex;
+};
+
+gluTexture.texture3DFromInternalFormat = function(gl, internalFormat, width, height, depth) {
+ var tex = new gluTexture.Texture3D(gl, internalFormat, false, new tcuTexture.Texture3D(gluTextureUtil.mapGLInternalFormat(internalFormat), width, height, depth));
+ return tex;
+};
+
+/**
+ * @constructor
+ * @extends {gluTexture.Texture2D}
+ */
+gluTexture.Compressed2D = function(gl, format, isCompressed, refTexture) {
+ gluTexture.Texture2D.call(this, gl, format, isCompressed, refTexture);
+};
+
+gluTexture.Compressed2D.prototype = Object.create(gluTexture.Texture2D.prototype);
+gluTexture.Compressed2D.prototype.constructor = gluTexture.Compressed2D;
+
+gluTexture.Compressed2D.prototype.uploadLevel = function(level, source) {
+ DE_ASSERT(this.m_isCompressed);
+
+ if (this.m_glTexture == null)
+ testFailedOptions('Failed to create GL texture', true);
+
+ gl.bindTexture(gl.TEXTURE_2D, this.m_glTexture);
+
+ gl.compressedTexImage2D(gl.TEXTURE_2D, level, this.m_format, source.m_width, source.m_height, 0 /* border */, source.m_data);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+};
+
+/**
+ * @constructor
+ * @extends {gluTexture.Texture2D}
+ */
+gluTexture.CompressedCube = function(gl, format, isCompressed, refTexture) {
+ gluTexture.Texture2D.call(this, gl, format, isCompressed, refTexture);
+};
+
+gluTexture.CompressedCube.prototype = Object.create(gluTexture.Texture2D.prototype);
+gluTexture.CompressedCube.prototype.constructor = gluTexture.CompressedCube;
+
+gluTexture.CompressedCube.prototype.uploadLevel = function(level, source) {
+ DE_ASSERT(this.m_isCompressed);
+
+ if (this.m_glTexture == null)
+ testFailedOptions('Failed to create GL texture', true);
+
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.m_glTexture);
+
+ for (var face in tcuTexture.CubeFace) {
+
+ // Upload to GL texture in compressed form.
+ gl.compressedTexImage2D(gluTexture.cubeFaceToGLFace(tcuTexture.CubeFace[face]), 0, this.m_format,
+ source.m_width, source.m_height, 0 /* border */, source.m_data);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'Texture upload failed', false, true);
+ }
+
+};
+
+gluTexture.compressed2DFromInternalFormat = function(gl, format, width, height, compressed) {
+ var tex = new gluTexture.Compressed2D(gl, gluTextureUtil.getGLFormat(format), true, new tcuTexture.Texture2D(compressed.getUncompressedFormat(), width, height));
+ tex.m_refTexture.allocLevel(0);
+ compressed.decompress(tex.m_refTexture.getLevel(0));
+ tex.uploadLevel(0, compressed);
+ return tex;
+};
+
+gluTexture.compressedCubeFromInternalFormat = function(gl, format, size, compressed) {
+ var tex = new gluTexture.CompressedCube(gl, gluTextureUtil.getGLFormat(format), true, new tcuTexture.TextureCube(compressed.getUncompressedFormat(), size));
+ for (var face in tcuTexture.CubeFace) {
+ tex.m_refTexture.allocLevel(tcuTexture.CubeFace[face], 0);
+
+ /*tcu::ConstPixelBufferAccess*/ var access = tex.m_refTexture.getLevelFace(0, tcuTexture.CubeFace[face]);
+ DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize() * access.getWidth());
+ compressed.decompress(access);
+ }
+ tex.uploadLevel(0, compressed);
+ return tex;
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTextureUtil.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTextureUtil.js
new file mode 100644
index 0000000000..06f3f5289d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTextureUtil.js
@@ -0,0 +1,1025 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*--------------------------------------------------------------------*//*!
+ * \brief Map tcuTexture.TextureFormat to GL pixel transfer format.
+ *
+ * Maps generic texture format description to GL pixel transfer format.
+ * If no mapping is found, throws tcu::InternalError.
+ *
+ * \param texFormat Generic texture format.
+ * \return GL pixel transfer format.
+ *//*--------------------------------------------------------------------*/
+'use strict';
+goog.provide('framework.opengl.gluTextureUtil');
+goog.require('framework.common.tcuCompressedTexture');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderUtil');
+
+goog.scope(function() {
+
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var deString = framework.delibs.debase.deString;
+var tcuTexture = framework.common.tcuTexture;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var tcuCompressedTexture = framework.common.tcuCompressedTexture;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+
+/**
+ * @param {number} format
+ * @param {number} dataType
+ * @constructor
+ */
+gluTextureUtil.TransferFormat = function(format, dataType) {
+ this.format = format; //!< Pixel format.
+ this.dataType = dataType; //!< Data type.
+};
+
+/**
+ * Map tcuTexture.TextureFormat to GL pixel transfer format.
+ *
+ * Maps generic texture format description to GL pixel transfer format.
+ * If no mapping is found, throws tcu::InternalError.
+ *
+ * @param {tcuTexture.TextureFormat} texFormat Generic texture format.
+ * @return {gluTextureUtil.TransferFormat} GL pixel transfer format.
+ * @throws {Error}
+ */
+gluTextureUtil.getTransferFormat = function(/* tcuTexture.TextureFormat */ texFormat) {
+ var format = gl.NONE;
+ var type = gl.NONE;
+ /*boolean*/ var isInt = false;
+
+ switch (texFormat.type) {
+ case tcuTexture.ChannelType.SIGNED_INT8:
+ case tcuTexture.ChannelType.SIGNED_INT16:
+ case tcuTexture.ChannelType.SIGNED_INT32:
+ case tcuTexture.ChannelType.UNSIGNED_INT8:
+ case tcuTexture.ChannelType.UNSIGNED_INT16:
+ case tcuTexture.ChannelType.UNSIGNED_INT32:
+ case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV:
+ isInt = true;
+ break;
+
+ default:
+ isInt = false;
+ break;
+ }
+
+ switch (texFormat.order) {
+ case tcuTexture.ChannelOrder.A: format = gl.ALPHA; break;
+ case tcuTexture.ChannelOrder.L: format = gl.LUMINANCE; break;
+ case tcuTexture.ChannelOrder.LA: format = gl.LUMINANCE_ALPHA; break;
+ case tcuTexture.ChannelOrder.R: format = isInt ? gl.RED_INTEGER : gl.RED; break;
+ case tcuTexture.ChannelOrder.RG: format = isInt ? gl.RG_INTEGER : gl.RG; break;
+ case tcuTexture.ChannelOrder.RGB: format = isInt ? gl.RGB_INTEGER : gl.RGB; break;
+ case tcuTexture.ChannelOrder.RGBA: format = isInt ? gl.RGBA_INTEGER : gl.RGBA; break;
+ case tcuTexture.ChannelOrder.sRGB: format = gl.RGB; break;
+ case tcuTexture.ChannelOrder.sRGBA: format = gl.RGBA; break;
+ case tcuTexture.ChannelOrder.D: format = gl.DEPTH_COMPONENT; break;
+ case tcuTexture.ChannelOrder.DS: format = gl.DEPTH_STENCIL; break;
+ case tcuTexture.ChannelOrder.S: format = gl.STENCIL_INDEX; break;
+
+ default:
+ throw new Error('Unknown ChannelOrder ' + texFormat.order);
+ }
+
+ switch (texFormat.type) {
+ case tcuTexture.ChannelType.SNORM_INT8: type = gl.BYTE; break;
+ case tcuTexture.ChannelType.SNORM_INT16: type = gl.SHORT; break;
+ case tcuTexture.ChannelType.UNORM_INT8: type = gl.UNSIGNED_BYTE; break;
+ case tcuTexture.ChannelType.UNORM_INT16: type = gl.UNSIGNED_SHORT; break;
+ case tcuTexture.ChannelType.UNORM_SHORT_565: type = gl.UNSIGNED_SHORT_5_6_5; break;
+ case tcuTexture.ChannelType.UNORM_SHORT_4444: type = gl.UNSIGNED_SHORT_4_4_4_4; break;
+ case tcuTexture.ChannelType.UNORM_SHORT_5551: type = gl.UNSIGNED_SHORT_5_5_5_1; break;
+ case tcuTexture.ChannelType.SIGNED_INT8: type = gl.BYTE; break;
+ case tcuTexture.ChannelType.SIGNED_INT16: type = gl.SHORT; break;
+ case tcuTexture.ChannelType.SIGNED_INT32: type = gl.INT; break;
+ case tcuTexture.ChannelType.UNSIGNED_INT8: type = gl.UNSIGNED_BYTE; break;
+ case tcuTexture.ChannelType.UNSIGNED_INT16: type = gl.UNSIGNED_SHORT; break;
+ case tcuTexture.ChannelType.UNSIGNED_INT32: type = gl.UNSIGNED_INT; break;
+ case tcuTexture.ChannelType.FLOAT: type = gl.FLOAT; break;
+ case tcuTexture.ChannelType.UNORM_INT_101010: type = gl.UNSIGNED_INT_2_10_10_10_REV; break;
+ case tcuTexture.ChannelType.UNORM_INT_1010102_REV: type = gl.UNSIGNED_INT_2_10_10_10_REV; break;
+ case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV: type = gl.UNSIGNED_INT_2_10_10_10_REV; break;
+ case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV: type = gl.UNSIGNED_INT_10F_11F_11F_REV; break;
+ case tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV: type = gl.UNSIGNED_INT_5_9_9_9_REV; break;
+ case tcuTexture.ChannelType.HALF_FLOAT: type = gl.HALF_FLOAT; break;
+ case tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV: type = gl.FLOAT_32_UNSIGNED_INT_24_8_REV; break;
+ case tcuTexture.ChannelType.UNSIGNED_INT_24_8: type = texFormat.order == tcuTexture.ChannelOrder.D ?
+ gl.UNSIGNED_INT : gl.UNSIGNED_INT_24_8; break;
+
+ default:
+ throw new Error("Can't map texture format to GL transfer format " + texFormat.type);
+ }
+
+ return new gluTextureUtil.TransferFormat(format, type);
+};
+
+/**
+ * Map tcuTexture.TextureFormat to GL internal sized format.
+ *
+ * Maps generic texture format description to GL internal format.
+ * If no mapping is found, throws Error.
+ *
+ * @param {tcuTexture.TextureFormat} texFormat Generic texture format.
+ * @return {number} GL texture format.
+ * @throws {Error}
+ */
+gluTextureUtil.getInternalFormat = function(texFormat) {
+
+ var stringify = function(order, type) {
+ return '' + order + ' ' + type;
+ };
+
+ switch (stringify(texFormat.order, texFormat.type)) {
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_5551): return gl.RGB5_A1;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_4444): return gl.RGBA4;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_SHORT_565): return gl.RGB565;
+ case stringify(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNORM_INT16): return gl.DEPTH_COMPONENT16;
+ case stringify(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT8): return gl.STENCIL_INDEX8;
+
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.FLOAT): return gl.RGBA32F;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT32): return gl.RGBA32I;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT32): return gl.RGBA32UI;
+ // TODO: Check which ones are valid in WebGL 2 - case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT16): return gl.RGBA16;
+ //case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SNORM_INT16): return gl.RGBA16_SNORM;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.HALF_FLOAT): return gl.RGBA16F;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT16): return gl.RGBA16I;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT16): return gl.RGBA16UI;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8): return gl.RGBA8;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT8): return gl.RGBA8I;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT8): return gl.RGBA8UI;
+ case stringify(tcuTexture.ChannelOrder.sRGBA, tcuTexture.ChannelType.UNORM_INT8): return gl.SRGB8_ALPHA8;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT_1010102_REV): return gl.RGB10_A2;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV): return gl.RGB10_A2UI;
+ case stringify(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SNORM_INT8): return gl.RGBA8_SNORM;
+
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8): return gl.RGB8;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV): return gl.R11F_G11F_B10F;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.FLOAT): return gl.RGB32F;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SIGNED_INT32): return gl.RGB32I;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT32): return gl.RGB32UI;
+ //case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT16): return gl.RGB16;
+ //case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SNORM_INT16): return gl.RGB16_SNORM;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.HALF_FLOAT): return gl.RGB16F;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SIGNED_INT16): return gl.RGB16I;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT16): return gl.RGB16UI;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SNORM_INT8): return gl.RGB8_SNORM;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SIGNED_INT8): return gl.RGB8I;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT8): return gl.RGB8UI;
+ case stringify(tcuTexture.ChannelOrder.sRGB, tcuTexture.ChannelType.UNORM_INT8): return gl.SRGB8;
+ case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV): return gl.RGB9_E5;
+ //case stringify(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT_1010102_REV): return gl.RGB10;
+
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.FLOAT): return gl.RG32F;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SIGNED_INT32): return gl.RG32I;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNSIGNED_INT32): return gl.RG32UI;
+ //case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNORM_INT16): return gl.RG16;
+ //case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SNORM_INT16): return gl.RG16_SNORM;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.HALF_FLOAT): return gl.RG16F;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SIGNED_INT16): return gl.RG16I;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNSIGNED_INT16): return gl.RG16UI;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNORM_INT8): return gl.RG8;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SIGNED_INT8): return gl.RG8I;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNSIGNED_INT8): return gl.RG8UI;
+ case stringify(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SNORM_INT8): return gl.RG8_SNORM;
+
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.FLOAT): return gl.R32F;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SIGNED_INT32): return gl.R32I;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNSIGNED_INT32): return gl.R32UI;
+ //case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNORM_INT16): return gl.R16;
+ //case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SNORM_INT16): return gl.R16_SNORM;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.HALF_FLOAT): return gl.R16F;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SIGNED_INT16): return gl.R16I;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNSIGNED_INT16): return gl.R16UI;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNORM_INT8): return gl.R8;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SIGNED_INT8): return gl.R8I;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNSIGNED_INT8): return gl.R8UI;
+ case stringify(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SNORM_INT8): return gl.R8_SNORM;
+
+ case stringify(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.FLOAT): return gl.DEPTH_COMPONENT32F;
+ case stringify(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNSIGNED_INT_24_8): return gl.DEPTH_COMPONENT24;
+ //case stringify(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNSIGNED_INT32): return gl.DEPTH_COMPONENT32;
+ case stringify(tcuTexture.ChannelOrder.DS, tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV): return gl.DEPTH32F_STENCIL8;
+ case stringify(tcuTexture.ChannelOrder.DS, tcuTexture.ChannelType.UNSIGNED_INT_24_8): return gl.DEPTH24_STENCIL8;
+
+ default:
+ throw new Error("Can't map texture format to GL internal format");
+ }
+};
+
+/**
+ * Enable WEBGL_compressed_texture_etc support if available, by merging it
+ * into the WebGL2RenderingContext.
+ *
+ * This function may be called many times.
+ *
+ * @return {boolean} True if enabled.
+ */
+gluTextureUtil.enableCompressedTextureETC = (function() {
+ var enabled = undefined;
+ return function() {
+ if (enabled === undefined) {
+ enabled = false;
+
+ var WEBGL_compressed_texture_etc = gl.getExtension("WEBGL_compressed_texture_etc");
+ if (WEBGL_compressed_texture_etc) {
+ // Extend gl with enums from WEBGL_compressed_texture_etc
+ // (if it doesn't already have the etc texture formats).
+ var proto = Object.getPrototypeOf(WEBGL_compressed_texture_etc);
+ for (var prop in proto) {
+ if (proto.hasOwnProperty(prop)) {
+ gl[prop] = proto[prop];
+ }
+ }
+ enabled = true;
+ }
+ }
+ return enabled;
+ };
+})();
+
+/**
+ * Map generic compressed format to GL compressed format enum.
+ *
+ * Maps generic compressed format to GL compressed format enum value.
+ * If no mapping is found, throws Error.
+
+ * @param {tcuCompressedTexture.Format} format Generic compressed format.
+ * @return {number} GL compressed texture format.
+ * @throws {Error}
+ */
+gluTextureUtil.getGLFormat = function(/* tcuCompressedTexture.Format */ format) {
+ switch (format) {
+ // TODO: check which are available in WebGL 2 - case tcuCompressedTexture.Format.ETC1_RGB8: return gl.ETC1_RGB8_OES;
+ case tcuCompressedTexture.Format.EAC_R11: return gl.COMPRESSED_R11_EAC;
+ case tcuCompressedTexture.Format.EAC_SIGNED_R11: return gl.COMPRESSED_SIGNED_R11_EAC;
+ case tcuCompressedTexture.Format.EAC_RG11: return gl.COMPRESSED_RG11_EAC;
+ case tcuCompressedTexture.Format.EAC_SIGNED_RG11: return gl.COMPRESSED_SIGNED_RG11_EAC;
+ case tcuCompressedTexture.Format.ETC2_RGB8: return gl.COMPRESSED_RGB8_ETC2;
+ case tcuCompressedTexture.Format.ETC2_SRGB8: return gl.COMPRESSED_SRGB8_ETC2;
+ case tcuCompressedTexture.Format.ETC2_RGB8_PUNCHTHROUGH_ALPHA1: return gl.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ case tcuCompressedTexture.Format.ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: return gl.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ case tcuCompressedTexture.Format.ETC2_EAC_RGBA8: return gl.COMPRESSED_RGBA8_ETC2_EAC;
+ case tcuCompressedTexture.Format.ETC2_EAC_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
+
+ /*case tcuCompressedTexture.Format.ASTC_4x4_RGBA: return gl.COMPRESSED_RGBA_ASTC_4x4_KHR;
+ case tcuCompressedTexture.Format.ASTC_5x4_RGBA: return gl.COMPRESSED_RGBA_ASTC_5x4_KHR;
+ case tcuCompressedTexture.Format.ASTC_5x5_RGBA: return gl.COMPRESSED_RGBA_ASTC_5x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_6x5_RGBA: return gl.COMPRESSED_RGBA_ASTC_6x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_6x6_RGBA: return gl.COMPRESSED_RGBA_ASTC_6x6_KHR;
+ case tcuCompressedTexture.Format.ASTC_8x5_RGBA: return gl.COMPRESSED_RGBA_ASTC_8x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_8x6_RGBA: return gl.COMPRESSED_RGBA_ASTC_8x6_KHR;
+ case tcuCompressedTexture.Format.ASTC_8x8_RGBA: return gl.COMPRESSED_RGBA_ASTC_8x8_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x5_RGBA: return gl.COMPRESSED_RGBA_ASTC_10x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x6_RGBA: return gl.COMPRESSED_RGBA_ASTC_10x6_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x8_RGBA: return gl.COMPRESSED_RGBA_ASTC_10x8_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x10_RGBA: return gl.COMPRESSED_RGBA_ASTC_10x10_KHR;
+ case tcuCompressedTexture.Format.ASTC_12x10_RGBA: return gl.COMPRESSED_RGBA_ASTC_12x10_KHR;
+ case tcuCompressedTexture.Format.ASTC_12x12_RGBA: return gl.COMPRESSED_RGBA_ASTC_12x12_KHR;
+ case tcuCompressedTexture.Format.ASTC_4x4_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
+ case tcuCompressedTexture.Format.ASTC_5x4_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
+ case tcuCompressedTexture.Format.ASTC_5x5_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_6x5_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_6x6_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
+ case tcuCompressedTexture.Format.ASTC_8x5_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_8x6_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
+ case tcuCompressedTexture.Format.ASTC_8x8_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x5_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x6_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x8_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
+ case tcuCompressedTexture.Format.ASTC_10x10_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
+ case tcuCompressedTexture.Format.ASTC_12x10_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
+ case tcuCompressedTexture.Format.ASTC_12x12_SRGB8_ALPHA8: return gl.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;*/
+
+ default:
+ throw new Error("Can't map compressed format to GL format");
+ }
+};
+
+/**
+ * @param {number} dataType
+ * @param {boolean} normalized
+ * @return {tcuTexture.ChannelType}
+ * @throws {Error}
+ */
+gluTextureUtil.mapGLChannelType = function(/* deMath.deUint32 */ dataType, /*boolean*/ normalized) {
+ // \note Normalized bit is ignored where it doesn't apply.
+
+ switch (dataType) {
+ case gl.UNSIGNED_BYTE: return normalized ? tcuTexture.ChannelType.UNORM_INT8 : tcuTexture.ChannelType.UNSIGNED_INT8;
+ case gl.BYTE: return normalized ? tcuTexture.ChannelType.SNORM_INT8 : tcuTexture.ChannelType.SIGNED_INT8;
+ case gl.UNSIGNED_SHORT: return normalized ? tcuTexture.ChannelType.UNORM_INT16 : tcuTexture.ChannelType.UNSIGNED_INT16;
+ case gl.SHORT: return normalized ? tcuTexture.ChannelType.SNORM_INT16 : tcuTexture.ChannelType.SIGNED_INT16;
+ case gl.UNSIGNED_INT: return normalized ? tcuTexture.ChannelType.UNORM_INT32 : tcuTexture.ChannelType.UNSIGNED_INT32;
+ case gl.INT: return normalized ? tcuTexture.ChannelType.SNORM_INT32 : tcuTexture.ChannelType.SIGNED_INT32;
+ case gl.FLOAT: return tcuTexture.ChannelType.FLOAT;
+ case gl.UNSIGNED_SHORT_4_4_4_4: return tcuTexture.ChannelType.UNORM_SHORT_4444;
+ case gl.UNSIGNED_SHORT_5_5_5_1: return tcuTexture.ChannelType.UNORM_SHORT_5551;
+ case gl.UNSIGNED_SHORT_5_6_5: return tcuTexture.ChannelType.UNORM_SHORT_565;
+ case gl.HALF_FLOAT: return tcuTexture.ChannelType.HALF_FLOAT;
+ case gl.UNSIGNED_INT_2_10_10_10_REV: return normalized ? tcuTexture.ChannelType.UNORM_INT_1010102_REV : tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV;
+ case gl.UNSIGNED_INT_10F_11F_11F_REV: return tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV;
+ case gl.UNSIGNED_INT_24_8: return tcuTexture.ChannelType.UNSIGNED_INT_24_8;
+ case gl.FLOAT_32_UNSIGNED_INT_24_8_REV: return tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV;
+ case gl.UNSIGNED_INT_5_9_9_9_REV: return tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV;
+
+ default:
+ throw new Error('Unsupported dataType ' + dataType);
+ }
+};
+
+/**
+ * @param {number} format Generic compressed format.
+ * @param {number} dataType
+ * @return {tcuTexture.TextureFormat} GL texture format.
+ * @throws {Error}
+ */
+gluTextureUtil.mapGLTransferFormat = function(format, dataType) {
+ switch (format) {
+ case gl.ALPHA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.A, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.LUMINANCE: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.L, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.LUMINANCE_ALPHA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.LA, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.RGB: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.RGBA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, gluTextureUtil.mapGLChannelType(dataType, true));
+ //case gl.BGRA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.BGRA, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.RG: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.RED: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.RGBA_INTEGER: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, gluTextureUtil.mapGLChannelType(dataType, false));
+ case gl.RGB_INTEGER: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, gluTextureUtil.mapGLChannelType(dataType, false));
+ case gl.RG_INTEGER: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, gluTextureUtil.mapGLChannelType(dataType, false));
+ case gl.RED_INTEGER: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, gluTextureUtil.mapGLChannelType(dataType, false));
+
+ case gl.DEPTH_COMPONENT: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, gluTextureUtil.mapGLChannelType(dataType, true));
+ case gl.DEPTH_STENCIL: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.DS, gluTextureUtil.mapGLChannelType(dataType, true));
+
+ default:
+ throw new Error("Can't map GL pixel format (" + deString.enumToString(gl, format) + ', ' + deString.enumToString(gl, dataType) + ') to texture format');
+ }
+};
+
+ /**
+ * Map GL internal texture format to tcuTexture.TextureFormat.
+ *
+ * If no mapping is found, throws Error.
+ * @param {number} internalFormat
+ * @return {tcuTexture.TextureFormat} GL texture format.
+ * @throws {Error}
+ */
+gluTextureUtil.mapGLInternalFormat = function(/*deMath.deUint32*/ internalFormat) {
+ if (internalFormat === undefined)
+ throw new Error('internalformat is undefined');
+
+ switch (internalFormat) {
+ case gl.RGB5_A1: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_5551);
+ case gl.RGBA4: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_4444);
+ case gl.RGB565: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_SHORT_565);
+ case gl.DEPTH_COMPONENT16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNORM_INT16);
+ case gl.STENCIL_INDEX8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT8);
+
+ case gl.RGBA32F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.FLOAT);
+ case gl.RGBA32I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT32);
+ case gl.RGBA32UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT32);
+ //TODO: Check which are available in WebGL 2 case gl.RGBA16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT16);
+ //case gl.RGBA16_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SNORM_INT16);
+ case gl.RGBA16F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.HALF_FLOAT);
+ case gl.RGBA16I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT16);
+ case gl.RGBA16UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT16);
+ case gl.RGBA8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.RGBA8I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT8);
+ case gl.RGBA8UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT8);
+ case gl.SRGB8_ALPHA8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.sRGBA, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.RGB10_A2: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT_1010102_REV);
+ case gl.RGB10_A2UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV);
+ case gl.RGBA8_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SNORM_INT8);
+
+ case gl.RGB8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.R11F_G11F_B10F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV);
+ case gl.RGB32F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.FLOAT);
+ case gl.RGB32I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SIGNED_INT32);
+ case gl.RGB32UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT32);
+ //case gl.RGB16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT16);
+ //case gl.RGB16_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SNORM_INT16);
+ case gl.RGB16F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.HALF_FLOAT);
+ case gl.RGB16I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SIGNED_INT16);
+ case gl.RGB16UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT16);
+ case gl.RGB8_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SNORM_INT8);
+ case gl.RGB8I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.SIGNED_INT8);
+ case gl.RGB8UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT8);
+ case gl.SRGB8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.sRGB, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.RGB9_E5: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV);
+ //case gl.RGB10: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT_1010102_REV);
+
+ case gl.RG32F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.FLOAT);
+ case gl.RG32I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SIGNED_INT32);
+ case gl.RG32UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNSIGNED_INT32);
+ //case gl.RG16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNORM_INT16);
+ //case gl.RG16_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SNORM_INT16);
+ case gl.RG16F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.HALF_FLOAT);
+ case gl.RG16I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SIGNED_INT16);
+ case gl.RG16UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNSIGNED_INT16);
+ case gl.RG8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.RG8I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SIGNED_INT8);
+ case gl.RG8UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.UNSIGNED_INT8);
+ case gl.RG8_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RG, tcuTexture.ChannelType.SNORM_INT8);
+
+ case gl.R32F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.FLOAT);
+ case gl.R32I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SIGNED_INT32);
+ case gl.R32UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNSIGNED_INT32);
+ //case gl.R16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNORM_INT16);
+ //case gl.R16_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SNORM_INT16);
+ case gl.R16F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.HALF_FLOAT);
+ case gl.R16I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SIGNED_INT16);
+ case gl.R16UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNSIGNED_INT16);
+ case gl.R8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.R8I: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SIGNED_INT8);
+ case gl.R8UI: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.UNSIGNED_INT8);
+ case gl.R8_SNORM: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.R, tcuTexture.ChannelType.SNORM_INT8);
+
+ case gl.DEPTH_COMPONENT32F: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.FLOAT);
+ case gl.DEPTH_COMPONENT24: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNSIGNED_INT_24_8);
+ //case gl.DEPTH_COMPONENT32: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNSIGNED_INT32);
+ case gl.DEPTH32F_STENCIL8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.DS, tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV);
+ case gl.DEPTH24_STENCIL8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.DS, tcuTexture.ChannelType.UNSIGNED_INT_24_8);
+
+ default:
+ throw new Error("Can't map GL sized internal format (" + internalFormat.toString(16) + ') to texture format');
+ }
+};
+
+/**
+ * @param {number} format
+ * @return {boolean}
+ */
+gluTextureUtil.isGLInternalColorFormatFilterable = function(format) {
+ switch (format) {
+ case gl.R8:
+ case gl.R8_SNORM:
+ case gl.RG8:
+ case gl.RG8_SNORM:
+ case gl.RGB8:
+ case gl.RGB8_SNORM:
+ case gl.RGB565:
+ case gl.RGBA4:
+ case gl.RGB5_A1:
+ case gl.RGBA8:
+ case gl.RGBA8_SNORM:
+ case gl.RGB10_A2:
+ case gl.SRGB8:
+ case gl.SRGB8_ALPHA8:
+ case gl.R16F:
+ case gl.RG16F:
+ case gl.RGB16F:
+ case gl.RGBA16F:
+ case gl.R11F_G11F_B10F:
+ case gl.RGB9_E5:
+ return true;
+
+ case gl.RGB10_A2UI:
+ case gl.R32F:
+ case gl.RG32F:
+ case gl.RGB32F:
+ case gl.RGBA32F:
+ case gl.R8I:
+ case gl.R8UI:
+ case gl.R16I:
+ case gl.R16UI:
+ case gl.R32I:
+ case gl.R32UI:
+ case gl.RG8I:
+ case gl.RG8UI:
+ case gl.RG16I:
+ case gl.RG16UI:
+ case gl.RG32I:
+ case gl.RG32UI:
+ case gl.RGB8I:
+ case gl.RGB8UI:
+ case gl.RGB16I:
+ case gl.RGB16UI:
+ case gl.RGB32I:
+ case gl.RGB32UI:
+ case gl.RGBA8I:
+ case gl.RGBA8UI:
+ case gl.RGBA16I:
+ case gl.RGBA16UI:
+ case gl.RGBA32I:
+ case gl.RGBA32UI:
+ return false;
+
+ default:
+ throw new Error('Unrecognized format ' + format);
+ }
+};
+
+/**
+ * @param {number} wrapMode
+ * @return {tcuTexture.WrapMode}
+ */
+gluTextureUtil.mapGLWrapMode = function(wrapMode) {
+ switch (wrapMode) {
+ case gl.CLAMP_TO_EDGE: return tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ case gl.REPEAT: return tcuTexture.WrapMode.REPEAT_GL;
+ case gl.MIRRORED_REPEAT: return tcuTexture.WrapMode.MIRRORED_REPEAT_GL;
+ default:
+ throw new Error("Can't map GL wrap mode " + deString.enumToString(gl, wrapMode));
+ }
+};
+
+/**
+ * @param {number} filterMode
+ * @return {tcuTexture.FilterMode}
+ * @throws {Error}
+ */
+gluTextureUtil.mapGLFilterMode = function(filterMode) {
+ switch (filterMode) {
+ case gl.NEAREST: return tcuTexture.FilterMode.NEAREST;
+ case gl.LINEAR: return tcuTexture.FilterMode.LINEAR;
+ case gl.NEAREST_MIPMAP_NEAREST: return tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST;
+ case gl.NEAREST_MIPMAP_LINEAR: return tcuTexture.FilterMode.NEAREST_MIPMAP_LINEAR;
+ case gl.LINEAR_MIPMAP_NEAREST: return tcuTexture.FilterMode.LINEAR_MIPMAP_NEAREST;
+ case gl.LINEAR_MIPMAP_LINEAR: return tcuTexture.FilterMode.LINEAR_MIPMAP_LINEAR;
+ default:
+ throw new Error("Can't map GL filter mode" + filterMode);
+ }
+};
+
+/* TODO: Port the code below */
+// /*--------------------------------------------------------------------*//*!
+// * \brief Map GL sampler parameters to tcu::Sampler.
+// *
+// * If no mapping is found, throws tcu::InternalError.
+// *
+// * \param wrapS S-component wrap mode
+// * \param minFilter Minification filter mode
+// * \param magFilter Magnification filter mode
+// * \return Sampler description.
+// *//*--------------------------------------------------------------------*/
+// /*tcu::Sampler mapGLSamplerWrapS (deUint32 wrapS, deUint32 minFilter, deUint32 magFilter)
+// {
+// return mapGLSampler(wrapS, wrapS, wrapS, minFilter, magFilter);
+// }
+// */
+
+/**
+ * Map GL sampler parameters to tcu::Sampler.
+ *
+ * If no mapping is found, throws tcu::InternalError.
+ *
+ * @param {number} wrapS S-component wrap mode
+ * @param {number} wrapT T-component wrap mode
+ * @param {number} minFilter Minification filter mode
+ * @param {number} magFilter Magnification filter mode
+ * @return {tcuTexture.Sampler}
+ */
+gluTextureUtil.mapGLSamplerWrapST = function(wrapS, wrapT, minFilter, magFilter) {
+ return gluTextureUtil.mapGLSampler(wrapS, wrapT, wrapS, minFilter, magFilter);
+};
+
+/**
+ * Map GL sampler parameters to tcu::Sampler.
+ *
+ * If no mapping is found, throws tcu::InternalError.
+ * @param {number} wrapS S-component wrap mode
+ * @param {number} wrapT T-component wrap mode
+ * @param {number} wrapR R-component wrap mode
+ * @param {number} minFilter Minification filter mode
+ * @param {number} magFilter Magnification filter mode
+ * @return {tcuTexture.Sampler}
+ */
+gluTextureUtil.mapGLSampler = function(wrapS, wrapT, wrapR, minFilter, magFilter) {
+ return new tcuTexture.Sampler(
+ gluTextureUtil.mapGLWrapMode(wrapS),
+ gluTextureUtil.mapGLWrapMode(wrapT),
+ gluTextureUtil.mapGLWrapMode(wrapR),
+ gluTextureUtil.mapGLFilterMode(minFilter),
+ gluTextureUtil.mapGLFilterMode(magFilter),
+ 0.0,
+ true,
+ tcuTexture.CompareMode.COMPAREMODE_NONE,
+ 0,
+ [0.0, 0.0, 0.0, 0.0]);
+};
+
+// /*--------------------------------------------------------------------*//*!
+// * \brief Map GL compare function to tcu::Sampler::CompareMode.
+// *
+// * If no mapping is found, throws tcu::InternalError.
+// *
+// * \param mode GL compare mode
+// * \return Compare mode
+// *//*--------------------------------------------------------------------*/
+/**
+ * @param {number} mode
+ */
+gluTextureUtil.mapGLCompareFunc = function(mode) {
+ switch (mode) {
+ case gl.LESS: return tcuTexture.CompareMode.COMPAREMODE_LESS;
+ case gl.LEQUAL: return tcuTexture.CompareMode.COMPAREMODE_LESS_OR_EQUAL;
+ case gl.GREATER: return tcuTexture.CompareMode.COMPAREMODE_GREATER;
+ case gl.GEQUAL: return tcuTexture.CompareMode.COMPAREMODE_GREATER_OR_EQUAL;
+ case gl.EQUAL: return tcuTexture.CompareMode.COMPAREMODE_EQUAL;
+ case gl.NOTEQUAL: return tcuTexture.CompareMode.COMPAREMODE_NOT_EQUAL;
+ case gl.ALWAYS: return tcuTexture.CompareMode.COMPAREMODE_ALWAYS;
+ case gl.NEVER: return tcuTexture.CompareMode.COMPAREMODE_NEVER;
+ default:
+ throw new Error("Can't map GL compare mode " + mode);
+ }
+};
+
+/**
+ * Get GL wrap mode.
+ *
+ * If no mapping is found, throws tcu::InternalError.
+ *
+ * @param {tcuTexture.WrapMode} wrapMode
+ * @return {number} GL wrap mode
+ */
+gluTextureUtil.getGLWrapMode = function(wrapMode) {
+ switch (wrapMode) {
+ case tcuTexture.WrapMode.CLAMP_TO_EDGE: return gl.CLAMP_TO_EDGE;
+ case tcuTexture.WrapMode.REPEAT_GL: return gl.REPEAT;
+ case tcuTexture.WrapMode.MIRRORED_REPEAT_GL: return gl.MIRRORED_REPEAT;
+ default:
+ throw new Error("Can't map wrap mode");
+ }
+};
+
+/**
+ * Get GL filter mode.
+ *
+ * If no mapping is found, throws tcu::InternalError.
+ *
+ * @param {tcuTexture.FilterMode} filterMode Filter mode
+ * @return {number} GL filter mode
+ */
+gluTextureUtil.getGLFilterMode = function(filterMode) {
+ switch (filterMode) {
+ case tcuTexture.FilterMode.NEAREST: return gl.NEAREST;
+ case tcuTexture.FilterMode.LINEAR: return gl.LINEAR;
+ case tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST: return gl.NEAREST_MIPMAP_NEAREST;
+ case tcuTexture.FilterMode.NEAREST_MIPMAP_LINEAR: return gl.NEAREST_MIPMAP_LINEAR;
+ case tcuTexture.FilterMode.LINEAR_MIPMAP_NEAREST: return gl.LINEAR_MIPMAP_NEAREST;
+ case tcuTexture.FilterMode.LINEAR_MIPMAP_LINEAR: return gl.LINEAR_MIPMAP_LINEAR;
+ default:
+ throw new Error("Can't map filter mode");
+ }
+};
+
+/**
+ * Get GL compare mode.
+ *
+ * If no mapping is found, throws tcu::InternalError.
+ *
+ * @param {tcuTexture.CompareMode} compareMode Compare mode
+ * @return {number} GL compare mode
+ */
+gluTextureUtil.getGLCompareFunc = function(compareMode) {
+ switch (compareMode) {
+ case tcuTexture.CompareMode.COMPAREMODE_NONE: return gl.NONE;
+ case tcuTexture.CompareMode.COMPAREMODE_LESS: return gl.LESS;
+ case tcuTexture.CompareMode.COMPAREMODE_LESS_OR_EQUAL: return gl.LEQUAL;
+ case tcuTexture.CompareMode.COMPAREMODE_GREATER: return gl.GREATER;
+ case tcuTexture.CompareMode.COMPAREMODE_GREATER_OR_EQUAL: return gl.GEQUAL;
+ case tcuTexture.CompareMode.COMPAREMODE_EQUAL: return gl.EQUAL;
+ case tcuTexture.CompareMode.COMPAREMODE_NOT_EQUAL: return gl.NOTEQUAL;
+ case tcuTexture.CompareMode.COMPAREMODE_ALWAYS: return gl.ALWAYS;
+ case tcuTexture.CompareMode.COMPAREMODE_NEVER: return gl.NEVER;
+ default:
+ throw new Error("Can't map compare mode");
+ }
+};
+
+/**
+ * Get GL cube face.
+ *
+ * If no mapping is found, throws tcu::InternalError.
+ *
+ * @param {tcuTexture.CubeFace} face Cube face
+ * @return {number} GL cube face
+ */
+gluTextureUtil.getGLCubeFace = function(face) {
+ switch (face) {
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X:
+ return gl.TEXTURE_CUBE_MAP_NEGATIVE_X;
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X:
+ return gl.TEXTURE_CUBE_MAP_POSITIVE_X;
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y:
+ return gl.TEXTURE_CUBE_MAP_NEGATIVE_Y;
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y:
+ return gl.TEXTURE_CUBE_MAP_POSITIVE_Y;
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z:
+ return gl.TEXTURE_CUBE_MAP_NEGATIVE_Z;
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z:
+ return gl.TEXTURE_CUBE_MAP_POSITIVE_Z;
+ default:
+ throw Error("Can't map cube face");
+ }
+};
+
+// /*--------------------------------------------------------------------*//*!
+// * \brief Get GLSL sampler type for texture format.
+// *
+// * If no mapping is found, glu::TYPE_LAST is returned.
+// *
+// * \param format Texture format
+// * \return GLSL 1D sampler type for format
+// *//*--------------------------------------------------------------------*/
+// DataType getSampler1DType (tcu::TextureFormat format)
+// {
+// using tcu::TextureFormat;
+
+// if (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS)
+// return TYPE_SAMPLER_1D;
+
+// if (format.order == tcuTexture.ChannelOrder.S)
+// return TYPE_LAST;
+
+// switch (tcu::getTextureChannelClass(format.type))
+// {
+// case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+// case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+// case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+// return glu::TYPE_SAMPLER_1D;
+
+// case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+// return glu::TYPE_INT_SAMPLER_1D;
+
+// case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+// return glu::TYPE_UINT_SAMPLER_1D;
+
+// default:
+// return glu::TYPE_LAST;
+// }
+// }
+
+/**
+ * Get GLSL sampler type for texture format.
+ * If no mapping is found, glu::TYPE_LAST is returned.
+ *
+ * @param {tcuTexture.TextureFormat} format
+ * @return {gluShaderUtil.DataType} GLSL 2D sampler type for format
+ */
+gluTextureUtil.getSampler2DType = function(format) {
+ if (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS)
+ return gluShaderUtil.DataType.SAMPLER_2D;
+
+ if (format.order == tcuTexture.ChannelOrder.S)
+ return /** @type {gluShaderUtil.DataType} */ (Object.keys(gluShaderUtil.DataType).length);
+
+ switch (tcuTexture.getTextureChannelClass(format.type)) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ return gluShaderUtil.DataType.SAMPLER_2D;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ return gluShaderUtil.DataType.INT_SAMPLER_2D;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ return gluShaderUtil.DataType.UINT_SAMPLER_2D;
+
+ default:
+ return /** @type {gluShaderUtil.DataType} */ (Object.keys(gluShaderUtil.DataType).length);
+ }
+};
+
+/**
+ *
+ * @param {tcuTexture.TextureFormat} format
+ * @return {gluShaderUtil.DataType} GLSL 2D sampler type for format
+ */
+gluTextureUtil.getSampler3DType = function(format) {
+ if (format.order === tcuTexture.ChannelOrder.D || format.order === tcuTexture.ChannelOrder.DS)
+ return gluShaderUtil.DataType.SAMPLER_3D;
+
+ if (format.order === tcuTexture.ChannelOrder.S)
+ return /** @type {gluShaderUtil.DataType} */ (Object.keys(gluShaderUtil.DataType).length); // shouldn't we throw an error instead?
+
+ switch (tcuTexture.getTextureChannelClass(format.type)) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ return gluShaderUtil.DataType.SAMPLER_3D;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ return gluShaderUtil.DataType.INT_SAMPLER_3D;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ return gluShaderUtil.DataType.UINT_SAMPLER_3D;
+
+ default:
+ return /** @type {gluShaderUtil.DataType} */ (Object.keys(gluShaderUtil.DataType).length);
+ }
+};
+
+/**
+ * \brief Get GLSL sampler type for texture format.
+ *
+ * @param {tcuTexture.TextureFormat} format
+ * @return {gluShaderUtil.DataType} GLSL 2D sampler type for format
+ */
+gluTextureUtil.getSamplerCubeType = function(format) {
+ if (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS)
+ return gluShaderUtil.DataType.SAMPLER_CUBE;
+
+ if (format.order == tcuTexture.ChannelOrder.S)
+ throw new Error('No cube sampler');
+
+ switch (tcuTexture.getTextureChannelClass(format.type)) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ return gluShaderUtil.DataType.SAMPLER_CUBE;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ return gluShaderUtil.DataType.INT_SAMPLER_CUBE;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ return gluShaderUtil.DataType.UINT_SAMPLER_CUBE;
+
+ default:
+ throw new Error('No cube sampler');
+ }
+};
+
+/**
+ * \brief Get GLSL sampler type for texture format.
+ *
+ * If no mapping is found, glu::TYPE_LAST is returned.
+ *
+ * @param {tcuTexture.TextureFormat} format
+ * @return {gluShaderUtil.DataType} GLSL 2D sampler type for format
+ */
+gluTextureUtil.getSampler2DArrayType = function(format) {
+
+ if (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS)
+ return gluShaderUtil.DataType.SAMPLER_2D_ARRAY;
+
+ if (format.order == tcuTexture.ChannelOrder.S)
+ throw new Error('No 2d array sampler');
+
+ switch (tcuTexture.getTextureChannelClass(format.type)) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ return gluShaderUtil.DataType.SAMPLER_2D_ARRAY;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ return gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ return gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY;
+
+ default:
+ throw new Error('No 2d array sampler');
+ }
+};
+
+/**
+ * \brief Get GLSL sampler type for texture format.
+ *
+ * If no mapping is found, glu::TYPE_LAST is returned.
+ *
+ * @param {tcuTexture.TextureFormat} format
+ * @return {gluShaderUtil.DataType} GLSL 2D sampler type for format
+ */
+gluTextureUtil.getSampler3D = function(format) {
+ if (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS)
+ return gluShaderUtil.DataType.SAMPLER_3D;
+
+ if (format.order == tcuTexture.ChannelOrder.S)
+ throw new Error('No 3d sampler');
+
+ switch (tcuTexture.getTextureChannelClass(format.type)) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ return gluShaderUtil.DataType.SAMPLER_3D;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ return gluShaderUtil.DataType.INT_SAMPLER_3D;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ return gluShaderUtil.DataType.UINT_SAMPLER_3D;
+
+ default:
+ throw new Error('No 3d sampler');
+ }
+};
+
+gluTextureUtil.RenderableType = {
+ RENDERABLE_COLOR: (1<<0),
+ RENDERABLE_DEPTH: (1<<1),
+ RENDERABLE_STENCIL: (1<<2)
+};
+
+/**
+ * \brief Get renderable bits.
+ * \note Works currently only on ES3 context.
+ *
+ * @param {number} internalFormat
+ * @return {gluTextureUtil.RenderableType}
+ */
+gluTextureUtil.getRenderableBitsES3 = function(internalFormat)
+{
+ switch (internalFormat)
+ {
+ // Color-renderable formats
+ case gl.RGBA32I:
+ case gl.RGBA32UI:
+ case gl.RGBA16I:
+ case gl.RGBA16UI:
+ case gl.RGBA8:
+ case gl.RGBA8I:
+ case gl.RGBA8UI:
+ case gl.SRGB8_ALPHA8:
+ case gl.RGB10_A2:
+ case gl.RGB10_A2UI:
+ case gl.RGBA4:
+ case gl.RGB5_A1:
+ case gl.RGB8:
+ case gl.RGB565:
+ case gl.RG32I:
+ case gl.RG32UI:
+ case gl.RG16I:
+ case gl.RG16UI:
+ case gl.RG8:
+ case gl.RG8I:
+ case gl.RG8UI:
+ case gl.R32I:
+ case gl.R32UI:
+ case gl.R16I:
+ case gl.R16UI:
+ case gl.R8:
+ case gl.R8I:
+ case gl.R8UI:
+ return gluTextureUtil.RenderableType.RENDERABLE_COLOR;
+
+ // EXT_color_buffer_float
+ case gl.RGBA32F:
+ case gl.R11F_G11F_B10F:
+ case gl.RG32F:
+ case gl.R32F:
+ case gl.RGBA16F:
+ case gl.RG16F:
+ case gl.R16F:
+ if (gl.getExtension("EXT_color_buffer_float"))
+ return gluTextureUtil.RenderableType.RENDERABLE_COLOR;
+ else
+ return 0;
+
+ // Depth formats
+ case gl.DEPTH_COMPONENT32F:
+ case gl.DEPTH_COMPONENT24:
+ case gl.DEPTH_COMPONENT16:
+ return gluTextureUtil.RenderableType.RENDERABLE_DEPTH;
+
+ // Depth+stencil formats
+ case gl.DEPTH32F_STENCIL8:
+ case gl.DEPTH24_STENCIL8:
+ return gluTextureUtil.RenderableType.RENDERABLE_DEPTH | gluTextureUtil.RenderableType.RENDERABLE_STENCIL;
+
+ // Stencil formats
+ case gl.STENCIL_INDEX8:
+ return gluTextureUtil.RenderableType.RENDERABLE_STENCIL;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ * \brief Check if sized internal format is color-renderable.
+ * \note Works currently only on ES3 context.
+ *
+ * @param {number} sizedFormat
+ * @return {boolean}
+ */
+gluTextureUtil.isSizedFormatColorRenderable = function(sizedFormat)
+{
+ var renderable = 0;
+ renderable = gluTextureUtil.getRenderableBitsES3(sizedFormat);
+ return (renderable & gluTextureUtil.RenderableType.RENDERABLE_COLOR) != 0;
+}
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarType.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarType.js
new file mode 100644
index 0000000000..a05f1c1e5c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarType.js
@@ -0,0 +1,814 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluVarType');
+goog.require('framework.opengl.gluShaderUtil');
+
+goog.scope(function() {
+
+ var gluVarType = framework.opengl.gluVarType;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+
+ /**
+ * gluVarType.VarType types enum
+ * @enum {number}
+ */
+ gluVarType.Type = {
+ TYPE_BASIC: 0,
+ TYPE_ARRAY: 1,
+ TYPE_STRUCT: 2
+ };
+
+ /**
+ * gluVarType.TypeArray struct
+ * @param {gluVarType.VarType} elementType
+ * @param {number} arraySize
+ * @constructor
+ */
+ gluVarType.TypeArray = function(elementType, arraySize) {
+ /** @type {gluVarType.VarType} */ this.elementType = gluVarType.newClone(elementType);
+ /** @type {number} */ this.size = arraySize;
+ };
+
+ /**
+ * gluVarType.VarType class
+ * @constructor
+ */
+ gluVarType.VarType = function() {
+ /**
+ * @type {gluShaderUtil.precision}
+ * @private
+ */
+ this.m_flags;
+
+ /**
+ * @type {number}
+ * @private
+ */
+ this.m_type = -1;
+
+ /**
+ * m_data used to be a 'Data' union in C++. Using a var is enough here.
+ * it will contain any necessary value.
+ * case TYPE_BASIC: number
+ * case TYPE_ARRAY: gluVarType.TypeArray
+ * case TYPE_STRUCT: gluVarType.StructType
+ * @private
+ * @type {(number|gluVarType.TypeArray|gluVarType.StructType)}
+ */
+ this.m_data = null;
+ };
+
+ gluVarType.VarType.UNSIZED_ARRAY = -1;
+
+ /**
+ * Creates a basic type gluVarType.VarType. Use this after the constructor call.
+ * @param {number} basicType
+ * @param {gluShaderUtil.precision} flags
+ * @return {gluVarType.VarType} The currently modified object
+ */
+ gluVarType.VarType.prototype.VarTypeBasic = function(basicType, flags) {
+ this.m_type = gluVarType.Type.TYPE_BASIC;
+ this.m_flags = flags;
+ this.m_data = basicType;
+
+ return this;
+ };
+
+ /**
+ * Creates a basic type gluVarType.VarType with type boolean and undefined precision.
+ * @param {number} basicType
+ * @return {gluVarType.VarType} The currently modified object
+ */
+ gluVarType.VarType.prototype.VarTypeBoolean = function(basicType) {
+ this.m_type = gluVarType.Type.TYPE_BASIC;
+ this.m_data = basicType;
+
+ return this;
+ };
+
+ /**
+ * Creates an array type gluVarType.VarType. Use this after the constructor call.
+ * @param {gluVarType.VarType} elementType
+ * @param {number} arraySize
+ * @return {gluVarType.VarType} The currently modified object
+ */
+ gluVarType.VarType.prototype.VarTypeArray = function(elementType, arraySize) {
+ this.m_type = gluVarType.Type.TYPE_ARRAY;
+ if (!(arraySize >= 0 || arraySize == gluVarType.VarType.UNSIZED_ARRAY))
+ throw new Error('Illegal array size: ' + arraySize);
+ this.m_data = new gluVarType.TypeArray(elementType, arraySize);
+
+ return this;
+ };
+
+ /**
+ * Creates a struct type gluVarType.VarType. Use this after the constructor call.
+ * @param {gluVarType.StructType} structPtr
+ * @return {gluVarType.VarType} The currently modified object
+ */
+ gluVarType.VarType.prototype.VarTypeStruct = function(structPtr) {
+ this.m_type = gluVarType.Type.TYPE_STRUCT;
+ this.m_data = structPtr;
+
+ return this;
+ };
+
+ /**
+ * Creates a gluVarType.VarType, the same type as the passed in object.
+ * Use this after the constructor call.
+ * @param {gluVarType.VarType} object
+ * @return {gluVarType.VarType} The currently modified object
+ */
+ gluVarType.VarType.prototype.VarTypeClone = function(object) {
+
+ this.m_type = object.m_type;
+
+ switch (this.m_type) {
+ case gluVarType.Type.TYPE_BASIC:
+ this.m_flags = object.m_flags;
+ this.m_data = object.m_data;
+ break;
+ case gluVarType.Type.TYPE_BASIC:
+ this.m_data = new gluVarType.TypeArray(object.m_data.elementType, object.m_data.size);
+ break;
+ case gluVarType.Type.TYPE_STRUCT:
+ this.m_data = object.m_data;
+ break;
+ default:
+ throw new Error('unknown type: ' + this.m_type);
+ }
+
+ return this;
+ };
+
+ /** isBasicType
+ * @return {boolean} true if the gluVarType.VarType represents a basic type.
+ */
+ gluVarType.VarType.prototype.isBasicType = function() {
+ return this.m_type == gluVarType.Type.TYPE_BASIC;
+ };
+
+ /** isArrayType
+ * @return {boolean} true if the gluVarType.VarType represents an array.
+ */
+ gluVarType.VarType.prototype.isArrayType = function() {
+ return this.m_type == gluVarType.Type.TYPE_ARRAY;
+ };
+
+ /** isStructType
+ * @return {boolean} true if the gluVarType.VarType represents a struct.
+ */
+ gluVarType.VarType.prototype.isStructType = function() {
+ return this.m_type == gluVarType.Type.TYPE_STRUCT;
+ };
+
+ /** getFlags
+ * @return {number} returns the flags of the gluVarType.VarType.
+ */
+ gluVarType.VarType.prototype.getFlags = function() {
+ return this.m_flags;
+ };
+
+ /** getBasicType
+ * @return {gluShaderUtil.DataType<number>} returns the basic data type of the gluVarType.VarType.
+ */
+ gluVarType.VarType.prototype.getBasicType = function() {
+ if (!this.isBasicType())
+ throw new Error('VarType is not a basic type.');
+ return /** @type {gluShaderUtil.DataType<number>} */ (this.m_data);
+ };
+
+ /** getPrecision
+ * @return {gluShaderUtil.precision} returns the precision flag.
+ */
+ gluVarType.VarType.prototype.getPrecision = function() {
+ if (!this.isBasicType())
+ throw new Error('VarType is not a basic type.');
+ return this.m_flags;
+ };
+
+ /** getElementType
+ * @return {gluVarType.VarType} returns the gluVarType.VarType of the element in case of an Array.
+ */
+ gluVarType.VarType.prototype.getElementType = function() {
+ if (!this.isArrayType())
+ throw new Error('VarType is not an array type.');
+ return this.m_data.elementType;
+ };
+
+ /** getArraySize
+ * (not to be confused with a javascript array)
+ * @return {number} returns the size of the array in case it is an array.
+ */
+ gluVarType.VarType.prototype.getArraySize = function() {
+ if (!this.isArrayType())
+ throw new Error('VarType is not an array type.');
+ return this.m_data.size;
+ };
+
+ /** getStruct
+ * @return {gluVarType.StructType} returns the structure when it is a gluVarType.StructType.
+ */
+ gluVarType.VarType.prototype.getStruct = function() {
+ if (!this.isStructType())
+ throw new Error('VarType is not a struct type.');
+ return /** @type {gluVarType.StructType} */ (this.m_data);
+ };
+
+ /**
+ * getScalarSize
+ * @return {number} size of the scalar
+ */
+ gluVarType.VarType.prototype.getScalarSize = function() {
+ switch (this.m_type) {
+ case gluVarType.Type.TYPE_BASIC: {
+ return gluShaderUtil.getDataTypeScalarSize(/** @type {gluShaderUtil.DataType} */(this.getBasicType()));
+ }
+
+ // TODO: check implementation below: return m_data.array.elementType->getScalarSize()*m_data.array.size;
+ case gluVarType.Type.TYPE_ARRAY: {
+ var m_data = /** @type {gluVarType.TypeArray} */(this.m_data);
+ return m_data.elementType.getScalarSize() * m_data.size;
+ }
+
+ case gluVarType.Type.TYPE_STRUCT: {
+ var size = 0;
+
+ var struct = /** @type {gluVarType.StructType} */ (this.m_data);
+
+ // TODO: check loop conditions below
+ // for (gluVarType.StructType::ConstIterator iter = m_data.structPtr->begin(); iter != m_data.structPtr->end(); iter++)
+ for (var iter = 0; struct.m_members[iter] < struct.getSize(); iter++)
+ size += struct.getMember(iter).m_type.getScalarSize();
+ return size;
+ }
+
+ default:
+ // throw new Error('Unexpected type.');
+ return 0;
+ }
+ };
+
+ /**
+ * is
+ * @return {boolean} returns true if the current object is equivalent to other.
+ */
+ gluVarType.VarType.prototype.is = function(other) {
+ if (this.m_type != other.m_type)
+ return false;
+
+ switch (this.m_type) {
+ case gluVarType.Type.TYPE_BASIC:
+ return this.m_data == other.m_data &&
+ this.m_flags == other.m_flags;
+
+ case gluVarType.Type.TYPE_ARRAY:
+ return this.m_data.elementType == other.m_data.elementType &&
+ this.m_data.size == other.m_data.size;
+
+ case gluVarType.Type.TYPE_STRUCT:
+ return this.m_data === other.m_data;
+
+ default:
+ // throw new Error('Unexpected type.');
+ return false;
+ }
+ };
+
+ /**
+ * isnt
+ * @return {boolean} returns true if the current object is not equivalent to other.
+ */
+ gluVarType.VarType.prototype.isnt = function(other) {
+ return !(this.is(other));
+ };
+
+ /**
+ * Creates a basic type gluVarType.VarType.
+ * @param {gluShaderUtil.DataType} basicType
+ * @param {framework.opengl.gluShaderUtil.precision=} flags
+ * @return {gluVarType.VarType}
+ */
+ gluVarType.newTypeBasic = function(basicType, flags) {
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(basicType))
+ return new gluVarType.VarType().VarTypeBasic(basicType, /** @type {framework.opengl.gluShaderUtil.precision}*/ (flags));
+ else
+ return new gluVarType.VarType().VarTypeBoolean(basicType);
+ };
+
+ /**
+ * Creates an array type gluVarType.VarType.
+ * @param {gluVarType.VarType} elementType
+ * @param {number} arraySize
+ * @return {gluVarType.VarType}
+ */
+ gluVarType.newTypeArray = function(elementType, arraySize) {
+ return new gluVarType.VarType().VarTypeArray(elementType, arraySize);
+ };
+
+ /**
+ * Creates a struct type gluVarType.VarType.
+ * @param {gluVarType.StructType} structPtr
+ * @return {gluVarType.VarType}
+ */
+ gluVarType.newTypeStruct = function(structPtr) {
+ return new gluVarType.VarType().VarTypeStruct(structPtr);
+ };
+
+ /**
+ * Creates a struct type gluVarType.VarType.
+ * @param {gluVarType.VarType} object
+ * @return {gluVarType.VarType}
+ */
+ gluVarType.newClone = function(object) {
+ return new gluVarType.VarType().VarTypeClone(object);
+ };
+
+ /**
+ * gluVarType.StructMember class
+ * @constructor
+ */
+ gluVarType.StructMember = function() {
+ /** @type {string} */ this.m_name;
+ /** @type {gluVarType.VarType} */ this.m_type;
+ /** @type {number} */ // this.m_flags = 0; // only in glsUniformBlockCase
+ };
+
+ /**
+ * Creates a gluVarType.StructMember. Use this after the constructor call.
+ * @param {string} name
+ * @param {gluVarType.VarType} type
+ * @return {gluVarType.StructMember} The currently modified object
+ */
+ gluVarType.StructMember.prototype.Constructor = function(name, type) {
+ this.m_type = type;
+ this.m_name = name;
+
+ return this;
+ };
+
+ /** getName
+ * @return {string} name of the gluVarType.StructMember object.
+ */
+ gluVarType.StructMember.prototype.getName = function() {
+ return this.m_name;
+ };
+
+ /** getType
+ * @return {gluVarType.VarType} type of the gluVarType.StructMember object.
+ */
+ gluVarType.StructMember.prototype.getType = function() {
+ return this.m_type;
+ };
+
+ /**
+ * Creates a gluVarType.StructMember.
+ * @param {string} name
+ * @param {gluVarType.VarType} type
+ * @return {gluVarType.StructMember}
+ */
+ gluVarType.newStructMember = function(name, type) {
+ return new gluVarType.StructMember().Constructor(name, type);
+ };
+
+ /**
+ * gluVarType.StructType class
+ * @constructor
+ */
+ gluVarType.StructType = function() {
+ /** @type {string} */ this.m_typeName = '';
+ /** @type {Array<gluVarType.StructMember>} */ this.m_members = [];
+ };
+
+ /**
+ * Creates a gluVarType.StructType. Use this after the constructor call.
+ * @param {string} name
+ * @return {gluVarType.StructType} The currently modified object
+ */
+ gluVarType.StructType.prototype.Constructor = function(name) {
+ /** @type {string}*/ this.m_typeName = this.setTypeName(name);
+ return this;
+ };
+
+ /** hasTypeName
+ * Checks if the gluVarType.StructType m_typeName is defined
+ * @return {boolean}
+ */
+ gluVarType.StructType.prototype.hasTypeName = function() {
+ return (this.m_typeName !== 'undefined');
+ };
+
+ /** setTypeName
+ * @param {string} name
+ * @return {string} returns gluVarType.StructType.m_typeName
+ */
+ gluVarType.StructType.prototype.setTypeName = function(name) {
+ return this.m_typeName = name;
+ };
+
+ /** getTypeName
+ * @return {string}
+ */
+ gluVarType.StructType.prototype.getTypeName = function() {
+ return this.m_typeName;
+ };
+
+ /** getNumMembers
+ * @return {number}
+ */
+ gluVarType.StructType.prototype.getNumMembers = function() {
+ return this.m_members.length;
+ };
+
+ /** getMember
+ * @param {number} memberNdx The index of the member to retrieve.
+ * @return {gluVarType.StructMember}
+ */
+ gluVarType.StructType.prototype.getMember = function(memberNdx) {
+ if (memberNdx >= 0 && memberNdx < this.m_members.length)
+ return this.m_members[memberNdx];
+ else {
+ throw new Error('Invalid member index for StructTypes members');
+ }
+ };
+
+ /** getSize
+ * @return {number} The size of the m_members array.
+ */
+ gluVarType.StructType.prototype.getSize = function() {
+ return this.m_members.length;
+ };
+
+ /** addMember
+ * @param {string} name
+ * @param {gluVarType.VarType} type
+ */
+ gluVarType.StructType.prototype.addMember = function(name, type) {
+ var member = gluVarType.newStructMember(name, type);
+ this.m_members.push(member);
+ };
+
+ /**
+ * Creates a gluVarType.StructType.
+ * @param {string} name
+ * @return {gluVarType.StructType}
+ */
+ gluVarType.newStructType = function(name) {
+ return new gluVarType.StructType().Constructor(name);
+ };
+
+ /**
+ * @param {number} level
+ * @return {string}
+ */
+ gluVarType.indent = function(level) {
+ /** @type {string} */ var str = '';
+ for (var i = 0; i < level; i++)
+ str += '\t';
+ return str;
+ };
+
+ /**
+ * @param {gluVarType.VarType} varType
+ * @param {string} name
+ * @param {number=} level
+ * @return {string}
+ */
+ gluVarType.declareVariable = function(varType, name, level) {
+ /** @type {string} */ var str = '';
+ /** @type {gluVarType.VarType} */ var type = varType;
+ /** @type {gluVarType.VarType} */ var curType = type;
+ /** @type {Array<number>} */ var arraySizes = [];
+
+ // Handle arrays.
+ while (curType.isArrayType()) {
+ arraySizes.push(curType.getArraySize());
+ curType = curType.getElementType();
+ }
+
+ if (curType.isBasicType()) {
+ if (curType.getPrecision() !== undefined)
+ str += gluShaderUtil.getPrecisionName(curType.getPrecision()) + ' ';
+ str += gluShaderUtil.getDataTypeName(/** @type {gluShaderUtil.DataType} */(curType.getBasicType()));
+ } else if (curType.isStructType()) {
+ /** @type {gluVarType.StructType} */ var structPtr = curType.getStruct();
+
+ if (structPtr.hasTypeName())
+ str += structPtr.getTypeName();
+ else
+ str += gluVarType.declareStructType(structPtr, level); // Generate inline declaration.
+ } else
+ throw new Error('Unexpected Array typed VarType.');
+
+ str += ' ' + name;
+
+ // Print array sizes.
+ for (var size = 0; size < arraySizes.length; size++) { //std::vector<int>::const_iterator sizeIter = arraySizes.begin(); sizeIter != arraySizes.end(); sizeIter++) {
+ /** @type {number} */ var arrSize = arraySizes[size];
+ if (arrSize == gluVarType.VarType.UNSIZED_ARRAY)
+ str += '[]';
+ else
+ str += '[' + arrSize + ']';
+ }
+
+ return str;
+ };
+
+ /**
+ * @param {gluVarType.StructType} structType
+ * @param {number=} level
+ * @return {string}
+ */
+ gluVarType.declareStructType = function(structType, level) {
+ /** @type {string} */ var str = 'struct';
+ level = level || 0;
+
+ // gluVarType.Type name is optional.
+ if (structType.hasTypeName())
+ str += ' ' + structType.getTypeName();
+
+ str += '\n' + gluVarType.indent(level) + ' {\n';
+
+ for (var memberNdx = 0; memberNdx < structType.getSize(); memberNdx++) { //gluVarType.StructType::ConstIterator memberIter = decl.structPtr->begin(); memberIter != decl.structPtr->end(); memberIter++) {
+ /** @type {gluVarType.StructMember} */ var memberIter = structType.getMember(memberNdx);
+ str += gluVarType.indent(level + 1);
+ str += gluVarType.declareVariable(memberIter.getType(), memberIter.getName(), level + 1) + ';\n';
+ }
+
+ str += gluVarType.indent(level) + '}';
+
+ return str;
+ };
+
+ /**
+ * @param {*} T
+ * @param {number=} size
+ * @param {gluShaderUtil.precision=} precision
+ * @return {gluVarType.VarType}
+ */
+ gluVarType.getVarTypeOf = function(T, size, precision) {
+ size = size || 1;
+ precision = precision || gluShaderUtil.precision.PRECISION_LOWP;
+ switch (size) {
+ case 4: return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, precision);
+ case 3: return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC3, precision);
+ case 2: return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, precision);
+ }
+ switch (T) {
+ case 'float' : return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT, precision);
+ case 'vec4': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, precision);
+ case 'vec3': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC3, precision);
+ case 'vec2': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, precision);
+ case 'mat2': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT2, precision);
+ case 'mat2x3': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT2X3, precision);
+ case 'mat2x4': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT2X4, precision);
+ case 'mat3x2': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3X2, precision);
+ case 'mat3': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, precision);
+ case 'mat3x4': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3X4, precision);
+ case 'mat4x2': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT4X2, precision);
+ case 'mat4x3': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT4X3, precision);
+ case 'mat4': return gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_MAT4, precision);
+ }
+ throw new Error('Invalid input type ' + T + ' or size ' + size);
+ };
+
+ /**
+ * @enum
+ */
+ gluVarType.Storage = {
+ STORAGE_IN: 0,
+ STORAGE_OUT: 1,
+ STORAGE_CONST: 2,
+ STORAGE_UNIFORM: 3,
+ STORAGE_BUFFER: 4
+ };
+
+ /**
+ * @param {gluVarType.Storage} storage
+ * @return {string}
+ */
+ gluVarType.getStorageName = function(storage) {
+ switch (storage) {
+ case gluVarType.Storage.STORAGE_IN: return 'in';
+ case gluVarType.Storage.STORAGE_OUT: return 'out';
+ case gluVarType.Storage.STORAGE_CONST: return 'const';
+ case gluVarType.Storage.STORAGE_UNIFORM: return 'uniform';
+ case gluVarType.Storage.STORAGE_BUFFER: return 'buffer';
+ default:
+ throw new Error('Unknown storage: ' + storage);
+ }
+ };
+
+ /**
+ * @enum
+ */
+ gluVarType.Interpolation = {
+ INTERPOLATION_SMOOTH: 0,
+ INTERPOLATION_FLAT: 1,
+ INTERPOLATION_CENTROID: 2
+ };
+
+ /**
+ * @param {gluVarType.Interpolation} interpolation
+ * @return {string}
+ */
+ gluVarType.getInterpolationName = function(interpolation) {
+ switch (interpolation) {
+ case gluVarType.Interpolation.INTERPOLATION_SMOOTH: return 'smooth';
+ case gluVarType.Interpolation.INTERPOLATION_FLAT: return 'flat';
+ case gluVarType.Interpolation.INTERPOLATION_CENTROID: return 'centrod';
+ default:
+ throw new Error('Unknown interpolation: ' + interpolation);
+ }
+ };
+
+ /**
+ * @enum
+ */
+ gluVarType.FormatLayout = {
+ FORMATLAYOUT_RGBA32F: 0,
+ FORMATLAYOUT_RGBA16F: 1,
+ FORMATLAYOUT_R32F: 2,
+ FORMATLAYOUT_RGBA8: 3,
+ FORMATLAYOUT_RGBA8_SNORM: 4,
+
+ FORMATLAYOUT_RGBA32I: 5,
+ FORMATLAYOUT_RGBA16I: 6,
+ FORMATLAYOUT_RGBA8I: 7,
+ FORMATLAYOUT_R32I: 8,
+
+ FORMATLAYOUT_RGBA32UI: 9,
+ FORMATLAYOUT_RGBA16UI: 10,
+ FORMATLAYOUT_RGBA8UI: 11,
+ FORMATLAYOUT_R32UI: 12
+ };
+
+ /**
+ * @param {gluVarType.FormatLayout} layout
+ * @return {string}
+ */
+ gluVarType.getFormatLayoutName = function(layout) {
+ switch (layout) {
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA32F: return 'rgba32f';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA16F: return 'rgba16f';
+ case gluVarType.FormatLayout.FORMATLAYOUT_R32F: return 'r32f';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA8: return 'rgba8';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA8_SNORM: return 'rgba8_snorm';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA32I: return 'rgba32i';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA16I: return 'rgba16i';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA8I: return 'rgba8i';
+ case gluVarType.FormatLayout.FORMATLAYOUT_R32I: return 'r32i';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA32UI: return 'rgba32ui';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA16UI: return 'rgba16ui';
+ case gluVarType.FormatLayout.FORMATLAYOUT_RGBA8UI: return 'rgba8ui';
+ case gluVarType.FormatLayout.FORMATLAYOUT_R32UI: return 'r32ui';
+ default:
+ throw new Error('Unknown layout: ' + layout);
+ }
+ };
+
+ /**
+ * @enum
+ */
+ gluVarType.MatrixOrder = {
+ MATRIXORDER_COLUMN_MAJOR: 0,
+ MATRIXORDER_ROW_MAJOR: 1
+ };
+
+ /**
+ * @param {gluVarType.MatrixOrder} qualifier
+ * @return {string}
+ */
+ gluVarType.getMatrixOrderName = function(qualifier) {
+ switch (qualifier) {
+ case gluVarType.MatrixOrder.MATRIXORDER_COLUMN_MAJOR: return 'column_major';
+ case gluVarType.MatrixOrder.MATRIXORDER_ROW_MAJOR: return 'row_major';
+ default:
+ throw new Error('Unknown qualifier: ' + qualifier);
+ }
+ };
+
+ gluVarType.MemoryAccessQualifier = {
+ MEMORYACCESSQUALIFIER_COHERENT_BIT: 0x01,
+ MEMORYACCESSQUALIFIER_VOLATILE_BIT: 0x02,
+ MEMORYACCESSQUALIFIER_RESTRICT_BIT: 0x04,
+ MEMORYACCESSQUALIFIER_READONLY_BIT: 0x08,
+ MEMORYACCESSQUALIFIER_WRITEONLY_BIT: 0x10
+ };
+ gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_MASK = (gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_WRITEONLY_BIT << 1) - 1;
+
+ /**
+ * @param {number} qualifier
+ * @return {string}
+ */
+ gluVarType.getMemoryAccessQualifierName = function(qualifier) {
+ switch (qualifier) {
+ case gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_COHERENT_BIT: return 'coherent';
+ case gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_VOLATILE_BIT: return 'volatile';
+ case gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_RESTRICT_BIT: return 'restrict';
+ case gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_READONLY_BIT: return 'readonly';
+ case gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_WRITEONLY_BIT: return 'writeonly';
+ default:
+ throw new Error('Unknown qualifier: ' + qualifier);
+ }
+ };
+
+ /**
+ * @constructor
+ * @param {number=} location
+ * @param {number=} binding
+ * @param {number=} offset
+ * @param {gluVarType.FormatLayout=} format
+ * @param {gluVarType.MatrixOrder=} matrixOrder
+ */
+ gluVarType.Layout = function(location, binding, offset, format, matrixOrder) {
+ this.location = location;
+ this.binding = binding;
+ this.offset = offset;
+ this.format = format;
+ this.matrixOrder = matrixOrder;
+ };
+
+ gluVarType.Layout.prototype.toString = function() {
+ var strings = [];
+ var str = '';
+ if (typeof this.location !== 'undefined')
+ strings.push('location=' + this.location);
+ if (typeof this.binding !== 'undefined')
+ strings.push('binding=' + this.binding);
+ if (typeof this.offset !== 'undefined')
+ strings.push('offset=' + this.offset);
+ if (typeof this.format !== 'undefined')
+ strings.push(gluVarType.getFormatLayoutName(this.format));
+ if (typeof this.matrixOrder !== 'undefined')
+ strings.push(gluVarType.getMatrixOrderName(this.matrixOrder));
+
+ if (strings.length > 0) {
+ str += 'layout(' + strings[0];
+
+ for (var i = 1; i < strings.length; i++)
+ str += ', ' + strings[i];
+ str += ')';
+ }
+
+ return str;
+ };
+
+ /**
+ * @constructor
+ * @param {gluVarType.VarType} varType
+ * @param {string} name
+ * @param {gluVarType.Storage=} storage
+ * @param {gluVarType.Interpolation=} interpolation
+ * @param {gluVarType.Layout=} layout
+ * @param {number=} memoryAccessQualifierBits
+ */
+ gluVarType.VariableDeclaration = function(varType, name, storage, interpolation, layout, memoryAccessQualifierBits) {
+ this.varType = varType;
+ this.name = name;
+ this.storage = storage;
+ this.interpolation = interpolation;
+ this.layout = layout;
+ this.memoryAccessQualifierBits = memoryAccessQualifierBits || 0;
+ };
+
+ gluVarType.VariableDeclaration.prototype.toString = function() {
+ var str = '';
+ if (typeof this.layout !== 'undefined')
+ str += this.layout.toString() + ' ';
+
+ for (var bitNdx = 0; (1 << bitNdx) & gluVarType.MemoryAccessQualifier.MEMORYACCESSQUALIFIER_MASK; ++bitNdx)
+ if (this.memoryAccessQualifierBits & (1 << bitNdx))
+ str += gluVarType.getMemoryAccessQualifierName((1 << bitNdx)) + ' ';
+
+ if (typeof this.interpolation !== 'undefined')
+ str += gluVarType.getInterpolationName(this.interpolation) + ' ';
+
+ if (typeof this.storage !== 'undefined')
+ str += gluVarType.getStorageName(this.storage) + ' ';
+
+ str += gluVarType.declareVariable(this.varType, this.name);
+
+ return str;
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarTypeUtil.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarTypeUtil.js
new file mode 100644
index 0000000000..30e198a606
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarTypeUtil.js
@@ -0,0 +1,693 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.gluVarTypeUtil');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluVarType');
+
+goog.scope(function() {
+
+ var gluVarTypeUtil = framework.opengl.gluVarTypeUtil;
+ var gluVarType = framework.opengl.gluVarType;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+
+ gluVarTypeUtil.isNum = function(c) { return /^[0-9]$/.test(c); };
+ gluVarTypeUtil.isAlpha = function(c) { return /^[a-zA-Z]$/.test(c); };
+ gluVarTypeUtil.isIdentifierChar = function(c) { return /^[a-zA-Z0-9_]$/.test(c); };
+ gluVarTypeUtil.array_op_equivalent = function(arr1, arr2) {
+ if (arr1.length != arr2.length) return false;
+ for (var i = 0; i < arr1.length; ++i) {
+ if (arr1[i].isnt(arr2[1])) return false;
+ }
+ return true;
+ };
+
+ /**
+ * gluVarTypeUtil.VarTokenizer class.
+ * @param {string} str
+ * @constructor
+ */
+ gluVarTypeUtil.VarTokenizer = function(str) {
+
+ /** @private */
+ this.m_str = str;
+ /** @private */
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.length;
+ /** @private */
+ this.m_tokenStart = 0;
+ /** @private */
+ this.m_tokenLen = 0;
+
+ this.advance();
+
+ };
+ gluVarTypeUtil.VarTokenizer.s_Token = {
+ IDENTIFIER: 0,
+ LEFT_BRACKET: 1,
+ RIGHT_BRACKET: 2,
+ PERIOD: 3,
+ NUMBER: 4,
+ END: 5
+ };
+ gluVarTypeUtil.VarTokenizer.s_Token.length = Object.keys(gluVarTypeUtil.VarTokenizer.s_Token).length;
+
+ gluVarTypeUtil.VarTokenizer.prototype.getToken = function() {
+ return this.m_token;
+ };
+ gluVarTypeUtil.VarTokenizer.prototype.getIdentifier = function() {
+ return this.m_str.substr(this.m_tokenStart, this.m_tokenLen);
+ };
+ gluVarTypeUtil.VarTokenizer.prototype.getNumber = function() {
+ return parseInt(this.getIdentifier(), 10);
+ };
+ gluVarTypeUtil.VarTokenizer.prototype.getCurrentTokenStartLocation = function() {
+ return this.m_tokenStart;
+ };
+ gluVarTypeUtil.VarTokenizer.prototype.getCurrentTokenEndLocation = function() {
+ return this.m_tokenStart + this.m_tokenLen;
+ };
+
+ gluVarTypeUtil.VarTokenizer.prototype.advance = function() {
+
+ if (this.m_token == gluVarTypeUtil.VarTokenizer.s_Token.END) {
+ throw new Error('No more tokens.');
+ }
+
+ this.m_tokenStart += this.m_tokenLen;
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.length;
+ this.m_tokenLen = 1;
+
+ if (this.m_tokenStart >= this.m_str.length) {
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.END;
+
+ } else if (this.m_str[this.m_tokenStart] == '[') {
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.LEFT_BRACKET;
+
+ } else if (this.m_str[this.m_tokenStart] == ']') {
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.RIGHT_BRACKET;
+
+ } else if (this.m_str[this.m_tokenStart] == '.') {
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.PERIOD;
+
+ } else if (gluVarTypeUtil.isNum(this.m_str[this.m_tokenStart])) {
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.NUMBER;
+ while (gluVarTypeUtil.isNum(this.m_str[this.m_tokenStart + this.m_tokenLen])) {
+ this.m_tokenLen += 1;
+ }
+
+ } else if (gluVarTypeUtil.isIdentifierChar(this.m_str[this.m_tokenStart])) {
+ this.m_token = gluVarTypeUtil.VarTokenizer.s_Token.IDENTIFIER;
+ while (gluVarTypeUtil.isIdentifierChar(this.m_str[this.m_tokenStart + this.m_tokenLen])) {
+ this.m_tokenLen += 1;
+ }
+
+ } else {
+ throw new Error('Unexpected character');
+ }
+
+ };
+
+ /**
+ * VarType subtype path utilities class.
+ * @param {gluVarTypeUtil.VarTypeComponent.s_Type} type
+ * @param {number} index
+ * @constructor
+ */
+ gluVarTypeUtil.VarTypeComponent = function(type, index) {
+ /** @type {gluVarTypeUtil.VarTypeComponent.s_Type} */ this.type = type;
+ this.index = index || 0;
+ };
+
+ gluVarTypeUtil.VarTypeComponent.prototype.is = function(other) {
+ return this.type == other.type && this.index == other.index;
+ };
+ gluVarTypeUtil.VarTypeComponent.prototype.isnt = function(other) {
+ return this.type != other.type || this.index != other.index;
+ };
+
+ /**
+ * @enum
+ */
+ gluVarTypeUtil.VarTypeComponent.s_Type = {
+ STRUCT_MEMBER: 0,
+ ARRAY_ELEMENT: 1,
+ MATRIX_COLUMN: 2,
+ VECTOR_COMPONENT: 3
+ };
+
+ /**
+ * Type path formatter.
+ * @param {gluVarType.VarType} type_
+ * @param {Array<gluVarTypeUtil.VarTypeComponent>} path_
+ * @constructor
+ */
+ gluVarTypeUtil.TypeAccessFormat = function(type_, path_) {
+ this.type = type_;
+ this.path = path_;
+ };
+
+ gluVarTypeUtil.TypeAccessFormat.prototype.toString = function() {
+ var curType = this.type;
+ var str = '';
+
+ for (var i = 0; i < this.path.length; i++) {
+ var iter = this.path[i];
+ switch (iter.type) {
+ case gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT:
+ curType = curType.getElementType(); // Update current type.
+ // Fall-through.
+
+ case gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN:
+ case gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT:
+ str += '[' + iter.index + ']';
+ break;
+
+ case gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER: {
+ var member = curType.getStruct().getMember(i);
+ str += '.' + member.getName();
+ curType = member.getType();
+ break;
+ }
+
+ default:
+ throw new Error('Unrecognized type:' + iter.type);
+ }
+ }
+
+ return str;
+ };
+
+ /** gluVarTypeUtil.SubTypeAccess
+ * @param {gluVarType.VarType} type
+ * @constructor
+ */
+ gluVarTypeUtil.SubTypeAccess = function(type) {
+
+ this.m_type = null; // VarType
+ this.m_path = []; // TypeComponentVector
+
+ };
+
+ /** @private */
+ gluVarTypeUtil.SubTypeAccess.prototype.helper = function(type, ndx) {
+ this.m_path.push(new gluVarTypeUtil.VarTypeComponent(type, ndx));
+ if (!this.isValid()) {
+ throw new Error;
+ }
+ return this;
+ };
+
+ gluVarTypeUtil.SubTypeAccess.prototype.member = function(ndx) {
+ return this.helper(gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER, ndx);
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.element = function(ndx) {
+ return this.helper(gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT, ndx);
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.column = function(ndx) {
+ return this.helper(gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN, ndx);
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.component = function(ndx) {
+ return this.helper(gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT, ndx);
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.parent = function() {
+ if (!this.m_path.length) {
+ throw new Error;
+ }
+ this.m_path.pop();
+ return this;
+ };
+
+ gluVarTypeUtil.SubTypeAccess.prototype.isValid = function() {
+ return gluVarTypeUtil.isValidTypePath(this.m_type, this.m_path);
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.getType = function() {
+ return gluVarTypeUtil.getVarType(this.m_type, this.m_path);
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.getPath = function() {
+ return this.m_path;
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.empty = function() {
+ return !this.m_path.length;
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.is = function(other) {
+ return (
+ gluVarTypeUtil.array_op_equivalent(this.m_path, other.m_path) &&
+ this.m_type.is(other.m_type)
+ );
+ };
+ gluVarTypeUtil.SubTypeAccess.prototype.isnt = function(other) {
+ return (
+ !gluVarTypeUtil.array_op_equivalent(this.m_path, other.m_path) ||
+ this.m_type.isnt(other.m_type)
+ );
+ };
+
+ /**
+ * Subtype iterator parent class.
+ * basic usage for all child classes:
+ * for (var i = new gluVarTypeUtil.BasicTypeIterator(type) ; !i.end() ; i.next()) {
+ * var j = i.getType();
+ * }
+ * @constructor
+ */
+ gluVarTypeUtil.SubTypeIterator = function(type) {
+
+ /** @private */
+ this.m_type = null; // const VarType*
+ /** @private */
+ this.m_path = []; // TypeComponentVector
+
+ if (type) {
+ this.m_type = type;
+ this.findNext();
+ }
+
+ };
+
+ gluVarTypeUtil.SubTypeIterator.prototype.isExpanded = function(type) {
+ throw new Error('This function must be overriden in child class');
+ };
+
+ /** removeTraversed
+ * @private
+ */
+ gluVarTypeUtil.SubTypeIterator.prototype.removeTraversed = function() {
+
+ while (this.m_path.length) {
+ var curComp = this.m_path[this.m_path.length - 1]; // gluVarTypeUtil.VarTypeComponent&
+ var parentType = gluVarTypeUtil.getVarType(this.m_type, this.m_path, 0, this.m_path.length - 1); // VarType
+
+ if (curComp.type == gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN) {
+ if (!gluShaderUtil.isDataTypeMatrix(parentType.getBasicType())) {
+ throw new Error('Isn\'t a matrix.');
+ }
+ if (curComp.index + 1 < gluShaderUtil.getDataTypeMatrixNumColumns(parentType.getBasicType())) {
+ break;
+ }
+
+ } else if (curComp.type == gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT) {
+ if (!gluShaderUtil.isDataTypeVector(parentType.getBasicType())) {
+ throw new Error('Isn\'t a vector.');
+ }
+ if (curComp.index + 1 < gluShaderUtil.getDataTypeScalarSize(parentType.getBasicType())) {
+ break;
+ }
+
+ } else if (curComp.type == gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT) {
+ if (!parentType.isArrayType()) {
+ throw new Error('Isn\'t an array.');
+ }
+ if (curComp.index + 1 < parentType.getArraySize()) {
+ break;
+ }
+
+ } else if (curComp.type == gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER) {
+ if (!parentType.isStructType()) {
+ throw new Error('Isn\'t a struct.');
+ }
+ if (curComp.index + 1 < parentType.getStruct().getNumMembers()) {
+ break;
+ }
+
+ }
+
+ this.m_path.pop();
+ }
+ };
+ gluVarTypeUtil.SubTypeIterator.prototype.findNext = function() {
+
+ if (this.m_path.length > 0) {
+ // Increment child counter in current level.
+ var curComp = this.m_path[this.m_path.length - 1]; // gluVarTypeUtil.VarTypeComponent&
+ curComp.index += 1;
+ }
+
+ for (;;) {
+
+ var curType = gluVarTypeUtil.getVarType(this.m_type, this.m_path); // VarType
+
+ if (this.isExpanded(curType))
+ break;
+
+ // Recurse into child type.
+ if (curType.isBasicType()) {
+ var basicType = curType.getBasicType(); // DataType
+
+ if (gluShaderUtil.isDataTypeMatrix(basicType)) {
+ this.m_path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN, 0));
+
+ } else if (gluShaderUtil.isDataTypeVector(basicType)) {
+ this.m_path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT, 0));
+
+ } else {
+ throw new Error('Cant expand scalars - isExpanded() is buggy.');
+ }
+
+ } else if (curType.isArrayType()) {
+ this.m_path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT, 0));
+
+ } else if (curType.isStructType()) {
+ this.m_path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER, 0));
+
+ } else {
+ throw new Error();
+ }
+ }
+
+ };
+ gluVarTypeUtil.SubTypeIterator.prototype.end = function() {
+ return (this.m_type == null);
+ };
+ /** next
+ * equivelant to operator++(), doesnt return.
+ */
+ gluVarTypeUtil.SubTypeIterator.prototype.next = function() {
+ if (this.m_path.length > 0) {
+ // Remove traversed nodes.
+ this.removeTraversed();
+
+ if (this.m_path.length > 0)
+ this.findNext();
+ else
+ this.m_type = null; // Unset type to signal end.
+ } else {
+ if (!this.isExpanded(gluVarTypeUtil.getVarType(this.m_type, this.m_path))) {
+ throw new Error('First type was already expanded.');
+ }
+ this.m_type = null;
+ }
+ };
+ gluVarTypeUtil.SubTypeIterator.prototype.getType = function() {
+ return gluVarTypeUtil.getVarType(this.m_type, this.m_path);
+ };
+ gluVarTypeUtil.SubTypeIterator.prototype.getPath = function() {
+ return this.m_path;
+ };
+
+ gluVarTypeUtil.SubTypeIterator.prototype.toString = function() {
+ var x = new gluVarTypeUtil.TypeAccessFormat(this.m_type, this.m_path);
+ return x.toString();
+ };
+
+ /** gluVarTypeUtil.BasicTypeIterator
+ * @param {gluVarType.VarType} type
+ * @constructor
+ * @extends {gluVarTypeUtil.SubTypeIterator}
+ */
+ gluVarTypeUtil.BasicTypeIterator = function(type) {
+ gluVarTypeUtil.SubTypeIterator.call(this, type);
+ };
+ gluVarTypeUtil.BasicTypeIterator.prototype = Object.create(gluVarTypeUtil.SubTypeIterator.prototype);
+ gluVarTypeUtil.BasicTypeIterator.prototype.constructor = gluVarTypeUtil.BasicTypeIterator;
+
+ gluVarTypeUtil.BasicTypeIterator.prototype.isExpanded = function(type) {
+ return type.isBasicType();
+ };
+
+ /** gluVarTypeUtil.VectorTypeIterator
+ * @param {gluVarType.VarType} type
+ * @constructor
+ * @extends {gluVarTypeUtil.SubTypeIterator}
+ */
+ gluVarTypeUtil.VectorTypeIterator = function(type) {
+ gluVarTypeUtil.SubTypeIterator.call(this, type);
+ };
+ gluVarTypeUtil.VectorTypeIterator.prototype = Object.create(gluVarTypeUtil.SubTypeIterator.prototype);
+ gluVarTypeUtil.VectorTypeIterator.prototype.constructor = gluVarTypeUtil.VectorTypeIterator;
+
+ gluVarTypeUtil.VectorTypeIterator.prototype.isExpanded = function(type) {
+ return type.isBasicType() && gluShaderUtil.isDataTypeScalarOrVector(type.getBasicType());
+ };
+
+ /** gluVarTypeUtil.ScalarTypeIterator
+ * @param {gluVarType.VarType} type
+ * @constructor
+ * @extends {gluVarTypeUtil.SubTypeIterator}
+ */
+ gluVarTypeUtil.ScalarTypeIterator = function(type) {
+ gluVarTypeUtil.SubTypeIterator.call(this, type);
+ };
+ gluVarTypeUtil.ScalarTypeIterator.prototype = Object.create(gluVarTypeUtil.SubTypeIterator.prototype);
+ gluVarTypeUtil.ScalarTypeIterator.prototype.constructor = gluVarTypeUtil.ScalarTypeIterator;
+
+ gluVarTypeUtil.ScalarTypeIterator.prototype.isExpanded = function(type) {
+ return type.isBasicType() && gluShaderUtil.isDataTypeScalar(type.getBasicType());
+ };
+
+ gluVarTypeUtil.inBounds = (function(x, a, b) { return a <= x && x < b; });
+
+ /** gluVarTypeUtil.isValidTypePath
+ * @param {gluVarType.VarType} type
+ * @param {Array<gluVarTypeUtil.VarTypeComponent>} array
+ * @param {number=} begin
+ * @param {number=} end
+ * @return {boolean}
+ */
+ gluVarTypeUtil.isValidTypePath = function(type, array, begin, end) {
+
+ if (typeof(begin) == 'undefined') {begin = 0;}
+ if (typeof(end) == 'undefined') {begin = array.length;}
+
+ var curType = type; // const VarType*
+ var pathIter = begin; // Iterator
+
+ // Process struct member and array element parts of path.
+ while (pathIter != end) {
+ var element = array[pathIter];
+
+ if (element.type == gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER) {
+
+ if (!curType.isStructType() || !gluVarTypeUtil.inBounds(element.index, 0, curType.getStruct().getNumMembers())) {
+ return false;
+ }
+
+ curType = curType.getStruct().getMember(element.index).getType();
+
+ } else if (element.type == gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT) {
+ if (
+ !curType.isArrayType() ||
+ (
+ curType.getArraySize() != gluVarType.VarType.UNSIZED_ARRAY &&
+ !gluVarTypeUtil.inBounds(element.index, 0, curType.getArraySize())
+ )
+ ) {
+ return false;
+ }
+
+ curType = curType.getElementType();
+ } else {
+ break;
+ }
+
+ ++pathIter;
+ }
+
+ if (pathIter != end) {
+ if (!(
+ array[pathIter].type == gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN ||
+ array[pathIter].type == gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT
+ )) {
+ throw new Error('Not a matrix or a vector');
+ }
+
+ // Current type should be basic type.
+ if (!curType.isBasicType()) {
+ return false;
+ }
+
+ var basicType = curType.getBasicType(); // DataType
+
+ if (array[pathIter].type == gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN) {
+ if (!gluShaderUtil.isDataTypeMatrix(basicType)) {
+ return false;
+ }
+
+ basicType = gluShaderUtil.getDataTypeFloatVec(gluShaderUtil.getDataTypeMatrixNumRows(basicType));
+ ++pathIter;
+ }
+
+ if (pathIter != end && array[pathIter].type == gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT) {
+ if (!gluShaderUtil.isDataTypeVector(basicType))
+ return false;
+
+ basicType = gluShaderUtil.getDataTypeScalarType(basicType);
+ ++pathIter;
+ }
+ }
+
+ return pathIter == end;
+ };
+
+ /** gluVarTypeUtil.getVarType
+ * @param {gluVarType.VarType} type
+ * @param {Array<gluVarTypeUtil.VarTypeComponent>} array
+ * @param {number=} start
+ * @param {number=} end
+ * @return {gluVarType.VarType}
+ */
+ gluVarTypeUtil.getVarType = function(type, array, start, end) {
+
+ if (typeof(start) == 'undefined') start = 0;
+ if (typeof(end) == 'undefined') end = array.length;
+
+ if (!gluVarTypeUtil.isValidTypePath(type, array, start, end)) {
+ throw new Error('Type is invalid');
+ }
+
+ var curType = type; // const VarType*
+ var element = null; // Iterator
+ var pathIter = 0;
+
+ // Process struct member and array element parts of path.
+ for (pathIter = start; pathIter != end; ++pathIter) {
+ element = array[pathIter];
+
+ if (element.type == gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER) {
+ curType = curType.getStruct().getMember(element.index).getType();
+
+ } else if (element.type == gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT) {
+ curType = curType.getElementType();
+
+ } else {
+ break;
+
+ }
+ }
+
+ if (pathIter != end) {
+
+ var basicType = curType.getBasicType(); // DataType
+ var precision = curType.getPrecision(); // Precision
+
+ if (element.type == gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN) {
+ basicType = gluShaderUtil.getDataTypeFloatVec(gluShaderUtil.getDataTypeMatrixNumRows(basicType));
+ element = array[++pathIter];
+ }
+
+ if (pathIter != end && element.type == gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT) {
+ basicType = gluShaderUtil.getDataTypeScalarTypeAsDataType(basicType);
+ element = array[++pathIter];
+ }
+
+ if (pathIter != end) {
+ throw new Error();
+ }
+ return gluVarType.newTypeBasic(basicType, precision);
+ } else {
+ /* TODO: Original code created an object copy. We are returning reference to the same object */
+ return curType;
+ }
+ };
+
+ gluVarTypeUtil.parseVariableName = function(nameWithPath) {
+ var tokenizer = new gluVarTypeUtil.VarTokenizer(nameWithPath);
+ if (tokenizer.getToken() != gluVarTypeUtil.VarTokenizer.s_Token.IDENTIFIER) {
+ throw new Error('Not an identifier.');
+ }
+ return tokenizer.getIdentifier();
+ };
+
+ // returns an array (TypeComponentVector& path)
+ // params: const char*, const VarType&
+ gluVarTypeUtil.parseTypePath = function(nameWithPath, type) {
+
+ var tokenizer = new gluVarTypeUtil.VarTokenizer(nameWithPath);
+
+ if (tokenizer.getToken() == gluVarTypeUtil.VarTokenizer.s_Token.IDENTIFIER) {
+ tokenizer.advance();
+ }
+
+ var path = [];
+
+ while (tokenizer.getToken() != gluVarTypeUtil.VarTokenizer.s_Token.END) {
+
+ var curType = gluVarTypeUtil.getVarType(type, path);
+
+ if (tokenizer.getToken() == gluVarTypeUtil.VarTokenizer.s_Token.PERIOD) {
+
+ tokenizer.advance();
+ if (tokenizer.getToken() != gluVarTypeUtil.VarTokenizer.s_Token.IDENTIFIER) {
+ throw new Error();
+ }
+ if (!curType.isStructType()) {
+ throw new Error('Invalid field selector');
+ }
+
+ // Find member.
+ var memberName = tokenizer.getIdentifier();
+ var ndx = 0;
+ for (; ndx < curType.getStruct().getSize(); ++ndx) {
+
+ if (memberName == curType.getStruct().getMember(ndx).getName()) {
+ break;
+ }
+
+ }
+ if (ndx >= curType.getStruct().getSize()) {
+ throw new Error('Member not found in type: ' + memberName);
+ }
+
+ path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER, ndx));
+ tokenizer.advance();
+
+ } else if (tokenizer.getToken() == gluVarTypeUtil.VarTokenizer.s_Token.LEFT_BRACKET) {
+
+ tokenizer.advance();
+ if (tokenizer.getToken() != gluVarTypeUtil.VarTokenizer.s_Token.NUMBER) {
+ throw new Error();
+ }
+
+ var ndx = tokenizer.getNumber();
+
+ if (curType.isArrayType()) {
+ if (!gluVarTypeUtil.inBounds(ndx, 0, curType.getArraySize())) throw new Error;
+ path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT, ndx));
+
+ } else if (curType.isBasicType() && gluShaderUtil.isDataTypeMatrix(curType.getBasicType())) {
+ if (!gluVarTypeUtil.inBounds(ndx, 0, gluShaderUtil.getDataTypeMatrixNumColumns(curType.getBasicType()))) throw new Error;
+ path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN, ndx));
+
+ } else if (curType.isBasicType() && gluShaderUtil.isDataTypeVector(curType.getBasicType())) {
+ if (!gluVarTypeUtil.inBounds(ndx, 0, gluShaderUtil.getDataTypeScalarSize(curType.getBasicType()))) throw new Error;
+ path.push(new gluVarTypeUtil.VarTypeComponent(gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT, ndx));
+
+ } else {
+ //TCU_FAIL
+ throw new Error('Invalid subscript');
+ }
+
+ tokenizer.advance();
+ if (tokenizer.getToken() != gluVarTypeUtil.VarTokenizer.s_Token.RIGHT_BRACKET) {
+ throw new Error('Expected token RIGHT_BRACKET');
+ }
+ tokenizer.advance();
+
+ } else {
+ // TCU_FAIL
+ throw new Error('Unexpected token');
+ }
+ }
+
+ return path;
+
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/00_test_list.txt
new file mode 100644
index 0000000000..7db3d9d5c7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/00_test_list.txt
@@ -0,0 +1 @@
+referencecontext.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/referencecontext.html b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/referencecontext.html
new file mode 100644
index 0000000000..f3ba0ed262
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/referencecontext.html
@@ -0,0 +1,32 @@
+<html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>Reference context test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('framework.opengl.simplereference.sglrReferenceContextTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+ try {
+ framework.opengl.simplereference.sglrReferenceContextTest.run(gl);
+ }
+ catch(err)
+ {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrGLContext.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrGLContext.js
new file mode 100644
index 0000000000..13f75e8f5e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrGLContext.js
@@ -0,0 +1,231 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.simplereference.sglrShaderProgram');
+goog.require('framework.referencerenderer.rrDefs');
+goog.require('framework.referencerenderer.rrMultisamplePixelBufferAccess');
+goog.require('framework.referencerenderer.rrRenderState');
+goog.require('framework.referencerenderer.rrRenderer');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+
+goog.scope(function() {
+
+ var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+ var tcuTexture = framework.common.tcuTexture;
+ var deUtil = framework.delibs.debase.deUtil;
+ var deMath = framework.delibs.debase.deMath;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
+ var rrDefs = framework.referencerenderer.rrDefs;
+ var rrMultisamplePixelBufferAccess = framework.referencerenderer.rrMultisamplePixelBufferAccess;
+ var rrRenderer = framework.referencerenderer.rrRenderer;
+ var rrRenderState = framework.referencerenderer.rrRenderState;
+ var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /**
+ * sglrGLContext.GLContext wraps the standard WebGL context to be able to be used interchangeably with the ReferenceContext
+ * @constructor
+ * @extends {WebGL2RenderingContext}
+ * @param {?WebGL2RenderingContext} context
+ * @param {Array<number>=} viewport
+ */
+ sglrGLContext.GLContext = function(context, viewport) {
+ DE_ASSERT(context);
+
+ var functionwrapper = function(context, fname) {
+ return function() {
+ return context[fname].apply(context, arguments);
+ };
+ };
+
+ var wrap = {};
+ for (var i in context) {
+ try {
+ if (typeof context[i] == 'function') {
+ wrap[i] = functionwrapper(context, i);
+ } else {
+ wrap[i] = context[i];
+ }
+ } catch (e) {
+ throw new Error('GLContext: Error accessing ' + i);
+ }
+ }
+ if (viewport)
+ context.viewport(viewport[0], viewport[1], viewport[2], viewport[3]);
+
+ /**
+ * createProgram
+ * @override
+ * @param {sglrShaderProgram.ShaderProgram=} shader
+ * @return {!WebGLProgram}
+ */
+ this.createProgram = function(shader) {
+ var program = new gluShaderProgram.ShaderProgram(
+ context,
+ gluShaderProgram.makeVtxFragSources(
+ shader.m_vertSrc,
+ shader.m_fragSrc
+ )
+ );
+
+ if (!program.isOk()) {
+ bufferedLogToConsole(program.toString());
+ testFailedOptions('Compile failed', true);
+ }
+ return program.getProgram();
+ };
+ wrap['createProgram'] = this.createProgram;
+
+ /**
+ * Draws quads from vertex arrays
+ * @param {number} primitive Primitive type
+ * @param {number} first First vertex to begin drawing with
+ * @param {number} count Number of vertices
+ */
+ var drawQuads = function(primitive, first, count) {
+ context.drawArrays(primitive, first, count);
+ };
+ wrap['drawQuads'] = drawQuads;
+
+ /**
+ * @return {number}
+ */
+ var getWidth = function() {
+ if(viewport)
+ return viewport[2];
+ else
+ return context.drawingBufferWidth;
+ };
+ wrap['getWidth'] = getWidth;
+
+ /**
+ * @return {number}
+ */
+ var getHeight = function() {
+ if(viewport)
+ return viewport[3];
+ else
+ return context.drawingBufferHeight;
+ };
+ wrap['getHeight'] = getHeight;
+
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ * @param {number} format
+ * @param {number} dataType
+ * @param {ArrayBuffer|ArrayBufferView} data
+ */
+ var readPixels = function(x, y, width, height, format, dataType, data) {
+ /** @type {?ArrayBufferView} */ var dataArr;
+ if (!ArrayBuffer.isView(data)) {
+ var type = gluTextureUtil.mapGLChannelType(dataType, true);
+ var dataArrType = tcuTexture.getTypedArray(type);
+ dataArr = new dataArrType(data);
+ } else {
+ dataArr = /** @type {?ArrayBufferView} */ (data);
+ }
+
+ context.readPixels(x, y, width, height, format, dataType, dataArr);
+ };
+ wrap['readPixels'] = readPixels;
+
+ /**
+ * @param {number} target
+ * @param {number} level
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ */
+ var texImage2DDelegate = function(target, level, internalFormat, width, height) {
+ var format;
+ var dataType;
+
+ switch(internalFormat)
+ {
+ case gl.ALPHA:
+ case gl.LUMINANCE:
+ case gl.LUMINANCE_ALPHA:
+ case gl.RGB:
+ case gl.RGBA:
+ format = internalFormat;
+ dataType = gl.UNSIGNED_BYTE;
+ break;
+ default:
+ {
+ var transferFmt = gluTextureUtil.getTransferFormat(gluTextureUtil.mapGLInternalFormat(internalFormat));
+ format = transferFmt.format;
+ dataType = transferFmt.dataType;
+ break;
+ }
+ }
+ context.texImage2D(target, level, internalFormat, width, height, 0, format, dataType, null);
+ };
+ wrap['texImage2DDelegate'] = texImage2DDelegate;
+
+ return wrap;
+ };
+
+ /**
+ * createProgram - This had to be added here as dummy to remove a warning when the only context used is GLContext (no reference context)
+ * @override
+ * @param {sglrShaderProgram.ShaderProgram=} shader
+ * @return {!WebGLProgram}
+ */
+ sglrGLContext.GLContext.prototype.createProgram = function(shader) {return this.createProgram();};
+
+ /**
+ * @param ctx GL-like context
+ * @param {string} name
+ * @return {boolean}
+ */
+ sglrGLContext.isExtensionSupported = function(ctx, name) {
+ var extns = ctx.getSupportedExtensions();
+ var found = false;
+ if (extns) {
+ var index = extns.indexOf(name);
+ if (index != -1)
+ found = true;
+ }
+ return found;
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContext.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContext.js
new file mode 100644
index 0000000000..523dbe607f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContext.js
@@ -0,0 +1,4986 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.common.tcuMatrix');
+goog.require('framework.common.tcuMatrixUtil');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.simplereference.sglrReferenceUtils');
+goog.require('framework.opengl.simplereference.sglrShaderProgram');
+goog.require('framework.referencerenderer.rrDefs');
+goog.require('framework.referencerenderer.rrGenericVector');
+goog.require('framework.referencerenderer.rrMultisamplePixelBufferAccess');
+goog.require('framework.referencerenderer.rrRenderState');
+goog.require('framework.referencerenderer.rrRenderer');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+
+goog.scope(function() {
+
+ var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
+ var rrMultisamplePixelBufferAccess = framework.referencerenderer.rrMultisamplePixelBufferAccess;
+ var tcuTexture = framework.common.tcuTexture;
+ var deMath = framework.delibs.debase.deMath;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var rrRenderer = framework.referencerenderer.rrRenderer;
+ var rrDefs = framework.referencerenderer.rrDefs;
+ var rrGenericVector = framework.referencerenderer.rrGenericVector;
+ var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+ var rrRenderState = framework.referencerenderer.rrRenderState;
+ var sglrReferenceUtils = framework.opengl.simplereference.sglrReferenceUtils;
+ var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
+ var tcuMatrix = framework.common.tcuMatrix;
+ var tcuMatrixUtil = framework.common.tcuMatrixUtil;
+
+ sglrReferenceContext.rrMPBA = rrMultisamplePixelBufferAccess;
+
+ //TODO: Implement automatic error checking in sglrReferenceContext, optional on creation.
+
+ /** @typedef {WebGLRenderbuffer|WebGLTexture|sglrReferenceContext.Renderbuffer|sglrReferenceContext.TextureContainer} */ sglrReferenceContext.AnyRenderbuffer;
+
+ /** @typedef {WebGLFramebuffer|sglrReferenceContext.Framebuffer} */ sglrReferenceContext.AnyFramebuffer;
+
+ /**
+ * @param {number} error
+ * @param {number} message
+ * @throws {Error}
+ */
+ sglrReferenceContext.GLU_EXPECT_NO_ERROR = function(error, message) {
+ if (error !== gl.NONE) {
+ bufferedLogToConsole('Assertion failed message:' + message);
+ }
+ };
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ // /* TODO: remove */
+ // /** @type {WebGL2RenderingContext} */ var gl;
+
+ sglrReferenceContext.MAX_TEXTURE_SIZE_LOG2 = 14;
+ sglrReferenceContext.MAX_TEXTURE_SIZE = 1 << sglrReferenceContext.MAX_TEXTURE_SIZE_LOG2;
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ * @return {number}
+ */
+ sglrReferenceContext.getNumMipLevels2D = function(width, height) {
+ return Math.floor(Math.log2(Math.max(width, height)) + 1);
+ };
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @return {number}
+ */
+ sglrReferenceContext.getNumMipLevels3D = function(width, height, depth) {
+ return Math.floor(Math.log2(Math.max(width, height, depth)) + 1);
+ };
+
+ /**
+ * @param {number} baseLevelSize
+ * @param {number} levelNdx
+ * @return {number}
+ */
+ sglrReferenceContext.getMipLevelSize = function(baseLevelSize, levelNdx) {
+ return Math.max(baseLevelSize >> levelNdx, 1);
+ };
+
+ sglrReferenceContext.mapGLCubeFace = function(face) {
+ switch (face) {
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_X: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X;
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_X: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_X;
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y;
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Y: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y;
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z;
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Z: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z;
+ default: throw new Error('Invalid cube face: ' + face);
+ }
+ };
+
+ /**
+ * @param {tcuTexture.FilterMode} mode
+ * @return {boolean}
+ */
+ sglrReferenceContext.isMipmapFilter = function(/*const tcu::Sampler::FilterMode*/ mode) {
+ return mode != tcuTexture.FilterMode.NEAREST && mode != tcuTexture.FilterMode.LINEAR;
+ };
+
+ sglrReferenceContext.getNumMipLevels1D = function(size) {
+ return Math.floor(Math.log2(size)) + 1;
+ };
+
+ /**
+ * @param {?sglrReferenceContext.TextureType} type
+ * @return {sglrReferenceContext.TexTarget}
+ */
+ sglrReferenceContext.texLayeredTypeToTarget = function(type) {
+ switch (type) {
+ case sglrReferenceContext.TextureType.TYPE_2D_ARRAY: return sglrReferenceContext.TexTarget.TEXTARGET_2D_ARRAY;
+ case sglrReferenceContext.TextureType.TYPE_3D: return sglrReferenceContext.TexTarget.TEXTARGET_3D;
+ case sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_ARRAY;
+ default: throw new Error('Invalid texture type: ' + type);
+ }
+ };
+
+ /**
+ * @param {rrDefs.IndexType} indexType
+ * @return {number}
+ * @throws {Error}
+ */
+ sglrReferenceContext.getFixedRestartIndex = function(indexType) {
+ switch (indexType) {
+ case rrDefs.IndexType.INDEXTYPE_UINT8: return 0xFF;
+ case rrDefs.IndexType.INDEXTYPE_UINT16: return 0xFFFF;
+ case rrDefs.IndexType.INDEXTYPE_UINT32: return 0xFFFFFFFF;
+ default:
+ throw new Error('Unrecognized index type: ' + indexType);
+ }
+ };
+
+ /**
+ * @constructor
+ * @param {sglrShaderProgram.ShaderProgram} program
+ */
+ sglrReferenceContext.ShaderProgramObjectContainer = function(program) {
+ this.m_program = program;
+ /** @type {boolean} */ this.m_deleteFlag = false;
+ };
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ * @constructor
+ */
+ sglrReferenceContext.ReferenceContextLimits = function(gl) {
+ /** @type {number} */ this.maxTextureImageUnits = 16;
+ /** @type {number} */ this.maxTexture2DSize = 2048;
+ /** @type {number} */ this.maxTextureCubeSize = 2048;
+ /** @type {number} */ this.maxTexture2DArrayLayers = 256;
+ /** @type {number} */ this.maxTexture3DSize = 256;
+ /** @type {number} */ this.maxRenderbufferSize = 2048;
+ /** @type {number} */ this.maxVertexAttribs = 16;
+
+ if (gl) {
+ this.maxTextureImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
+ this.maxTexture2DSize = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE));
+ this.maxTextureCubeSize = /** @type {number} */ (gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE));
+ this.maxRenderbufferSize = /** @type {number} */ (gl.getParameter(gl.MAX_RENDERBUFFER_SIZE));
+ this.maxVertexAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ this.maxTexture2DArrayLayers = /** @type {number} */ (gl.getParameter(gl.MAX_ARRAY_TEXTURE_LAYERS));
+ this.maxTexture3DSize = /** @type {number} */ (gl.getParameter(gl.MAX_3D_TEXTURE_SIZE));
+
+ // Limit texture sizes to supported values
+ this.maxTexture2DSize = Math.min(this.maxTexture2DSize, sglrReferenceContext.MAX_TEXTURE_SIZE);
+ this.maxTextureCubeSize = Math.min(this.maxTextureCubeSize, sglrReferenceContext.MAX_TEXTURE_SIZE);
+ this.maxTexture3DSize = Math.min(this.maxTexture3DSize, sglrReferenceContext.MAX_TEXTURE_SIZE);
+
+ sglrReferenceContext.GLU_EXPECT_NO_ERROR(gl.getError(), gl.NO_ERROR);
+ }
+
+ /* TODO: Port
+ // \todo [pyry] Figure out following things:
+ // + supported fbo configurations
+ // ...
+
+ // \todo [2013-08-01 pyry] Do we want to make these conditional based on renderCtx?
+ addExtension("gl.EXT_color_buffer_half_float");
+ addExtension("gl.WEBGL_color_buffer_float");
+ */
+ };
+
+ /**
+ * @enum
+ */
+ sglrReferenceContext.TextureType = {
+ TYPE_2D: 0,
+ TYPE_CUBE_MAP: 1,
+ TYPE_2D_ARRAY: 2,
+ TYPE_3D: 3,
+ TYPE_CUBE_MAP_ARRAY: 4
+ };
+
+ /**
+ * @constructor
+ * @implements {rrDefs.Sampler}
+ * @param {sglrReferenceContext.TextureType} type
+ */
+ sglrReferenceContext.Texture = function(type) {
+ // NamedObject.call(this, name);
+ /** @type {sglrReferenceContext.TextureType} */ this.m_type = type;
+ /** @type {boolean} */ this.m_immutable = false;
+ /** @type {number} */ this.m_baseLevel = 0;
+ /** @type {number} */ this.m_maxLevel = 1000;
+ /** @type {tcuTexture.Sampler} */ this.m_sampler = new tcuTexture.Sampler(
+ tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.NEAREST_MIPMAP_LINEAR,
+ tcuTexture.FilterMode.LINEAR,
+ 0,
+ true,
+ tcuTexture.CompareMode.COMPAREMODE_NONE,
+ 0,
+ [0, 0, 0, 0],
+ true);
+ };
+
+ /**
+ * @param {Array<number>} pos
+ * @param {number=} lod
+ * @throws {Error}
+ */
+ sglrReferenceContext.Texture.prototype.sample = function(pos, lod) {throw new Error('Intentionally empty. Call method from child class instead'); };
+
+ /**
+ * @param {Array<Array<number>>} packetTexcoords
+ * @param {number} lodBias
+ * @throws {Error}
+ */
+ sglrReferenceContext.Texture.prototype.sample4 = function(packetTexcoords, lodBias) {throw new Error('Intentionally empty. Call method from child class instead'); };
+
+ // sglrReferenceContext.Texture.prototype = Object.create(NamedObject.prototype);
+ // sglrReferenceContext.Texture.prototype.constructor = sglrReferenceContext.Texture;
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.Texture.prototype.getType = function() { return this.m_type; };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.Texture.prototype.getBaseLevel = function() { return this.m_baseLevel; };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.Texture.prototype.getMaxLevel = function() { return this.m_maxLevel; };
+
+ /**
+ * @return {boolean}
+ */
+ sglrReferenceContext.Texture.prototype.isImmutable = function() { return this.m_immutable; };
+
+ /**
+ * @param {number} baseLevel
+ */
+ sglrReferenceContext.Texture.prototype.setBaseLevel = function(baseLevel) { this.m_baseLevel = baseLevel; };
+
+ /**
+ * @param {number} maxLevel
+ */
+ sglrReferenceContext.Texture.prototype.setMaxLevel = function(maxLevel) { this.m_maxLevel = maxLevel; };
+
+ /**
+ */
+ sglrReferenceContext.Texture.prototype.setImmutable = function() { this.m_immutable = true; };
+
+ /**
+ * @return {tcuTexture.Sampler}
+ */
+ sglrReferenceContext.Texture.prototype.getSampler = function() { return this.m_sampler; };
+
+ /**
+ * @constructor
+ */
+ sglrReferenceContext.TextureLevelArray = function() {
+ /** @type {Array<ArrayBuffer>} */ this.m_data = [];
+ /** @type {Array<tcuTexture.PixelBufferAccess>} */ this.m_access = [];
+ };
+
+ /**
+ * @param {number} level
+ * @return {boolean}
+ */
+ sglrReferenceContext.TextureLevelArray.prototype.hasLevel = function(level) { return this.m_data[level] != null; };
+
+ /**
+ * @param {number} level
+ * @return {tcuTexture.PixelBufferAccess}
+ * @throws {Error}
+ */
+ sglrReferenceContext.TextureLevelArray.prototype.getLevel = function(level) {
+ if (!this.hasLevel(level))
+ throw new Error('Level: ' + level + ' is not defined.');
+
+ return this.m_access[level];
+ };
+
+ /**
+ * @return {Array<tcuTexture.PixelBufferAccess>}
+ */
+ sglrReferenceContext.TextureLevelArray.prototype.getLevels = function() { return this.m_access; };
+
+ /**
+ * @param {number} level
+ * @param {tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ */
+ sglrReferenceContext.TextureLevelArray.prototype.allocLevel = function(level, format, width, height, depth) {
+ /** @type {number} */ var dataSize = format.getPixelSize() * width * height * depth;
+ if (this.hasLevel(level))
+ this.clearLevel(level);
+
+ this.m_data[level] = new ArrayBuffer(dataSize);
+ this.m_access[level] = new tcuTexture.PixelBufferAccess({
+ format: format,
+ width: width,
+ height: height,
+ depth: depth,
+ data: this.m_data[level]});
+ };
+
+ /**
+ * @param {number} level
+ */
+ sglrReferenceContext.TextureLevelArray.prototype.clearLevel = function(level) {
+ delete this.m_data[level];
+ delete this.m_access[level];
+ };
+
+ /**
+ */
+ sglrReferenceContext.TextureLevelArray.prototype.clear = function() {
+ for (var key in this.m_data)
+ delete this.m_data[key];
+
+ for (var key in this.m_access)
+ delete this.m_access[key];
+ };
+
+ /**
+ * @constructor
+ * @extends {sglrReferenceContext.Texture}
+ */
+ sglrReferenceContext.Texture2D = function() {
+ sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_2D);
+ /** @type {tcuTexture.Texture2DView} */ this.m_view = new tcuTexture.Texture2DView(0, null);
+ /** @type {sglrReferenceContext.TextureLevelArray} */ this.m_levels = new sglrReferenceContext.TextureLevelArray();
+ };
+
+ /**
+ */
+ sglrReferenceContext.Texture2D.prototype = Object.create(sglrReferenceContext.Texture.prototype);
+ sglrReferenceContext.Texture2D.prototype.constructor = sglrReferenceContext.Texture2D;
+
+ sglrReferenceContext.Texture2D.prototype.clearLevels = function() { this.m_levels.clear(); };
+
+ /**
+ * @param {number} level
+ * @return {boolean}
+ */
+ sglrReferenceContext.Texture2D.prototype.hasLevel = function(level) { return this.m_levels.hasLevel(level); };
+
+ /**
+ * @param {number} level
+ * @return {tcuTexture.PixelBufferAccess}
+ */
+ sglrReferenceContext.Texture2D.prototype.getLevel = function(level) { return this.m_levels.getLevel(level); };
+
+ /**
+ * @param {number} level
+ * @param {?tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.Texture2D.prototype.allocLevel = function(level, format, width, height) { this.m_levels.allocLevel(level, format, width, height, 1); };
+
+ /**
+ * @return {boolean}
+ */
+ sglrReferenceContext.Texture2D.prototype.isComplete = function() {
+ /** @type {number} */ var baseLevel = this.getBaseLevel();
+
+ if (this.hasLevel(baseLevel)) {
+ /** @type {tcuTexture.PixelBufferAccess} */ var level0 = this.getLevel(baseLevel);
+ /** @type {boolean} */ var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+
+ if (mipmap) {
+ /** @type {tcuTexture.TextureFormat} */ var format = level0.getFormat();
+ /** @type {number} */ var w = level0.getWidth();
+ /** @type {number} */ var h = level0.getHeight();
+ /** @type {number} */ var numLevels = Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(w, h));
+
+ for (var levelNdx = 1; levelNdx < numLevels; levelNdx++) {
+ if (this.hasLevel(baseLevel + levelNdx)) {
+ /** @type {tcuTexture.PixelBufferAccess} */ var level = this.getLevel(baseLevel + levelNdx);
+ /** @type {number} */ var expectedW = sglrReferenceContext.getMipLevelSize(w, levelNdx);
+ /** @type {number} */ var expectedH = sglrReferenceContext.getMipLevelSize(h, levelNdx);
+
+ if (level.getWidth() != expectedW ||
+ level.getHeight() != expectedH ||
+ !level.getFormat().isEqual(format))
+ return false;
+ } else
+ return false;
+ }
+ }
+
+ return true;
+ } else
+ return false;
+ };
+
+ /**
+ */
+ sglrReferenceContext.Texture2D.prototype.updateView = function() {
+ /** @type {number} */ var baseLevel = this.getBaseLevel();
+
+ if (this.hasLevel(baseLevel) && !this.getLevel(baseLevel).isEmpty()) {
+ // Update number of levels in mipmap pyramid.
+ /** @type {number} */ var width = this.getLevel(baseLevel).getWidth();
+ /** @type {number} */ var height = this.getLevel(baseLevel).getHeight();
+ /** @type {boolean} */ var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+ /** @type {number} */ var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1;
+
+ this.m_view = new tcuTexture.Texture2DView(numLevels, this.m_levels.getLevels().slice(baseLevel));
+ } else
+ this.m_view = new tcuTexture.Texture2DView(0, null);
+ };
+
+ /**
+ * @param {Array<number>} pos
+ * @param {number=} lod
+ * @return {Array<number>}
+ */
+ sglrReferenceContext.Texture2D.prototype.sample = function(pos, lod) {
+ return this.m_view.sample(this.getSampler(), pos, lod);
+ };
+
+ /**
+ * @param {Array<Array<number>>} packetTexcoords 4 vec2 coordinates
+ * @param {number} lodBias_
+ * @return {Array<Array<number>>} 4 vec4 samples
+ */
+ sglrReferenceContext.Texture2D.prototype.sample4 = function(packetTexcoords, lodBias_) {
+ /** @type {number} */ var lodBias = lodBias_ || 0;
+ /** @type {number} */ var texWidth = this.m_view.getWidth();
+ /** @type {number} */ var texHeight = this.m_view.getHeight();
+ /** @type {Array<Array<number>>}*/ var output = [];
+
+ /** @type {Array<number>}*/ var dFdx0 = deMath.subtract(packetTexcoords[1], packetTexcoords[0]);
+ /** @type {Array<number>}*/ var dFdx1 = deMath.subtract(packetTexcoords[3], packetTexcoords[2]);
+ /** @type {Array<number>}*/ var dFdy0 = deMath.subtract(packetTexcoords[2], packetTexcoords[0]);
+ /** @type {Array<number>}*/ var dFdy1 = deMath.subtract(packetTexcoords[3], packetTexcoords[1]);
+
+ for (var fragNdx = 0; fragNdx < 4; ++fragNdx) {
+ /** @type {Array<number>}*/var dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
+ /** @type {Array<number>}*/var dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
+
+ /** @type {number} */ var mu = Math.max(Math.abs(dFdx[0]), Math.abs(dFdy[0]));
+ /** @type {number} */ var mv = Math.max(Math.abs(dFdx[1]), Math.abs(dFdy[1]));
+ /** @type {number} */ var p = Math.max(mu * texWidth, mv * texHeight);
+
+ /** @type {number} */ var lod = Math.log2(p) + lodBias;
+
+ output.push(this.sample([packetTexcoords[fragNdx][0], packetTexcoords[fragNdx][1]], lod));
+ }
+
+ return output;
+ };
+
+ /**
+ * @constructor
+ * @extends {sglrReferenceContext.Texture}
+ */
+ sglrReferenceContext.TextureCube = function() {
+ sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_CUBE_MAP);
+ /** @type {tcuTexture.TextureCubeView} */ this.m_view = new tcuTexture.TextureCubeView(0, null);
+ /** @type {Array<sglrReferenceContext.TextureLevelArray>} */ this.m_levels = [];
+ for (var face in tcuTexture.CubeFace)
+ this.m_levels[tcuTexture.CubeFace[face]] = new sglrReferenceContext.TextureLevelArray();
+ };
+
+ /**
+ */
+ sglrReferenceContext.TextureCube.prototype = Object.create(sglrReferenceContext.Texture.prototype);
+ sglrReferenceContext.TextureCube.prototype.constructor = sglrReferenceContext.Texture2D;
+
+ sglrReferenceContext.TextureCube.prototype.clearLevels = function() {
+ for (var face in tcuTexture.CubeFace)
+ this.m_levels[tcuTexture.CubeFace[face]].clear();
+ };
+
+ /**
+ * @param {number} level
+ * @param {tcuTexture.CubeFace} face
+ * @return {boolean}
+ */
+ sglrReferenceContext.TextureCube.prototype.hasFace = function(level, face) { return this.m_levels[face].hasLevel(level); };
+
+ /**
+ * @param {number} level
+ * @param {tcuTexture.CubeFace} face
+ * @return {tcuTexture.PixelBufferAccess}
+ */
+ sglrReferenceContext.TextureCube.prototype.getFace = function(level, face) { return this.m_levels[face].getLevel(level); };
+
+ /**
+ * @param {number} level
+ * @param {tcuTexture.CubeFace} face
+ * @param {?tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.TextureCube.prototype.allocLevel = function(level, face, format, width, height) {
+ this.m_levels[face].allocLevel(level, format, width, height, 1);
+ };
+
+ sglrReferenceContext.TextureCube.prototype.isComplete = function() {
+ var baseLevel = this.getBaseLevel();
+
+ if (this.hasFace(baseLevel, tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X)) {
+ var level = this.getFace(baseLevel, tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X);
+ var width = level.getWidth();
+ var height = level.getHeight();
+ var format = level.getFormat();
+ var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+ var numLevels = mipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1;
+
+ if (width != height)
+ return false; // Non-square is not supported.
+
+ // \note Level 0 is always checked for consistency
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ var levelW = sglrReferenceContext.getMipLevelSize(width, levelNdx);
+ var levelH = sglrReferenceContext.getMipLevelSize(height, levelNdx);
+
+ for (var face in tcuTexture.CubeFace) {
+ if (this.hasFace(baseLevel + levelNdx, tcuTexture.CubeFace[face])) {
+ level = this.getFace(baseLevel + levelNdx, tcuTexture.CubeFace[face]);
+
+ if (level.getWidth() != levelW ||
+ level.getHeight() != levelH ||
+ !level.getFormat().isEqual(format))
+ return false;
+ } else
+ return false;
+ }
+ }
+
+ return true;
+ } else
+ return false;
+ };
+
+ sglrReferenceContext.TextureCube.prototype.updateView = function() {
+
+ var baseLevel = this.getBaseLevel();
+ var faces = [];
+
+ if (this.isComplete()) {
+ var size = this.getFace(baseLevel, tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X).getWidth();
+ var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+ var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels1D(size)) : 1;
+
+ for (var face in tcuTexture.CubeFace)
+ faces[tcuTexture.CubeFace[face]] = this.m_levels[tcuTexture.CubeFace[face]].getLevels().slice(baseLevel);
+
+ this.m_view = new tcuTexture.TextureCubeView(numLevels, faces);
+ } else
+ this.m_view = new tcuTexture.TextureCubeView(0, null);
+ };
+
+ /**
+ * @param {Array<number>} pos
+ * @param {number=} lod
+ * @return {Array<number>}
+ */
+ sglrReferenceContext.TextureCube.prototype.sample = function(pos, lod) { return this.m_view.sample(this.getSampler(), pos, lod) };
+
+ /**
+ * @constructor
+ * @extends {sglrReferenceContext.Texture}
+ */
+ sglrReferenceContext.Texture2DArray = function() {
+ sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_2D_ARRAY);
+ /** @type {tcuTexture.Texture2DArrayView} */ this.m_view = new tcuTexture.Texture2DArrayView(0, null);
+ /** @type {sglrReferenceContext.TextureLevelArray} */ this.m_levels = new sglrReferenceContext.TextureLevelArray();
+ };
+
+ /**
+ */
+ sglrReferenceContext.Texture2DArray.prototype = Object.create(sglrReferenceContext.Texture.prototype);
+ sglrReferenceContext.Texture2DArray.prototype.constructor = sglrReferenceContext.Texture2DArray;
+
+ sglrReferenceContext.Texture2DArray.prototype.clearLevels = function() { this.m_levels.clear(); };
+
+ /**
+ * @param {number} level
+ * @return {boolean}
+ */
+ sglrReferenceContext.Texture2DArray.prototype.hasLevel = function(level) { return this.m_levels.hasLevel(level); };
+
+ /**
+ * @param {number} level
+ * @return {tcuTexture.PixelBufferAccess}
+ */
+ sglrReferenceContext.Texture2DArray.prototype.getLevel = function(level) { return this.m_levels.getLevel(level); };
+
+ /**
+ * @param {number} level
+ * @param {?tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLayers
+ */
+ sglrReferenceContext.Texture2DArray.prototype.allocLevel = function(level, format, width, height, numLayers) {
+ this.m_levels.allocLevel(level, format, width, height, numLayers);
+ };
+
+ /**
+ * @return {boolean}
+ */
+ sglrReferenceContext.Texture2DArray.prototype.isComplete = function() {
+ /** @type {number} */ var baseLevel = this.getBaseLevel();
+
+ if (this.hasLevel(baseLevel)) {
+ /** @type {tcuTexture.PixelBufferAccess} */ var level0 = this.getLevel(baseLevel);
+ /** @type {boolean} */ var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+
+ if (mipmap) {
+ /** @type {tcuTexture.TextureFormat} */ var format = level0.getFormat();
+ /** @type {number} */ var w = level0.getWidth();
+ /** @type {number} */ var h = level0.getHeight();
+ /** @type {number} */ var numLayers = level0.getDepth();
+ /** @type {number} */ var numLevels = Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(w, h));
+
+ for (var levelNdx = 1; levelNdx < numLevels; levelNdx++) {
+ if (this.hasLevel(baseLevel + levelNdx)) {
+ /** @type {tcuTexture.PixelBufferAccess} */ var level = this.getLevel(baseLevel + levelNdx);
+ /** @type {number} */ var expectedW = sglrReferenceContext.getMipLevelSize(w, levelNdx);
+ /** @type {number} */ var expectedH = sglrReferenceContext.getMipLevelSize(h, levelNdx);
+
+ if (level.getWidth() != expectedW ||
+ level.getHeight() != expectedH ||
+ level.getDepth() != numLayers ||
+ !level.getFormat().isEqual(format))
+ return false;
+ } else
+ return false;
+ }
+ }
+
+ return true;
+ } else
+ return false;
+ };
+
+ /**
+ */
+ sglrReferenceContext.Texture2DArray.prototype.updateView = function() {
+ /** @type {number} */ var baseLevel = this.getBaseLevel();
+
+ if (this.hasLevel(baseLevel) && !this.getLevel(baseLevel).isEmpty()) {
+ // Update number of levels in mipmap pyramid.
+ /** @type {number} */ var width = this.getLevel(baseLevel).getWidth();
+ /** @type {number} */ var height = this.getLevel(baseLevel).getHeight();
+ /** @type {boolean} */ var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+ /** @type {number} */ var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1;
+
+ this.m_view = new tcuTexture.Texture2DArrayView(numLevels, this.m_levels.getLevels().slice(baseLevel));
+ } else
+ this.m_view = new tcuTexture.Texture2DArrayView(0, null);
+ };
+
+ /**
+ * @param {Array<number>} pos
+ * @param {number=} lod
+ * @return {Array<number>}
+ */
+ sglrReferenceContext.Texture2DArray.prototype.sample = function(pos, lod) {
+ return this.m_view.sample(this.getSampler(), pos, lod);
+ };
+
+ /**
+ * @constructor
+ * @extends {sglrReferenceContext.Texture}
+ */
+ sglrReferenceContext.Texture3D = function() {
+ sglrReferenceContext.Texture.call(this, sglrReferenceContext.TextureType.TYPE_2D_ARRAY);
+ /** @type {tcuTexture.Texture3DView} */ this.m_view = new tcuTexture.Texture3DView(0, null);
+ /** @type {sglrReferenceContext.TextureLevelArray} */ this.m_levels = new sglrReferenceContext.TextureLevelArray();
+ };
+
+ /**
+ */
+ sglrReferenceContext.Texture3D.prototype = Object.create(sglrReferenceContext.Texture.prototype);
+ sglrReferenceContext.Texture3D.prototype.constructor = sglrReferenceContext.Texture3D;
+
+ sglrReferenceContext.Texture3D.prototype.clearLevels = function() { this.m_levels.clear(); };
+
+ /**
+ * @param {number} level
+ * @return {boolean}
+ */
+ sglrReferenceContext.Texture3D.prototype.hasLevel = function(level) { return this.m_levels.hasLevel(level); };
+
+ /**
+ * @param {number} level
+ * @return {tcuTexture.PixelBufferAccess}
+ */
+ sglrReferenceContext.Texture3D.prototype.getLevel = function(level) { return this.m_levels.getLevel(level); };
+
+ /**
+ * @param {number} level
+ * @param {?tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ */
+ sglrReferenceContext.Texture3D.prototype.allocLevel = function(level, format, width, height, depth) {
+ this.m_levels.allocLevel(level, format, width, height, depth);
+ };
+
+ /**
+ * @return {boolean}
+ */
+ sglrReferenceContext.Texture3D.prototype.isComplete = function() {
+ /** @type {number} */ var baseLevel = this.getBaseLevel();
+
+ if (this.hasLevel(baseLevel)) {
+ /** @type {tcuTexture.PixelBufferAccess} */ var level0 = this.getLevel(baseLevel);
+ /** @type {boolean} */ var mipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+
+ if (mipmap) {
+ /** @type {tcuTexture.TextureFormat} */ var format = level0.getFormat();
+ /** @type {number} */ var w = level0.getWidth();
+ /** @type {number} */ var h = level0.getHeight();
+ /** @type {number} */ var d = level0.getDepth();
+ /** @type {number} */ var numLevels = Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels3D(w, h, d));
+
+ for (var levelNdx = 1; levelNdx < numLevels; levelNdx++) {
+ if (this.hasLevel(baseLevel + levelNdx)) {
+ /** @type {tcuTexture.PixelBufferAccess} */ var level = this.getLevel(baseLevel + levelNdx);
+ /** @type {number} */ var expectedW = sglrReferenceContext.getMipLevelSize(w, levelNdx);
+ /** @type {number} */ var expectedH = sglrReferenceContext.getMipLevelSize(h, levelNdx);
+ /** @type {number} */ var expectedD = sglrReferenceContext.getMipLevelSize(d, levelNdx);
+
+ if (level.getWidth() != expectedW ||
+ level.getHeight() != expectedH ||
+ level.getDepth() != expectedD ||
+ !level.getFormat().isEqual(format))
+ return false;
+ } else
+ return false;
+ }
+ }
+
+ return true;
+ } else
+ return false;
+ };
+
+ /**
+ */
+ sglrReferenceContext.Texture3D.prototype.updateView = function() {
+ /** @type {number} */ var baseLevel = this.getBaseLevel();
+
+ if (this.hasLevel(baseLevel) && !this.getLevel(baseLevel).isEmpty()) {
+ // Update number of levels in mipmap pyramid.
+ /** @type {number} */ var width = this.getLevel(baseLevel).getWidth();
+ /** @type {number} */ var height = this.getLevel(baseLevel).getHeight();
+ /** @type {boolean} */ var isMipmap = sglrReferenceContext.isMipmapFilter(this.getSampler().minFilter);
+ /** @type {number} */ var numLevels = isMipmap ? Math.min(this.getMaxLevel() - baseLevel + 1, sglrReferenceContext.getNumMipLevels2D(width, height)) : 1;
+
+ this.m_view = new tcuTexture.Texture3DView(numLevels, this.m_levels.getLevels().slice(baseLevel));
+ } else
+ this.m_view = new tcuTexture.Texture3DView(0, null);
+ };
+
+ /**
+ * @param {Array<number>} pos
+ * @param {number=} lod
+ * @return {Array<number>}
+ */
+ sglrReferenceContext.Texture3D.prototype.sample = function(pos, lod) { return this.m_view.sample(this.getSampler(), pos, lod) };
+
+ /**
+ * A container object for storing one of texture types;
+ * @constructor
+ */
+ sglrReferenceContext.TextureContainer = function() {
+ /** @type {sglrReferenceContext.Texture2D | sglrReferenceContext.TextureCube|sglrReferenceContext.Texture2DArray|sglrReferenceContext.Texture3D} */
+ this.texture = null;
+ /** @type {?sglrReferenceContext.TextureType} */ this.textureType = null;
+ };
+
+ /**
+ * @return {?sglrReferenceContext.TextureType}
+ */
+ sglrReferenceContext.TextureContainer.prototype.getType = function() { return this.textureType; };
+
+ /**
+ * @param {number} target
+ * @throws {Error}
+ */
+ sglrReferenceContext.TextureContainer.prototype.init = function(target) {
+ switch (target) {
+ case gl.TEXTURE_2D:
+ this.texture = new sglrReferenceContext.Texture2D();
+ this.textureType = sglrReferenceContext.TextureType.TYPE_2D;
+ break;
+ case gl.TEXTURE_CUBE_MAP:
+ this.texture = new sglrReferenceContext.TextureCube();
+ this.textureType = sglrReferenceContext.TextureType.TYPE_CUBE_MAP;
+ break;
+ case gl.TEXTURE_2D_ARRAY:
+ this.texture = new sglrReferenceContext.Texture2DArray();
+ this.textureType = sglrReferenceContext.TextureType.TYPE_2D_ARRAY;
+ break;
+ case gl.TEXTURE_3D:
+ this.texture = new sglrReferenceContext.Texture3D();
+ this.textureType = sglrReferenceContext.TextureType.TYPE_3D;
+ break;
+ /* TODO: Implement other types */
+ // case gl.TEXTURE_CUBE_MAP_ARRAY:
+ // this.textureType = sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY;
+ // break;
+ default: throw new Error('Unrecognized target: ' + target);
+ }
+ };
+
+ /**
+ * @enum
+ */
+ sglrReferenceContext.AttachmentPoint = {
+ ATTACHMENTPOINT_COLOR0: 0,
+ ATTACHMENTPOINT_DEPTH: 1,
+ ATTACHMENTPOINT_STENCIL: 2
+ };
+
+ /**
+ * @param {number} attachment
+ * @return {sglrReferenceContext.AttachmentPoint}
+ * @throws {Error}
+ */
+ sglrReferenceContext.mapGLAttachmentPoint = function(attachment) {
+ switch (attachment) {
+ case gl.COLOR_ATTACHMENT0: return sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0;
+ case gl.DEPTH_ATTACHMENT: return sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH;
+ case gl.STENCIL_ATTACHMENT: return sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL;
+ default: throw new Error('Wrong attachment point:' + attachment);
+ }
+ };
+
+ /**
+ * @enum
+ */
+ sglrReferenceContext.AttachmentType = {
+ ATTACHMENTTYPE_RENDERBUFFER: 0,
+ ATTACHMENTTYPE_TEXTURE: 1
+ };
+
+ /**
+ * @enum
+ */
+ sglrReferenceContext.TexTarget = {
+ TEXTARGET_2D: 0,
+ TEXTARGET_CUBE_MAP_POSITIVE_X: 1,
+ TEXTARGET_CUBE_MAP_POSITIVE_Y: 2,
+ TEXTARGET_CUBE_MAP_POSITIVE_Z: 3,
+ TEXTARGET_CUBE_MAP_NEGATIVE_X: 4,
+ TEXTARGET_CUBE_MAP_NEGATIVE_Y: 5,
+ TEXTARGET_CUBE_MAP_NEGATIVE_Z: 6,
+ TEXTARGET_2D_ARRAY: 7,
+ TEXTARGET_3D: 8,
+ TEXTARGET_CUBE_MAP_ARRAY: 9
+ };
+
+ /**
+ * @param {?sglrReferenceContext.TexTarget} target
+ * @return {tcuTexture.CubeFace}
+ */
+ sglrReferenceContext.texTargetToFace = function(target) {
+ switch (target) {
+ case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_X: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X;
+ case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_X;
+ case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Y: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y;
+ case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Y: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y;
+ case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z: return tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z;
+ case sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Z: return tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z;
+ default: throw new Error('Invalid target ' + target);
+ }
+ };
+
+ /**
+ * @param {sglrReferenceContext.TexTarget} target
+ * @return {sglrReferenceContext.TexTarget}
+ * @throws {Error}
+ */
+ sglrReferenceContext.mapGLFboTexTarget = function(target) {
+ switch (target) {
+ case gl.TEXTURE_2D: return sglrReferenceContext.TexTarget.TEXTARGET_2D;
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_X: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X;
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Y: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Y;
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Z: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_Z;
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_X: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_X;
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Y;
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z: return sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z;
+ default: throw new Error('Wrong texture target:' + target);
+ }
+ };
+
+ /**
+ * @constructor
+ */
+ sglrReferenceContext.Attachment = function() {
+ /** @type {?sglrReferenceContext.AttachmentType} */ this.type = null;
+ /** @type {sglrReferenceContext.TextureContainer|sglrReferenceContext.Renderbuffer} */ this.object = null; // TODO: fix reserved word
+ /** @type {?sglrReferenceContext.TexTarget} */ this.texTarget = null;
+ /** @type {number} */ this.level = 0;
+ /** @type {number} */ this.layer = 0;
+ };
+
+ /**
+ * @constructor
+ */
+ sglrReferenceContext.Framebuffer = function() {
+ /** @type {Array<sglrReferenceContext.Attachment>} */ this.m_attachments = [];
+ for (var key in sglrReferenceContext.AttachmentPoint)
+ this.m_attachments[sglrReferenceContext.AttachmentPoint[key]] = new sglrReferenceContext.Attachment();
+ };
+
+ /**
+ * @param {sglrReferenceContext.AttachmentPoint} point
+ * @return {sglrReferenceContext.Attachment}
+ */
+ sglrReferenceContext.Framebuffer.prototype.getAttachment = function(point) { return this.m_attachments[point]; };
+
+ /**
+ * @param {sglrReferenceContext.AttachmentPoint} point
+ * @param {sglrReferenceContext.Attachment} attachment
+ */
+ sglrReferenceContext.Framebuffer.prototype.setAttachment = function(point, attachment) { this.m_attachments[point] = attachment; };
+
+ // /**
+ // * @enum
+ // */
+ // var Format = {
+ // FORMAT_DEPTH_COMPONENT16: 0,
+ // FORMAT_RGBA4: 1,
+ // FORMAT_RGB5_A1: 2,
+ // FORMAT_RGB565: 3,
+ // FORMAT_STENCIL_INDEX8: 4
+ // };
+
+ /**
+ * @constructor
+ */
+ sglrReferenceContext.Renderbuffer = function() {
+ /** @type {tcuTexture.TextureLevel} */ this.m_data;
+ };
+
+ /**
+ * @param {tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.Renderbuffer.prototype.setStorage = function(format, width, height) {
+ this.m_data = new tcuTexture.TextureLevel(format, width, height);
+ };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.Renderbuffer.prototype.getWidth = function() { return this.m_data.getWidth(); };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.Renderbuffer.prototype.getHeight = function() { return this.m_data.getHeight(); };
+
+ /**
+ * @return {?tcuTexture.TextureFormat}
+ */
+ sglrReferenceContext.Renderbuffer.prototype.getFormat = function() { return this.m_data.getFormat(); };
+
+ /**
+ * @return {tcuTexture.PixelBufferAccess}
+ */
+ sglrReferenceContext.Renderbuffer.prototype.getAccess = function() { return this.m_data.getAccess(); };
+
+ /**
+ * @constructor
+ * @param {number} maxVertexAttribs
+ */
+ sglrReferenceContext.VertexArray = function(maxVertexAttribs) {
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_elementArrayBufferBinding = null;
+
+ /** @type {Array<sglrReferenceContext.VertexArray.VertexAttribArray>} */this.m_arrays = [];
+ for (var i = 0; i < maxVertexAttribs; i++)
+ this.m_arrays.push(new sglrReferenceContext.VertexArray.VertexAttribArray());
+ };
+
+ /** @constructor */
+ sglrReferenceContext.VertexArray.VertexAttribArray = function() {
+ this.enabled = false;
+ this.size = 4;
+ this.stride = 0;
+ this.type = gl.FLOAT;
+
+ this.normalized = false;
+ this.integer = false;
+ this.divisor = 0;
+ this.offset = 0;
+ this.bufferBinding = null;
+ };
+
+ /**
+ * @constructor
+ */
+ sglrReferenceContext.DataBuffer = function() {
+ /** @type {?ArrayBuffer} */ this.m_data = null;
+ };
+
+ /**
+ * @param {number} size
+ */
+ sglrReferenceContext.DataBuffer.prototype.setStorage = function(size) {this.m_data = new ArrayBuffer(size); };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.DataBuffer.prototype.getSize = function() {
+ /** @type {number} */ var size = 0;
+ if (this.m_data)
+ size = this.m_data.byteLength;
+ return size;
+ };
+
+ /**
+ * @return {?ArrayBuffer}
+ */
+ sglrReferenceContext.DataBuffer.prototype.getData = function() { return this.m_data; };
+
+ /**
+ * @param {ArrayBuffer|goog.NumberArray} data
+ */
+ sglrReferenceContext.DataBuffer.prototype.setData = function(data) {
+ /** @type {ArrayBuffer} */ var buffer;
+ /** @type {number} */ var offset = 0;
+ /** @type {number} */ var byteLength = data.byteLength;
+ if (data instanceof ArrayBuffer)
+ buffer = data;
+ else {
+ buffer = data.buffer;
+ offset = data.byteOffset;
+ }
+
+ if (!buffer)
+ throw new Error('Invalid buffer');
+
+ this.m_data = buffer.slice(offset, offset + byteLength);
+ };
+
+ /**
+ * @param {number} offset
+ * @param {goog.NumberArray} data
+ */
+ sglrReferenceContext.DataBuffer.prototype.setSubData = function(offset, data) {
+ /** @type {ArrayBuffer} */ var buffer;
+ /** @type {number} */ var srcOffset = 0;
+ /** @type {number} */ var byteLength = data.byteLength;
+ if (data instanceof ArrayBuffer)
+ buffer = data;
+ else {
+ buffer = data.buffer;
+ srcOffset = data.byteOffset;
+ }
+
+ if (!buffer)
+ throw new Error('Invalid buffer');
+
+ /** @type {goog.NumberArray} */ var src = new Uint8Array(buffer, srcOffset, byteLength);
+ /** @type {goog.NumberArray} */ var dst = new Uint8Array(this.m_data, offset, byteLength);
+ dst.set(src);
+ };
+
+ // /**
+ // * @constructor
+ // */
+ // var ObjectManager = function() {
+ // this.m_objects = {};
+ // };
+
+ // ObjectManager.prototype.insert = function(obj) {
+ // var name = obj.getName();
+ // if (!name)
+ // throw new Error("Cannot insert unnamed object");
+ // this.m_objects[name] = obj;
+ // };
+
+ // ObjectManager.prototype.find = function(name) { return this.m_objects[name]; };
+
+ // ObjectManager.prototype.acquireReference = function(obj) {
+ // if (this.find(obj.getName()) !== obj)
+ // throw new Error("Object is not in the object manager");
+ // obj.incRefCount();
+ // };
+
+ // ObjectManager.prototype.releaseReference = function(obj) {
+ // if (this.find(obj.getName()) !== obj)
+ // throw new Error("Object is not in the object manager");
+
+ // obj.decRefCount();
+
+ // if (obj.getRefCount() == 0)
+ // delete this.m_objects[obj.getName()];
+ // };
+
+ // ObjectManager.prototype.getAll = function() { return this.m_objects; };
+
+ /**
+ * @constructor
+ */
+ sglrReferenceContext.TextureUnit = function() {
+ /** @type {?sglrReferenceContext.TextureContainer} */ this.tex2DBinding = null;
+ /** @type {?sglrReferenceContext.TextureContainer} */ this.texCubeBinding = null;
+ /** @type {?sglrReferenceContext.TextureContainer} */ this.tex2DArrayBinding = null;
+ /** @type {?sglrReferenceContext.TextureContainer} */ this.tex3DBinding = null;
+ /** @type {?sglrReferenceContext.TextureContainer} */ this.texCubeArrayBinding = null;
+ };
+
+ /**
+ * @constructor
+ */
+ sglrReferenceContext.StencilState = function() {
+ /** @type {number} */ this.func = gl.ALWAYS;
+ /** @type {number} */ this.ref = 0;
+ /** @type {number} */ this.opMask = ~0;
+ /** @type {number} */ this.opStencilFail = gl.KEEP;
+ /** @type {number} */ this.opDepthFail = gl.KEEP;
+ /** @type {number} */ this.opDepthPass = gl.KEEP;
+ /** @type {number} */ this.writeMask = ~0;
+ };
+
+ /**
+ * @param {tcuPixelFormat.PixelFormat} pixelFmt
+ * @return {tcuTexture.TextureFormat}
+ * @throws {Error}
+ */
+ sglrReferenceContext.toTextureFormat = function(pixelFmt) {
+ if (pixelFmt.equals(8, 8, 8, 8))
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8);
+ else if (pixelFmt.equals(8, 8, 8, 0))
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8);
+ else if (pixelFmt.equals(4, 4, 4, 4))
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_4444);
+ else if (pixelFmt.equals(5, 5, 5, 1))
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_5551);
+ else if (pixelFmt.equals(5, 6, 5, 0))
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_SHORT_565);
+
+ throw new Error('Could not map pixel format:' + pixelFmt);
+ };
+
+ /**
+ * @param {number} depthBits
+ * @return {tcuTexture.TextureFormat}
+ * @throws {Error}
+ */
+ sglrReferenceContext.getDepthFormat = function(depthBits) {
+ switch (depthBits) {
+ case 8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNORM_INT8);
+ case 16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNORM_INT16);
+ case 24: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.UNSIGNED_INT_24_8);
+ case 32: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.D, tcuTexture.ChannelType.FLOAT);
+ default:
+ throw new Error("Can't map depth buffer format, bits: " + depthBits);
+ }
+ };
+
+ /**
+ * @param {number} stencilBits
+ * @return {tcuTexture.TextureFormat}
+ * @throws {Error}
+ */
+ sglrReferenceContext.getStencilFormat = function(stencilBits) {
+ switch (stencilBits) {
+ case 8: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT8);
+ case 16: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT16);
+ case 24: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT_24_8);
+ case 32: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.S, tcuTexture.ChannelType.UNSIGNED_INT32);
+ default:
+ throw new Error("Can't map stencil buffer format, bits: " + stencilBits);
+ }
+ };
+
+ /**
+ * @constructor
+ * @param {tcuPixelFormat.PixelFormat} colorBits
+ * @param {number} depthBits
+ * @param {number} stencilBits
+ * @param {number} width
+ * @param {number} height
+ * @param {number=} samples_
+ */
+ sglrReferenceContext.ReferenceContextBuffers = function(colorBits, depthBits, stencilBits, width, height, samples_) {
+ if (samples_ === undefined)
+ samples_ = 1;
+
+ /** @type {number} */ var samples = samples_;
+ /** @type {tcuTexture.TextureLevel} */ this.m_colorbuffer = new tcuTexture.TextureLevel(sglrReferenceContext.toTextureFormat(colorBits), samples, width, height);
+
+ if (depthBits > 0)
+ /** @type {tcuTexture.TextureLevel} */ this.m_depthbuffer = new tcuTexture.TextureLevel(sglrReferenceContext.getDepthFormat(depthBits), samples, width, height);
+
+ if (stencilBits > 0)
+ /** @type {tcuTexture.TextureLevel} */ this.m_stencilbuffer = new tcuTexture.TextureLevel(sglrReferenceContext.getStencilFormat(stencilBits), samples, width, height);
+ };
+
+ /**
+ * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContextBuffers.prototype.getColorbuffer = function() { return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromMultisampleAccess(this.m_colorbuffer.getAccess()); };
+
+ /**
+ * @return {?rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContextBuffers.prototype.getDepthbuffer = function() { return this.m_depthbuffer !== undefined ? rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromMultisampleAccess(this.m_depthbuffer.getAccess()) : null; };
+
+ /**
+ * @return {?rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContextBuffers.prototype.getStencilbuffer = function() { return this.m_stencilbuffer !== undefined ? rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromMultisampleAccess(this.m_stencilbuffer.getAccess()) : null; };
+
+ /**
+ * @param {sglrReferenceContext.ReferenceContextLimits} limits
+ * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} colorbuffer
+ * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} depthbuffer
+ * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} stencilbuffer
+ * @constructor
+ */
+ sglrReferenceContext.ReferenceContext = function(limits, colorbuffer, depthbuffer, stencilbuffer) {
+ /** @type {sglrReferenceContext.ReferenceContextLimits} */ this.m_limits = limits;
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ this.m_defaultColorbuffer = colorbuffer;
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ this.m_defaultDepthbuffer = depthbuffer;
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ this.m_defaultStencilbuffer = stencilbuffer;
+ /** @type {Array<number>} */ this.m_viewport = [0, 0, colorbuffer.raw().getHeight(), colorbuffer.raw().getDepth()];
+ /** @type {Array<sglrReferenceContext.TextureUnit>} */ this.m_textureUnits = [];
+ for (var i = 0; i < this.m_limits.maxTextureImageUnits; i++)
+ this.m_textureUnits.push(new sglrReferenceContext.TextureUnit());
+ /** @type {number} */ this.m_activeTexture = 0;
+ /** @type {number} */ this.m_lastError = gl.NO_ERROR;
+ // this.m_textures = new ObjectManager();
+ /** @type {number} */ this.m_pixelUnpackRowLength = 0;
+ /** @type {number} */ this.m_pixelUnpackSkipRows = 0;
+ /** @type {number} */ this.m_pixelUnpackSkipPixels = 0;
+ /** @type {number} */ this.m_pixelUnpackImageHeight = 0;
+ /** @type {number} */ this.m_pixelUnpackSkipImages = 0;
+ /** @type {number} */ this.m_pixelUnpackAlignment = 4;
+ /** @type {number} */ this.m_pixelPackAlignment = 4;
+ /** @type {Array<number>} */ this.m_clearColor = [0, 0, 0, 0];
+ /** @type {number} */ this.m_clearDepth = 1;
+ /** @type {number} */ this.m_clearStencil = 0;
+ /** @type {Array<number>} */ this.m_scissorBox = this.m_viewport;
+ /** @type {boolean} */ this.m_blendEnabled = false;
+ /** @type {boolean} */ this.m_scissorEnabled = false;
+ /** @type {boolean} */ this.m_depthTestEnabled = false;
+ /** @type {boolean} */ this.m_stencilTestEnabled = false;
+ /** @type {boolean} */ this.m_polygonOffsetFillEnabled = false;
+ /** @type {boolean} */ this.m_primitiveRestartFixedIndex = true; //always on
+ /** @type {boolean} */ this.m_primitiveRestartSettableIndex = true; //always on
+ /** @type {Array<sglrReferenceContext.StencilState>} */ this.m_stencil = [];
+ for (var type in rrDefs.FaceType)
+ this.m_stencil[rrDefs.FaceType[type]] = new sglrReferenceContext.StencilState();
+ /** @type {number} */ this.m_depthFunc = gl.LESS;
+ /** @type {number} */ this.m_depthRangeNear = 0;
+ /** @type {number} */ this.m_depthRangeFar = 1;
+ /** @type {number} */ this.m_polygonOffsetFactor = 0;
+ /** @type {number} */ this.m_polygonOffsetUnits = 0;
+ /** @type {number} */ this.m_blendModeRGB = gl.FUNC_ADD;
+ /** @type {number} */ this.m_blendModeAlpha = gl.FUNC_ADD;
+ /** @type {number} */ this.m_blendFactorSrcRGB = gl.ONE;
+ /** @type {number} */ this.m_blendFactorDstRGB = gl.ZERO;
+ /** @type {number} */ this.m_blendFactorSrcAlpha = gl.ONE;
+ /** @type {number} */ this.m_blendFactorDstAlpha = gl.ZERO;
+ /** @type {Array<number>} */ this.m_blendColor = [0, 0, 0, 0];
+ /** @type {boolean} */ this.m_sRGBUpdateEnabled = true;
+ /** @type {Array<boolean>} */ this.m_colorMask = [true, true, true, true];
+ /** @type {boolean} */ this.m_depthMask = true;
+ /** @type {sglrReferenceContext.VertexArray} */ this.m_defaultVAO = new sglrReferenceContext.VertexArray(this.m_limits.maxVertexAttribs);
+ /** @type {sglrReferenceContext.VertexArray} */ this.m_vertexArrayBinding = this.m_defaultVAO;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_arrayBufferBinding = null;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_copyReadBufferBinding = null;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_copyWriteBufferBinding = null;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_drawIndirectBufferBinding = null;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_pixelPackBufferBinding = null;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_pixelUnpackBufferBinding = null;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_transformFeedbackBufferBinding = null;
+ /** @type {sglrReferenceContext.DataBuffer} */ this.m_uniformBufferBinding = null;
+ /** @type {sglrReferenceContext.Framebuffer} */ this.m_readFramebufferBinding = null;
+ /** @type {sglrReferenceContext.Framebuffer} */ this.m_drawFramebufferBinding = null;
+ /** @type {sglrReferenceContext.Renderbuffer} */ this.m_renderbufferBinding = null;
+ /** @type {sglrShaderProgram.ShaderProgram} */ this.m_currentProgram = null;
+ /** @type {Array<rrGenericVector.GenericVec4>} */ this.m_currentAttribs = [];
+ for (var i = 0; i < this.m_limits.maxVertexAttribs; i++)
+ this.m_currentAttribs.push(new rrGenericVector.GenericVec4());
+ /** @type {number} */ this.m_lineWidth = 1;
+
+ /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTex2D = new sglrReferenceContext.TextureContainer();
+ this.m_emptyTex2D.init(gl.TEXTURE_2D);
+ this.m_emptyTex2D.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex2D.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex2D.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST;
+ this.m_emptyTex2D.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST;
+ this.m_emptyTex2D.texture.allocLevel(0, new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1);
+ this.m_emptyTex2D.texture.getLevel(0).setPixel([0, 0, 0, 1], 0, 0);
+ this.m_emptyTex2D.texture.updateView();
+
+ /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTexCube = new sglrReferenceContext.TextureContainer();
+ this.m_emptyTexCube.init(gl.TEXTURE_CUBE_MAP);
+ this.m_emptyTexCube.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTexCube.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTexCube.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST;
+ this.m_emptyTexCube.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST;
+
+ for (var face in tcuTexture.CubeFace) {
+ this.m_emptyTexCube.texture.allocLevel(0, tcuTexture.CubeFace[face],
+ new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1);
+ this.m_emptyTexCube.texture.getFace(0, tcuTexture.CubeFace[face]).setPixel([0, 0, 0, 1], 0, 0);
+ }
+ this.m_emptyTexCube.texture.updateView();
+
+ /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTex2DArray = new sglrReferenceContext.TextureContainer();
+ this.m_emptyTex2DArray.init(gl.TEXTURE_2D_ARRAY);
+ this.m_emptyTex2DArray.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex2DArray.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex2DArray.texture.getSampler().wrapR = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex2DArray.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST;
+ this.m_emptyTex2DArray.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST;
+ this.m_emptyTex2DArray.texture.allocLevel(0, new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1);
+ this.m_emptyTex2DArray.texture.getLevel(0).setPixel([0, 0, 0, 1], 0, 0);
+ this.m_emptyTex2DArray.texture.updateView();
+
+ /** @type {sglrReferenceContext.TextureContainer} */ this.m_emptyTex3D = new sglrReferenceContext.TextureContainer();
+ this.m_emptyTex3D.init(gl.TEXTURE_3D);
+ this.m_emptyTex3D.texture.getSampler().wrapS = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex3D.texture.getSampler().wrapT = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex3D.texture.getSampler().wrapR = tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ this.m_emptyTex3D.texture.getSampler().minFilter = tcuTexture.FilterMode.NEAREST;
+ this.m_emptyTex3D.texture.getSampler().magFilter = tcuTexture.FilterMode.NEAREST;
+ this.m_emptyTex3D.texture.allocLevel(0, new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8), 1, 1);
+ this.m_emptyTex3D.texture.getLevel(0).setPixel([0, 0, 0, 1], 0, 0);
+ this.m_emptyTex3D.texture.updateView();
+
+ /** @type {sglrReferenceContext.TextureType} */ this.m_type;
+
+ /** @type {boolean} */ this.m_immutable;
+
+ /** @type {tcuTexture.Sampler} */ this.m_sampler;
+ /** @type {number} */ this.m_baseLevel;
+ /** @type {number} */ this.m_maxLevel;
+ };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getWidth = function() { return this.m_defaultColorbuffer.raw().getHeight(); };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getHeight = function() { return this.m_defaultColorbuffer.raw().getDepth(); };
+
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.ReferenceContext.prototype.viewport = function(x, y, width, height) { this.m_viewport = [x, y, width, height]; };
+
+ /**
+ * @param {number} texture
+ */
+ sglrReferenceContext.ReferenceContext.prototype.activeTexture = function(texture) {
+ if (deMath.deInBounds32(texture, gl.TEXTURE0, gl.TEXTURE0 + this.m_textureUnits.length))
+ this.m_activeTexture = texture - gl.TEXTURE0;
+ else
+ this.setError(gl.INVALID_ENUM);
+ };
+
+ /**
+ * @param {number} error
+ */
+ sglrReferenceContext.ReferenceContext.prototype.setError = function(error) {
+ if (this.m_lastError == gl.NO_ERROR)
+ this.m_lastError = error;
+ };
+
+ /**
+ * @return {number} error
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getError = function() {
+ /** @type {number} */ var err = this.m_lastError;
+ this.m_lastError = gl.NO_ERROR;
+ return err;
+ };
+
+ /**
+ * @param {boolean} condition
+ * @param {number} error
+ */
+ sglrReferenceContext.ReferenceContext.prototype.conditionalSetError = function(condition, error) {
+ if (condition)
+ this.setError(error);
+ return condition;
+ };
+
+ /**
+ * @param {number} target
+ * @param {sglrReferenceContext.TextureContainer} texture
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.bindTexture = function(target, texture) {
+ /** @type {number} */ var unitNdx = this.m_activeTexture;
+
+ if (this.conditionalSetError((target != gl.TEXTURE_2D &&
+ target != gl.TEXTURE_CUBE_MAP &&
+ target != gl.TEXTURE_2D_ARRAY &&
+ target != gl.TEXTURE_3D), // &&
+ // target != gl.TEXTURE_CUBE_MAP_ARRAY),
+ gl.INVALID_ENUM))
+ return;
+
+ if (!texture) {
+ // Clear binding.
+ switch (target) {
+ case gl.TEXTURE_2D: this.setTex2DBinding(unitNdx, null); break;
+ case gl.TEXTURE_CUBE_MAP: this.setTexCubeBinding(unitNdx, null); break;
+ case gl.TEXTURE_2D_ARRAY: this.setTex2DArrayBinding(unitNdx, null); break;
+ case gl.TEXTURE_3D: this.setTex3DBinding(unitNdx, null); break;
+ default:
+ throw new Error('Unrecognized target: ' + target);
+ }
+ } else {
+ if (texture.textureType == null) {
+ texture.init(target);
+ } else {
+ // Validate type.
+ /** @type {sglrReferenceContext.TextureType} */ var expectedType;
+ switch (target) {
+ case gl.TEXTURE_2D: expectedType = sglrReferenceContext.TextureType.TYPE_2D; break;
+ case gl.TEXTURE_CUBE_MAP: expectedType = sglrReferenceContext.TextureType.TYPE_CUBE_MAP; break;
+ case gl.TEXTURE_2D_ARRAY: expectedType = sglrReferenceContext.TextureType.TYPE_2D_ARRAY; break;
+ case gl.TEXTURE_3D: expectedType = sglrReferenceContext.TextureType.TYPE_3D; break;
+ default: throw new Error('Unrecognized target: ' + target);
+ }
+ if (this.conditionalSetError((texture.textureType != expectedType), gl.INVALID_OPERATION))
+ return;
+ }
+ switch (target) {
+ case gl.TEXTURE_2D: this.setTex2DBinding(unitNdx, texture); break;
+ case gl.TEXTURE_CUBE_MAP: this.setTexCubeBinding(unitNdx, texture); break;
+ case gl.TEXTURE_2D_ARRAY: this.setTex2DArrayBinding(unitNdx, texture); break;
+ case gl.TEXTURE_3D: this.setTex3DBinding(unitNdx, texture); break;
+ default:
+ throw new Error('Unrecognized target: ' + target);
+ }
+ }
+ };
+
+ /**
+ * @param {number} unitNdx
+ * @param {?sglrReferenceContext.TextureContainer} texture
+ */
+ sglrReferenceContext.ReferenceContext.prototype.setTexCubeBinding = function(unitNdx, texture) {
+ if (this.m_textureUnits[unitNdx].texCubeBinding) {
+ this.m_textureUnits[unitNdx].texCubeBinding = null;
+ }
+
+ if (texture) {
+ this.m_textureUnits[unitNdx].texCubeBinding = texture;
+ }
+ };
+
+ /**
+ * @param {number} unitNdx
+ * @param {?sglrReferenceContext.TextureContainer} texture
+ */
+ sglrReferenceContext.ReferenceContext.prototype.setTex2DBinding = function(unitNdx, texture) {
+ if (this.m_textureUnits[unitNdx].tex2DBinding) {
+ // this.m_textures.releaseReference(this.m_textureUnits[unitNdx].tex2DBinding);
+ this.m_textureUnits[unitNdx].tex2DBinding = null;
+ }
+
+ if (texture) {
+ // this.m_textures.acquireReference(texture);
+ this.m_textureUnits[unitNdx].tex2DBinding = texture;
+ }
+ };
+
+ /**
+ * @param {number} unitNdx
+ * @param {?sglrReferenceContext.TextureContainer} texture
+ */
+ sglrReferenceContext.ReferenceContext.prototype.setTex2DArrayBinding = function(unitNdx, texture) {
+ if (this.m_textureUnits[unitNdx].tex2DArrayBinding) {
+ // this.m_textures.releaseReference(this.m_textureUnits[unitNdx].tex2DArrayBinding);
+ this.m_textureUnits[unitNdx].tex2DArrayBinding = null;
+ }
+
+ if (texture) {
+ // this.m_textures.acquireReference(texture);
+ this.m_textureUnits[unitNdx].tex2DArrayBinding = texture;
+ }
+ };
+
+ /**
+ * @param {number} unitNdx
+ * @param {?sglrReferenceContext.TextureContainer} texture
+ */
+ sglrReferenceContext.ReferenceContext.prototype.setTex3DBinding = function(unitNdx, texture) {
+ if (this.m_textureUnits[unitNdx].tex3DBinding) {
+ // this.m_textures.releaseReference(this.m_textureUnits[unitNdx].tex3DBinding);
+ this.m_textureUnits[unitNdx].tex3DBinding = null;
+ }
+
+ if (texture) {
+ // this.m_textures.acquireReference(texture);
+ this.m_textureUnits[unitNdx].tex3DBinding = texture;
+ }
+ };
+
+ /**
+ * @return {sglrReferenceContext.TextureContainer}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.createTexture = function() { return new sglrReferenceContext.TextureContainer(); };
+
+ /**
+ * @param {sglrReferenceContext.Texture} texture
+ */
+ sglrReferenceContext.ReferenceContext.prototype.deleteTexture = function(texture) { /*empty*/ };
+
+ /**
+ * @param {number} target
+ * @param {framework.opengl.simplereference.sglrReferenceContext.Framebuffer} fbo
+ */
+ sglrReferenceContext.ReferenceContext.prototype.bindFramebuffer = function(target, fbo) {
+ if (this.conditionalSetError((target != gl.FRAMEBUFFER &&
+ target != gl.DRAW_FRAMEBUFFER &&
+ target != gl.READ_FRAMEBUFFER), gl.INVALID_ENUM))
+ return;
+ for (var ndx = 0; ndx < 2; ndx++) {
+ /** @type {number} */ var bindingTarget = ndx ? gl.DRAW_FRAMEBUFFER : gl.READ_FRAMEBUFFER;
+
+ if (target != gl.FRAMEBUFFER && target != bindingTarget)
+ continue; // Doesn't match this target.
+
+ if (ndx)
+ this.m_drawFramebufferBinding = fbo;
+ else
+ this.m_readFramebufferBinding = fbo;
+ }
+ };
+
+ /**
+ * @return {sglrReferenceContext.Framebuffer}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.createFramebuffer = function() { return new sglrReferenceContext.Framebuffer(); };
+
+ /**
+ * @param {sglrReferenceContext.Framebuffer} fbo
+ */
+ sglrReferenceContext.ReferenceContext.prototype.deleteFramebuffer = function(fbo) { /*empty*/ };
+
+ /**
+ * @param {number} target
+ * @param {sglrReferenceContext.Renderbuffer} rbo
+ */
+ sglrReferenceContext.ReferenceContext.prototype.bindRenderbuffer = function(target, rbo) {
+ if (this.conditionalSetError(target != gl.RENDERBUFFER, gl.INVALID_ENUM))
+ return;
+
+ this.m_renderbufferBinding = rbo;
+ };
+
+ /**
+ * @return {sglrReferenceContext.Renderbuffer}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.createRenderbuffer = function() { return new sglrReferenceContext.Renderbuffer(); };
+
+ /**
+ * @param {sglrReferenceContext.Renderbuffer} rbo
+ */
+ sglrReferenceContext.ReferenceContext.prototype.deleteRenderbuffer = function(rbo) { /*empty*/ };
+
+ /**
+ * @param {number} pname
+ * @param {number} param
+ */
+ sglrReferenceContext.ReferenceContext.prototype.pixelStorei = function(pname, param) {
+ switch (pname) {
+ case gl.UNPACK_ALIGNMENT:
+ if (this.conditionalSetError((param != 1 && param != 2 && param != 4 && param != 8), gl.INVALID_VALUE)) return;
+ this.m_pixelUnpackAlignment = param;
+ break;
+
+ case gl.PACK_ALIGNMENT:
+ if (this.conditionalSetError((param != 1 && param != 2 && param != 4 && param != 8), gl.INVALID_VALUE)) return;
+ this.m_pixelPackAlignment = param;
+ break;
+
+ case gl.UNPACK_ROW_LENGTH:
+ if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return;
+ this.m_pixelUnpackRowLength = param;
+ break;
+
+ case gl.UNPACK_SKIP_ROWS:
+ if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return;
+ this.m_pixelUnpackSkipRows = param;
+ break;
+
+ case gl.UNPACK_SKIP_PIXELS:
+ if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return;
+ this.m_pixelUnpackSkipPixels = param;
+ break;
+
+ case gl.UNPACK_IMAGE_HEIGHT:
+ if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return;
+ this.m_pixelUnpackImageHeight = param;
+ break;
+
+ case gl.UNPACK_SKIP_IMAGES:
+ if (this.conditionalSetError(param < 0, gl.INVALID_VALUE)) return;
+ this.m_pixelUnpackSkipImages = param;
+ break;
+
+ default:
+ this.setError(gl.INVALID_ENUM);
+ }
+ };
+
+ /**
+ * @param {number} red
+ * @param {number} green
+ * @param {number} blue
+ * @param {number} alpha
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clearColor = function(red, green, blue, alpha) {
+ this.m_clearColor = [deMath.clamp(red, 0, 1),
+ deMath.clamp(green, 0, 1),
+ deMath.clamp(blue, 0, 1),
+ deMath.clamp(alpha, 0, 1)];
+ };
+
+ /**
+ * @param {number} depth
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clearDepthf = function(depth) {
+ this.m_clearDepth = deMath.clamp(depth, 0, 1);
+ };
+
+ /**
+ * @param {number} stencil
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clearStencil = function(stencil) {
+ this.m_clearStencil = stencil;
+ };
+
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.ReferenceContext.prototype.scissor = function(x, y, width, height) {
+ if (this.conditionalSetError(width < 0 || height < 0, gl.INVALID_VALUE))
+ return;
+ this.m_scissorBox = [x, y, width, height];
+ };
+
+ /**
+ * @param {number} cap
+ */
+ sglrReferenceContext.ReferenceContext.prototype.enable = function(cap) {
+ switch (cap) {
+ case gl.BLEND: this.m_blendEnabled = true; break;
+ case gl.SCISSOR_TEST: this.m_scissorEnabled = true; break;
+ case gl.DEPTH_TEST: this.m_depthTestEnabled = true; break;
+ case gl.STENCIL_TEST: this.m_stencilTestEnabled = true; break;
+ case gl.POLYGON_OFFSET_FILL: this.m_polygonOffsetFillEnabled = true; break;
+
+ case gl.DITHER:
+ // Not implemented - just ignored.
+ break;
+
+ default:
+ this.setError(gl.INVALID_ENUM);
+ break;
+ }
+ };
+
+ /**
+ * @param {number} cap
+ */
+ sglrReferenceContext.ReferenceContext.prototype.disable = function(cap) {
+ switch (cap) {
+ case gl.BLEND: this.m_blendEnabled = false; break;
+ case gl.SCISSOR_TEST: this.m_scissorEnabled = false; break;
+ case gl.DEPTH_TEST: this.m_depthTestEnabled = false; break;
+ case gl.STENCIL_TEST: this.m_stencilTestEnabled = false; break;
+ case gl.POLYGON_OFFSET_FILL: this.m_polygonOffsetFillEnabled = false; break;
+
+ case gl.DITHER:
+ // Not implemented - just ignored.
+ break;
+
+ default:
+ this.setError(gl.INVALID_ENUM);
+ break;
+ }
+ };
+
+ /**
+ * @param {number} func
+ * @param {number} ref
+ * @param {number} mask
+ */
+ sglrReferenceContext.ReferenceContext.prototype.stencilFunc = function(func, ref, mask) {
+ this.stencilFuncSeparate(gl.FRONT_AND_BACK, func, ref, mask);
+ };
+
+ /**
+ * @param {number} face
+ * @param {number} func
+ * @param {number} ref
+ * @param {number} mask
+ */
+ sglrReferenceContext.ReferenceContext.prototype.stencilFuncSeparate = function(face, func, ref, mask) {
+ /** @type {boolean} */ var setFront = face == gl.FRONT || face == gl.FRONT_AND_BACK;
+ /** @type {boolean} */ var setBack = face == gl.BACK || face == gl.FRONT_AND_BACK;
+
+ if (this.conditionalSetError(!sglrReferenceContext.isValidCompareFunc(func), gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(!setFront && !setBack, gl.INVALID_ENUM))
+ return;
+
+ for (var key in rrDefs.FaceType) {
+ /** @type {number} */ var type = rrDefs.FaceType[key];
+ if ((type == rrDefs.FaceType.FACETYPE_FRONT && setFront) ||
+ (type == rrDefs.FaceType.FACETYPE_BACK && setBack)) {
+ this.m_stencil[type].func = func;
+ this.m_stencil[type].ref = ref;
+ this.m_stencil[type].opMask = mask;
+ }
+ }
+ };
+
+ /**
+ * @param {number} func
+ * @return {boolean}
+ */
+ sglrReferenceContext.isValidCompareFunc = function(func) {
+ switch (func) {
+ case gl.NEVER:
+ case gl.LESS:
+ case gl.LEQUAL:
+ case gl.GREATER:
+ case gl.GEQUAL:
+ case gl.EQUAL:
+ case gl.NOTEQUAL:
+ case gl.ALWAYS:
+ return true;
+
+ default:
+ return false;
+ }
+ };
+
+ /**
+ * @param {number} op
+ * @return {boolean}
+ */
+ sglrReferenceContext.isValidStencilOp = function(op) {
+ switch (op) {
+ case gl.KEEP:
+ case gl.ZERO:
+ case gl.REPLACE:
+ case gl.INCR:
+ case gl.INCR_WRAP:
+ case gl.DECR:
+ case gl.DECR_WRAP:
+ case gl.INVERT:
+ return true;
+
+ default:
+ return false;
+ }
+ };
+
+ /**
+ * @param {number} sfail
+ * @param {number} dpfail
+ * @param {number} dppass
+ */
+ sglrReferenceContext.ReferenceContext.prototype.stencilOp = function(sfail, dpfail, dppass) {
+ this.stencilOpSeparate(gl.FRONT_AND_BACK, sfail, dpfail, dppass);
+ };
+
+ /**
+ * @param {number} face
+ * @param {number} sfail
+ * @param {number} dpfail
+ * @param {number} dppass
+ */
+ sglrReferenceContext.ReferenceContext.prototype.stencilOpSeparate = function(face, sfail, dpfail, dppass) {
+ /** @type {boolean} */ var setFront = face == gl.FRONT || face == gl.FRONT_AND_BACK;
+ /** @type {boolean} */ var setBack = face == gl.BACK || face == gl.FRONT_AND_BACK;
+
+ if (this.conditionalSetError((!sglrReferenceContext.isValidStencilOp(sfail) ||
+ !sglrReferenceContext.isValidStencilOp(dpfail) ||
+ !sglrReferenceContext.isValidStencilOp(dppass)),
+ gl.INVALID_ENUM))
+ return;
+
+ if (this.conditionalSetError(!setFront && !setBack, gl.INVALID_ENUM))
+ return;
+
+ for (var key in rrDefs.FaceType) {
+ /** @type {number} */ var type = rrDefs.FaceType[key];
+ if ((type == rrDefs.FaceType.FACETYPE_FRONT && setFront) ||
+ (type == rrDefs.FaceType.FACETYPE_BACK && setBack)) {
+ this.m_stencil[type].opStencilFail = sfail;
+ this.m_stencil[type].opDepthFail = dpfail;
+ this.m_stencil[type].opDepthPass = dppass;
+ }
+ }
+ };
+
+ /**
+ * @param {number} func
+ */
+ sglrReferenceContext.ReferenceContext.prototype.depthFunc = function(func) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidCompareFunc(func), gl.INVALID_ENUM))
+ return;
+ this.m_depthFunc = func;
+ };
+
+ /**
+ * @param {number} n
+ * @param {number} f
+ */
+ sglrReferenceContext.ReferenceContext.prototype.depthRange = function(n, f) {
+ this.m_depthRangeNear = deMath.clamp(n, 0, 1);
+ this.m_depthRangeFar = deMath.clamp(f, 0, 1);
+ };
+
+ /**
+ * @param {number} factor
+ * @param {number} units
+ */
+ sglrReferenceContext.ReferenceContext.prototype.polygonOffset = function(factor, units) {
+ this.m_polygonOffsetFactor = factor;
+ this.m_polygonOffsetUnits = units;
+ };
+
+ /**
+ * @param {number} mode
+ * @return {boolean}
+ */
+ sglrReferenceContext.isValidBlendEquation = function(mode) {
+ return mode == gl.FUNC_ADD ||
+ mode == gl.FUNC_SUBTRACT ||
+ mode == gl.FUNC_REVERSE_SUBTRACT ||
+ mode == gl.MIN ||
+ mode == gl.MAX;
+ };
+
+ /**
+ * @param {number} factor
+ * @return {boolean}
+ */
+ sglrReferenceContext.isValidBlendFactor = function(factor) {
+ switch (factor) {
+ case gl.ZERO:
+ case gl.ONE:
+ case gl.SRC_COLOR:
+ case gl.ONE_MINUS_SRC_COLOR:
+ case gl.DST_COLOR:
+ case gl.ONE_MINUS_DST_COLOR:
+ case gl.SRC_ALPHA:
+ case gl.ONE_MINUS_SRC_ALPHA:
+ case gl.DST_ALPHA:
+ case gl.ONE_MINUS_DST_ALPHA:
+ case gl.CONSTANT_COLOR:
+ case gl.ONE_MINUS_CONSTANT_COLOR:
+ case gl.CONSTANT_ALPHA:
+ case gl.ONE_MINUS_CONSTANT_ALPHA:
+ case gl.SRC_ALPHA_SATURATE:
+ return true;
+
+ default:
+ return false;
+ }
+ };
+
+ /**
+ * @param {number} mode
+ */
+ sglrReferenceContext.ReferenceContext.prototype.blendEquation = function(mode) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidBlendEquation(mode), gl.INVALID_ENUM))
+ return;
+ this.m_blendModeRGB = mode;
+ this.m_blendModeAlpha = mode;
+ };
+
+ /**
+ * @param {number} modeRGB
+ * @param {number} modeAlpha
+ */
+ sglrReferenceContext.ReferenceContext.prototype.blendEquationSeparate = function(modeRGB, modeAlpha) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidBlendEquation(modeRGB) ||
+ !sglrReferenceContext.isValidBlendEquation(modeAlpha),
+ gl.INVALID_ENUM))
+ return;
+
+ this.m_blendModeRGB = modeRGB;
+ this.m_blendModeAlpha = modeAlpha;
+ };
+
+ /**
+ * @param {number} src
+ * @param {number} dst
+ */
+ sglrReferenceContext.ReferenceContext.prototype.blendFunc = function(src, dst) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidBlendFactor(src) ||
+ !sglrReferenceContext.isValidBlendFactor(dst),
+ gl.INVALID_ENUM))
+ return;
+
+ this.m_blendFactorSrcRGB = src;
+ this.m_blendFactorSrcAlpha = src;
+ this.m_blendFactorDstRGB = dst;
+ this.m_blendFactorDstAlpha = dst;
+ };
+
+ /**
+ * @param {number} srcRGB
+ * @param {number} dstRGB
+ * @param {number} srcAlpha
+ * @param {number} dstAlpha
+ */
+ sglrReferenceContext.ReferenceContext.prototype.blendFuncSeparate = function(srcRGB, dstRGB, srcAlpha, dstAlpha) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidBlendFactor(srcRGB) ||
+ !sglrReferenceContext.isValidBlendFactor(dstRGB) ||
+ !sglrReferenceContext.isValidBlendFactor(srcAlpha) ||
+ !sglrReferenceContext.isValidBlendFactor(dstAlpha),
+ gl.INVALID_ENUM))
+ return;
+
+ this.m_blendFactorSrcRGB = srcRGB;
+ this.m_blendFactorSrcAlpha = srcAlpha;
+ this.m_blendFactorDstRGB = dstRGB;
+ this.m_blendFactorDstAlpha = dstAlpha;
+ };
+
+ /**
+ * @param {number} red
+ * @param {number} green
+ * @param {number} blue
+ * @param {number} alpha
+ */
+ sglrReferenceContext.ReferenceContext.prototype.blendColor = function(red, green, blue, alpha) {
+ this.m_blendColor = [deMath.clamp(red, 0, 1),
+ deMath.clamp(green, 0, 1),
+ deMath.clamp(blue, 0, 1),
+ deMath.clamp(alpha, 0, 1)];
+ };
+
+ /**
+ * @param {boolean} r
+ * @param {boolean} g
+ * @param {boolean} b
+ * @param {boolean} a
+ */
+ sglrReferenceContext.ReferenceContext.prototype.colorMask = function(r, g, b, a) {
+ this.m_colorMask = [r, g, b, a];
+ };
+
+ /**
+ * @param {boolean} mask
+ */
+ sglrReferenceContext.ReferenceContext.prototype.depthMask = function(mask) {
+ this.m_depthMask = mask;
+ };
+
+ /**
+ * @param {number} mask
+ */
+ sglrReferenceContext.ReferenceContext.prototype.stencilMask = function(mask) {
+ this.stencilMaskSeparate(gl.FRONT_AND_BACK, mask);
+ };
+
+ /**
+ * @param {number} face
+ * @param {number} mask
+ */
+ sglrReferenceContext.ReferenceContext.prototype.stencilMaskSeparate = function(face, mask) {
+ /** @type {boolean} */ var setFront = face == gl.FRONT || face == gl.FRONT_AND_BACK;
+ /** @type {boolean} */ var setBack = face == gl.BACK || face == gl.FRONT_AND_BACK;
+
+ if (this.conditionalSetError(!setFront && !setBack, gl.INVALID_ENUM))
+ return;
+
+ if (setFront) this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask = mask;
+ if (setBack) this.m_stencil[rrDefs.FaceType.FACETYPE_BACK].writeMask = mask;
+ };
+
+ /**
+ * @param {sglrReferenceContext.VertexArray} array
+ */
+ sglrReferenceContext.ReferenceContext.prototype.bindVertexArray = function(array) {
+ if (array)
+ this.m_vertexArrayBinding = array;
+ else
+ this.m_vertexArrayBinding = this.m_defaultVAO;
+ };
+
+ /**
+ * @return {sglrReferenceContext.VertexArray}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.createVertexArray = function() { return new sglrReferenceContext.VertexArray(this.m_limits.maxVertexAttribs); };
+
+ /**
+ * @param {number} array
+ */
+ sglrReferenceContext.ReferenceContext.prototype.deleteVertexArray = function(array) {};
+
+ /**
+ * @param {number} index
+ * @param {number} rawSize
+ * @param {number} type
+ * @param {boolean} normalized
+ * @param {number} stride
+ * @param {number} offset
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttribPointer = function(index, rawSize, type, normalized, stride, offset) {
+ /** @type {boolean} */ var allowBGRA = false;
+ /** @type {number} */ var effectiveSize = rawSize;
+
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(effectiveSize <= 0 || effectiveSize > 4, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(type != gl.BYTE && type != gl.UNSIGNED_BYTE &&
+ type != gl.SHORT && type != gl.UNSIGNED_SHORT &&
+ type != gl.INT && type != gl.UNSIGNED_INT &&
+ type != gl.FLOAT && type != gl.HALF_FLOAT &&
+ type != gl.INT_2_10_10_10_REV && type != gl.UNSIGNED_INT_2_10_10_10_REV, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(normalized != true && normalized != false, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(stride < 0, gl.INVALID_VALUE))
+ return;
+ 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))
+ return;
+ if (this.conditionalSetError(this.m_vertexArrayBinding != null && this.m_arrayBufferBinding == null && offset != 0, gl.INVALID_OPERATION))
+ return;
+
+ /** @type {?(sglrReferenceContext.VertexArray.VertexAttribArray)} */ var array_ = this.m_vertexArrayBinding.m_arrays[index]; // TODO: fix type
+
+ array_.size = rawSize;
+ array_.stride = stride;
+ array_.type = type;
+ array_.normalized = normalized;
+ array_.integer = false;
+ array_.offset = offset;
+
+ array_.bufferBinding = this.m_arrayBufferBinding;
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} size
+ * @param {number} type
+ * @param {number} stride
+ * @param {number} offset
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttribIPointer = function(index, size, type, stride, offset) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(size <= 0 || size > 4, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(type != gl.BYTE && type != gl.UNSIGNED_BYTE &&
+ type != gl.SHORT && type != gl.UNSIGNED_SHORT &&
+ type != gl.INT && type != gl.UNSIGNED_INT, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(stride < 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(this.m_vertexArrayBinding != null && this.m_arrayBufferBinding == null && offset != 0, gl.INVALID_OPERATION))
+ return;
+
+ /** @type {?(sglrReferenceContext.VertexArray.VertexAttribArray)} */ var array_ = this.m_vertexArrayBinding.m_arrays[index]; // TODO: fix type
+
+ array_.size = size;
+ array_.stride = stride;
+ array_.type = type;
+ array_.normalized = false;
+ array_.integer = true;
+ array_.offset = offset;
+
+ array_.bufferBinding = this.m_arrayBufferBinding;
+ };
+
+ /**
+ * @param {number} index
+ */
+ sglrReferenceContext.ReferenceContext.prototype.enableVertexAttribArray = function(index) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_vertexArrayBinding.m_arrays[index].enabled = true;
+ };
+
+ /**
+ * @param {number} index
+ */
+ sglrReferenceContext.ReferenceContext.prototype.disableVertexAttribArray = function(index) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_vertexArrayBinding.m_arrays[index].enabled = false;
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} divisor
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttribDivisor = function(index, divisor) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_vertexArrayBinding.m_arrays[index].divisor = divisor;
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttrib1f = function(index, x) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, 0, 0, 1);
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} x
+ * @param {number} y
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttrib2f = function(index, x, y) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, 0, 1);
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttrib3f = function(index, x, y, z) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, 1);
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @param {number} w
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttrib4f = function(index, x, y, z, w) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, w);
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @param {number} w
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttribI4i = function(index, x, y, z, w) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, w);
+ };
+
+ /**
+ * @param {number} index
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @param {number} w
+ */
+ sglrReferenceContext.ReferenceContext.prototype.vertexAttribI4ui = function(index, x, y, z, w) {
+ if (this.conditionalSetError(index >= this.m_limits.maxVertexAttribs, gl.INVALID_VALUE))
+ return;
+
+ this.m_currentAttribs[index] = new rrGenericVector.GenericVec4(x, y, z, w);
+ };
+
+ /**
+ * @param {sglrShaderProgram.ShaderProgram} program
+ * @param {string} name
+ * @return {number}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getAttribLocation = function(program, name) {
+ if (this.conditionalSetError(!(program), gl.INVALID_OPERATION))
+ return -1;
+
+ for (var i = 0; i < program.m_attributeNames.length; i++)
+ if (program.m_attributeNames[i] === name)
+ return i;
+
+ return -1;
+ };
+
+ /**
+ * @param {number} pname
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getParameter = function(pname) {
+ switch (pname) {
+ case (gl.VIEWPORT): return new Int32Array(this.m_viewport);
+ case (gl.SCISSOR_BOX): return new Int32Array(this.m_scissorBox);
+ default:
+ throw new Error('Unimplemented');
+ }
+ };
+
+ /**
+ * @param {number} location
+ * @param {gluShaderUtil.DataType} type
+ * @param {Array<number>} value
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniformValue = function(location, type, value) {
+ if (this.conditionalSetError(!this.m_currentProgram, gl.INVALID_OPERATION))
+ return;
+
+ if (location === null)
+ return;
+
+ /** @type {sglrShaderProgram.Uniform} */ var uniform = this.m_currentProgram.m_uniforms[location];
+
+ if (this.conditionalSetError(!uniform, gl.INVALID_OPERATION))
+ return;
+
+ if (gluShaderUtil.isDataTypeSampler(uniform.type)) {
+ if (this.conditionalSetError(type != gluShaderUtil.DataType.INT, gl.INVALID_OPERATION))
+ return;
+ } else if (this.conditionalSetError(uniform.type != type, gl.INVALID_OPERATION))
+ return;
+ /* TODO: Do we need to copy objects? */
+ uniform.value = value;
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform1f = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT, [x]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform1fv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT, x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform1i = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT, [x]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform1iv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT, x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ * @param {number} y
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform2f = function(location, x, y) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC2, [x, y]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform2fv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC2, x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ * @param {number} y
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform2i = function(location, x, y) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC2, [x, y]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform2iv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC2, x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform3f = function(location, x, y, z) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC3, [x, y, z]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform3fv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC3, x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform3i = function(location, x, y, z) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC3, [x, y, z]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform3iv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC3, x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @param {number} w
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform4f = function(location, x, y, z, w) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC4, [x, y, z, w]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform4fv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_VEC4, x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @param {number} w
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform4i = function(location, x, y, z, w) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC4, [x, y, z, w]);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniform4iv = function(location, x) {
+ return this.uniformValue(location, gluShaderUtil.DataType.INT_VEC4, x);
+ };
+
+ /**
+ * @return {Array<string>}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getSupportedExtensions = function() {
+ var extensions = gl.getSupportedExtensions(); //TODO: Let's just return gl's supported extensions for now
+ return extensions;
+ };
+
+ /**
+ * @param {string} name
+ * @return {*}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getExtension = function(name) {
+ return gl.getExtension(name); //TODO: Let's just return gl's supported extensions for now
+ };
+
+ /** transpose matrix 'x' of 'size' columns and rows
+ * @param {number} size
+ * @param {Array<number>} x
+ * @return {Array<number>}
+ */
+ sglrReferenceContext.trans = function(size, x) {
+ /** @type {Array<number>} */ var result = [];
+ for (var row = 0; row < size; ++row)
+ for (var col = 0; col < size; ++col)
+ result[row * size + col] = x[col * size + row];
+
+ return result;
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniformMatrix2fv = function(location, transpose, x) {
+ /* change from column-major to internal row-major if transpose if FALSE */
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_MAT2, !transpose ? sglrReferenceContext.trans(2, x) : x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniformMatrix3fv = function(location, transpose, x) {
+ /* change from column-major to internal row-major if transpose if FALSE */
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_MAT3, !transpose ? sglrReferenceContext.trans(3, x) : x);
+ };
+
+ /**
+ * @param {number} location
+ * @param {Array<number>} x
+ */
+ sglrReferenceContext.ReferenceContext.prototype.uniformMatrix4fv = function(location, transpose, x) {
+ /* change from column-major to internal row-major if transpose if FALSE */
+ return this.uniformValue(location, gluShaderUtil.DataType.FLOAT_MAT4, !transpose ? sglrReferenceContext.trans(4, x) : x);
+ };
+
+ /**
+ * @param {sglrShaderProgram.ShaderProgram} program
+ * @param {string} name
+ * @return {number}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getUniformLocation = function(program, name) {
+ if (this.conditionalSetError(!program, gl.INVALID_OPERATION))
+ return -1;
+
+ for (var i = 0; i < program.m_uniforms.length; i++)
+ if (program.m_uniforms[i].name === name)
+ return i;
+
+ return -1;
+ };
+
+ /**
+ * @param {number} w
+ */
+ sglrReferenceContext.ReferenceContext.prototype.lineWidth = function(w) {
+ if (this.conditionalSetError(w < 0, gl.INVALID_VALUE))
+ return;
+ this.m_lineWidth = w;
+ };
+
+ /**
+ * @param {number} target
+ * @return {boolean}
+ */
+ sglrReferenceContext.isValidBufferTarget = function(target) {
+ switch (target) {
+ case gl.ARRAY_BUFFER:
+ case gl.COPY_READ_BUFFER:
+ case gl.COPY_WRITE_BUFFER:
+ case gl.ELEMENT_ARRAY_BUFFER:
+ case gl.PIXEL_PACK_BUFFER:
+ case gl.PIXEL_UNPACK_BUFFER:
+ case gl.TRANSFORM_FEEDBACK_BUFFER:
+ case gl.UNIFORM_BUFFER:
+ return true;
+
+ default:
+ return false;
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @param {sglrReferenceContext.DataBuffer} buffer
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.setBufferBinding = function(target, buffer) {
+ switch (target) {
+ case gl.ARRAY_BUFFER: this.m_arrayBufferBinding = buffer; break;
+ case gl.COPY_READ_BUFFER: this.m_copyReadBufferBinding = buffer; break;
+ case gl.COPY_WRITE_BUFFER: this.m_copyWriteBufferBinding = buffer; break;
+ case gl.ELEMENT_ARRAY_BUFFER: this.m_vertexArrayBinding.m_elementArrayBufferBinding = buffer; break;
+ case gl.PIXEL_PACK_BUFFER: this.m_pixelPackBufferBinding = buffer; break;
+ case gl.PIXEL_UNPACK_BUFFER: this.m_pixelUnpackBufferBinding = buffer; break;
+ case gl.TRANSFORM_FEEDBACK_BUFFER: this.m_transformFeedbackBufferBinding = buffer; break;
+ case gl.UNIFORM_BUFFER: this.m_uniformBufferBinding = buffer; break;
+ default:
+ throw new Error('Unrecognized target: ' + target);
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @return {sglrReferenceContext.DataBuffer}
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getBufferBinding = function(target) {
+ switch (target) {
+ case gl.ARRAY_BUFFER: return this.m_arrayBufferBinding;
+ case gl.COPY_READ_BUFFER: return this.m_copyReadBufferBinding;
+ case gl.COPY_WRITE_BUFFER: return this.m_copyWriteBufferBinding;
+ case gl.ELEMENT_ARRAY_BUFFER: return this.m_vertexArrayBinding.m_elementArrayBufferBinding;
+ case gl.PIXEL_PACK_BUFFER: return this.m_pixelPackBufferBinding;
+ case gl.PIXEL_UNPACK_BUFFER: return this.m_pixelUnpackBufferBinding;
+ case gl.TRANSFORM_FEEDBACK_BUFFER: return this.m_transformFeedbackBufferBinding;
+ case gl.UNIFORM_BUFFER: return this.m_uniformBufferBinding;
+ default:
+ throw new Error('Unrecognized target: ' + target);
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @param {sglrReferenceContext.DataBuffer} buffer
+ */
+ sglrReferenceContext.ReferenceContext.prototype.bindBuffer = function(target, buffer) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidBufferTarget(target), gl.INVALID_ENUM))
+ return;
+
+ this.setBufferBinding(target, buffer);
+ };
+
+ /**
+ * @return {sglrReferenceContext.DataBuffer}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.createBuffer = function() { return new sglrReferenceContext.DataBuffer(); };
+
+ /**
+ * @param {number} buffer
+ */
+ sglrReferenceContext.ReferenceContext.prototype.deleteBuffer = function(buffer) {};
+
+ /**
+ * @param {number} target
+ * @param {number|goog.NumberArray} input
+ * @param {number} usage
+ */
+ sglrReferenceContext.ReferenceContext.prototype.bufferData = function(target, input, usage) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidBufferTarget(target), gl.INVALID_ENUM))
+ return;
+ /** @type {sglrReferenceContext.DataBuffer} */ var buffer = this.getBufferBinding(target);
+ if (this.conditionalSetError(!buffer, gl.INVALID_OPERATION))
+ return;
+
+ if (typeof input == 'number') {
+ if (this.conditionalSetError(input < 0, gl.INVALID_VALUE))
+ return;
+ buffer.setStorage(input);
+ } else {
+ buffer.setData(input);
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} offset
+ * @param {goog.NumberArray} data
+ */
+ sglrReferenceContext.ReferenceContext.prototype.bufferSubData = function(target, offset, data) {
+ if (this.conditionalSetError(!sglrReferenceContext.isValidBufferTarget(target), gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(offset < 0, gl.INVALID_VALUE))
+ return;
+ /** @type {sglrReferenceContext.DataBuffer} */ var buffer = this.getBufferBinding(target);
+ if (this.conditionalSetError(!buffer, gl.INVALID_OPERATION))
+ return;
+
+ if (this.conditionalSetError(offset + data.byteLength > buffer.getSize(), gl.INVALID_VALUE))
+ return;
+ buffer.setSubData(offset, data);
+ };
+
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ * @param {number} format
+ * @param {number} type
+ * @param {goog.NumberArray} pixels
+ */
+ sglrReferenceContext.ReferenceContext.prototype.readPixels = function(x, y, width, height, format, type, pixels) {
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src = this.getReadColorbuffer();
+
+ // Map transfer format.
+ /** @type {tcuTexture.TextureFormat} */ var transferFmt = gluTextureUtil.mapGLTransferFormat(format, type);
+
+ // Clamp input values
+ /** @type {number} */ var copyX = deMath.clamp(x, 0, src.raw().getHeight());
+ /** @type {number} */ var copyY = deMath.clamp(y, 0, src.raw().getDepth());
+ /** @type {number} */ var copyWidth = deMath.clamp(width, 0, src.raw().getHeight() - x);
+ /** @type {number} */ var copyHeight = deMath.clamp(height, 0, src.raw().getDepth() - y);
+
+ /** @type {?ArrayBuffer} */ var data;
+ /** @type {number} */ var offset;
+ if (this.m_pixelPackBufferBinding) {
+ if (this.conditionalSetError(typeof pixels !== 'number', gl.INVALID_VALUE))
+ return;
+ data = this.m_pixelPackBufferBinding.getData();
+ offset = pixels.byteOffset;
+ } else {
+ if (pixels instanceof ArrayBuffer) {
+ data = pixels;
+ offset = 0;
+ } else {
+ data = pixels.buffer;
+ offset = pixels.byteOffset;
+ }
+ }
+
+ /** @type {tcuTexture.PixelBufferAccess} */
+ var dst = new tcuTexture.PixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ depth: 1,
+ rowPitch: deMath.deAlign32(width * transferFmt.getPixelSize(), this.m_pixelPackAlignment),
+ slicePitch: 0,
+ data: data,
+ offset: offset});
+
+ src = src.getSubregion([copyX, copyY, copyWidth, copyHeight]);
+ src.resolveMultisampleColorBuffer(tcuTextureUtil.getSubregion(dst, 0, 0, 0, copyWidth, copyHeight, 1));
+ };
+
+ /**
+ * @return {number}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getType = function() {
+ return this.m_type;
+ };
+
+ /**
+ * @return {tcuTexture.PixelBufferAccess}
+ */
+ sglrReferenceContext.nullAccess = function() {
+ return new tcuTexture.PixelBufferAccess({
+ width: 0,
+ height: 0});
+ };
+
+ /**
+ * @param {sglrReferenceContext.Framebuffer} framebuffer
+ * @param {sglrReferenceContext.AttachmentPoint} point
+ * @return {tcuTexture.PixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getFboAttachment = function(framebuffer, point) {
+ /** @type {sglrReferenceContext.Attachment} */ var attachment = framebuffer.getAttachment(point);
+
+ switch (attachment.type) {
+ case sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE: {
+ var container = /** @type {sglrReferenceContext.TextureContainer} */ (attachment.object);
+ /** @type {?sglrReferenceContext.TextureType} */ var type = container.getType();
+ var texture = container.texture;
+
+ if (type == sglrReferenceContext.TextureType.TYPE_2D)
+ return texture.getLevel(attachment.level);
+ else if (type == sglrReferenceContext.TextureType.TYPE_CUBE_MAP)
+ return texture.getFace(attachment.level, sglrReferenceContext.texTargetToFace(attachment.texTarget));
+ else if (type == sglrReferenceContext.TextureType.TYPE_2D_ARRAY ||
+ type == sglrReferenceContext.TextureType.TYPE_3D ||
+ type == sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY) {
+ /** @type {tcuTexture.PixelBufferAccess} */ var level = texture.getLevel(attachment.level);
+
+ return new tcuTexture.PixelBufferAccess({
+ format: level.getFormat(),
+ width: level.getWidth(),
+ height: level.getHeight(),
+ depth: 1,
+ rowPitch: level.getRowPitch(),
+ slicePitch: 0,
+ data: level.getBuffer(),
+ offset: level.getSlicePitch() * attachment.layer});
+ } else
+ return sglrReferenceContext.nullAccess();
+ }
+
+ case sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_RENDERBUFFER: {
+ var rbo = /** @type {sglrReferenceContext.Renderbuffer} */ (attachment.object);
+ return rbo.getAccess();
+ }
+
+ default:
+ return sglrReferenceContext.nullAccess();
+ }
+ };
+
+ /**
+ * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getReadColorbuffer = function() {
+ if (this.m_readFramebufferBinding)
+ return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_readFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0));
+ else
+ return this.m_defaultColorbuffer;
+ };
+
+ // sglrReferenceContext.ReferenceContext.prototype.drawArrays = function(mode, first, count) {
+ // this.drawArraysInstanced(mode, first, count, 1);
+ // };
+
+ /**
+ * @param {number} target
+ * @return {number}
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.checkFramebufferStatus = function(target) {
+ if (this.conditionalSetError(target != gl.FRAMEBUFFER &&
+ target != gl.DRAW_FRAMEBUFFER &&
+ target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM))
+ return 0;
+
+ // Select binding point.
+ /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding;
+
+ // Default framebuffer is always complete.
+ if (!framebufferBinding)
+ return gl.FRAMEBUFFER_COMPLETE;
+
+ /** @type {number} */ var width = -1;
+ /** @type {number} */ var height = -1;
+ /** @type {boolean} */ var hasAttachment = false;
+ /** @type {boolean} */ var attachmentComplete = true;
+ /** @type {boolean} */ var dimensionsOk = true;
+
+ for (var key in sglrReferenceContext.AttachmentPoint) {
+ /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.AttachmentPoint[key];
+ /** @type {sglrReferenceContext.Attachment} */ var attachment = framebufferBinding.getAttachment(point);
+ /** @type {number} */ var attachmentWidth = 0;
+ /** @type {number} */ var attachmentHeight = 0;
+ /** @type {tcuTexture.TextureFormat} */ var attachmentFormat;
+
+ if (attachment.type == sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE) {
+ var container = /** @type {sglrReferenceContext.TextureContainer} */ (attachment.object);
+ /** @type {tcuTexture.ConstPixelBufferAccess} */ var level;
+
+ if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_2D) {
+ DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_2D);
+ /** @type {sglrReferenceContext.Texture2D} */ var tex2D = /** @type {sglrReferenceContext.Texture2D} */ (container.texture);
+
+ if (tex2D.hasLevel(attachment.level))
+ level = tex2D.getLevel(attachment.level);
+ // TODO: implement CUBE_MAP, 2D_ARRAY, 3D, CUBE_MAP_ARRAY
+ } else if (deMath.deInRange32(attachment.texTarget, sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X,
+ sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z)) {
+ DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_CUBE_MAP);
+
+ var texCube = /** @type {sglrReferenceContext.TextureCube} */ (container.texture);
+ var face = sglrReferenceContext.texTargetToFace(attachment.texTarget);
+
+ if (texCube.hasFace(attachment.level, face))
+ level = texCube.getFace(attachment.level, face);
+ } else if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_2D_ARRAY) {
+ DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_2D_ARRAY);
+ var tex2DArr = /** @type {sglrReferenceContext.Texture2DArray} */ (container.texture);
+
+ if (tex2DArr.hasLevel(attachment.level))
+ level = tex2DArr.getLevel(attachment.level); // \note Slice doesn't matter here.
+ } else if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_3D) {
+ DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_3D);
+ var tex3D = /** @type {sglrReferenceContext.Texture3D} */ (container.texture);
+
+ if (tex3D.hasLevel(attachment.level))
+ level = tex3D.getLevel(attachment.level); // \note Slice doesn't matter here.
+ // } else if (attachment.texTarget == sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_ARRAY) {
+ // DE_ASSERT(container.textureType == sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY);
+ // var texCubeArr = container.texture;
+ //
+ // if (texCubeArr.hasLevel(attachment.level))
+ // level = texCubeArr.getLevel(attachment.level); // \note Slice doesn't matter here.
+ } else
+ throw new Error('sglrReferenceContext.Framebuffer attached to a texture but no valid target specified.');
+
+ attachmentWidth = level.getWidth();
+ attachmentHeight = level.getHeight();
+ attachmentFormat = level.getFormat();
+ } else if (attachment.type == sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_RENDERBUFFER) {
+ var renderbuffer = attachment.object;
+
+ attachmentWidth = renderbuffer.getWidth();
+ attachmentHeight = renderbuffer.getHeight();
+ attachmentFormat = renderbuffer.getFormat();
+ } else
+ continue; // Skip rest of checks.
+
+ if (!hasAttachment && attachmentWidth > 0 && attachmentHeight > 0) {
+ width = attachmentWidth;
+ height = attachmentHeight;
+ hasAttachment = true;
+ } else if (attachmentWidth != width || attachmentHeight != height)
+ dimensionsOk = false;
+
+ // Validate attachment point compatibility.
+ switch (attachmentFormat.order) {
+ case tcuTexture.ChannelOrder.R:
+ case tcuTexture.ChannelOrder.RG:
+ case tcuTexture.ChannelOrder.RGB:
+ case tcuTexture.ChannelOrder.RGBA:
+ case tcuTexture.ChannelOrder.sRGB:
+ case tcuTexture.ChannelOrder.sRGBA:
+ if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0)
+ attachmentComplete = false;
+ break;
+
+ case tcuTexture.ChannelOrder.D:
+ if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH)
+ attachmentComplete = false;
+ break;
+
+ case tcuTexture.ChannelOrder.S:
+ if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL)
+ attachmentComplete = false;
+ break;
+
+ case tcuTexture.ChannelOrder.DS:
+ if (point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH &&
+ point != sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL)
+ attachmentComplete = false;
+ break;
+
+ default:
+ throw new Error('Unsupported attachment channel order:' + attachmentFormat.order);
+ }
+ }
+
+ if (!attachmentComplete)
+ return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ else if (!hasAttachment)
+ return gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+ else if (!dimensionsOk)
+ return gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ else
+ return gl.FRAMEBUFFER_COMPLETE;
+ };
+
+ /**
+ * @param {number} mode
+ * @return {boolean}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.predrawErrorChecks = function(mode) {
+ if (this.conditionalSetError(mode != gl.POINTS &&
+ mode != gl.LINE_STRIP && mode != gl.LINE_LOOP && mode != gl.LINES &&
+ mode != gl.TRIANGLE_STRIP && mode != gl.TRIANGLE_FAN && mode != gl.TRIANGLES,
+ gl.INVALID_ENUM))
+ return false;
+
+ // \todo [jarkko] Uncomment following code when the buffer mapping support is added
+ //for (size_t ndx = 0; ndx < vao.m_arrays.length; ++ndx)
+ // if (vao.m_arrays[ndx].enabled && vao.m_arrays[ndx].bufferBinding && vao.m_arrays[ndx].bufferBinding->isMapped)
+ // RC_ERROR_RET(gl.INVALID_OPERATION, RC_RET_VOID);
+
+ if (this.conditionalSetError(this.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE, gl.INVALID_FRAMEBUFFER_OPERATION))
+ return false;
+
+ return true;
+ };
+
+ /**
+ * Draws quads from vertex arrays
+ * @param {number} mode GL primitive type to draw with.
+ * @param {number} first First vertex to begin drawing with
+ * @param {number} count How many vertices to draw (not counting vertices before first)
+ * @param {number} instanceCount
+ */
+ sglrReferenceContext.ReferenceContext.prototype.drawArraysInstanced = function(mode, first, count, instanceCount) {
+ if (this.conditionalSetError(first < 0 || count < 0 || instanceCount < 0, gl.INVALID_VALUE))
+ return;
+
+ if (!this.predrawErrorChecks(mode))
+ return;
+
+ // All is ok
+ this.drawQuads(mode, first, count, instanceCount);
+ };
+
+ /**
+ * @param {number} mode GL primitive type to draw with.
+ * @param {number} start
+ * @param {number} end
+ * @param {number} count How many vertices to draw (not counting vertices before first)
+ * @param {number} type Data type
+ * @param {number} offset
+ */
+ sglrReferenceContext.ReferenceContext.prototype.drawRangeElements = function(mode, start, end, count, type, offset) {
+ if (this.conditionalSetError(end < start, gl.INVALID_VALUE))
+ return;
+
+ this.drawElements(mode, count, type, offset);
+ };
+
+ /**
+ * @param {number} mode GL primitive type to draw with.
+ * @param {number} count How many vertices to draw (not counting vertices before first)
+ * @param {number} type Data type
+ * @param {number} offset
+ */
+ sglrReferenceContext.ReferenceContext.prototype.drawElements = function(mode, count, type, offset) {
+ this.drawElementsInstanced(mode, count, type, offset, 1);
+ };
+
+ /**
+ * @param {number} mode GL primitive type to draw with.
+ * @param {number} count How many vertices to draw (not counting vertices before first)
+ * @param {number} type Data type
+ * @param {number} offset
+ * @param {number} instanceCount
+ */
+ sglrReferenceContext.ReferenceContext.prototype.drawElementsInstanced = function(mode, count, type, offset, instanceCount) {
+ this.drawElementsInstancedBaseVertex(mode, count, type, offset, instanceCount, 0);
+ };
+
+ /**
+ * @param {number} mode GL primitive type to draw with.
+ * @param {number} count How many vertices to draw (not counting vertices before first)
+ * @param {number} type Data type
+ * @param {number} offset
+ * @param {number} instanceCount
+ * @param {number} baseVertex
+ */
+ sglrReferenceContext.ReferenceContext.prototype.drawElementsInstancedBaseVertex = function(mode, count, type, offset, instanceCount, baseVertex) {
+ var vao = this.m_vertexArrayBinding;
+
+ if (this.conditionalSetError(type != gl.UNSIGNED_BYTE &&
+ type != gl.UNSIGNED_SHORT &&
+ type != gl.UNSIGNED_INT, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(count < 0 || instanceCount < 0, gl.INVALID_VALUE))
+ return;
+
+ if (!this.predrawErrorChecks(mode))
+ return;
+
+ if (this.conditionalSetError(count > 0 && !vao.m_elementArrayBufferBinding, gl.INVALID_OPERATION))
+ return;
+ // All is ok
+ var data = vao.m_elementArrayBufferBinding.getData();
+ var indices = new rrRenderer.DrawIndices(data, sglrReferenceUtils.mapGLIndexType(type), offset, baseVertex);
+
+ this.drawQuads(mode, indices, count, instanceCount);
+ };
+
+ /**
+ * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} access
+ * @return {Array<number>}
+ */
+ sglrReferenceContext.getBufferRect = function(access) { return [0, 0, access.raw().getHeight(), access.raw().getDepth()]; };
+
+ /**
+ * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getDrawColorbuffer = function() {
+ if (this.m_drawFramebufferBinding)
+ return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_drawFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_COLOR0));
+ return this.m_defaultColorbuffer;
+ };
+
+ /**
+ * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getDrawDepthbuffer = function() {
+ if (this.m_drawFramebufferBinding)
+ return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_drawFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH));
+ return this.m_defaultDepthbuffer;
+ };
+
+ /**
+ * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getDrawStencilbuffer = function() {
+ if (this.m_drawFramebufferBinding)
+ return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_drawFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL));
+ return this.m_defaultStencilbuffer;
+ };
+
+ /**
+ * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getReadDepthbuffer = function() {
+ if (this.m_readFramebufferBinding)
+ return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_readFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_DEPTH));
+ return this.m_defaultDepthbuffer;
+ };
+
+ /**
+ * @return {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.getReadStencilbuffer = function() {
+ if (this.m_readFramebufferBinding)
+ return rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(this.getFboAttachment(this.m_readFramebufferBinding, sglrReferenceContext.AttachmentPoint.ATTACHMENTPOINT_STENCIL));
+ return this.m_defaultStencilbuffer;
+ };
+
+ /**
+ * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} access
+ * @param {number} s
+ * @param {number} x
+ * @param {number} y
+ * @param {number} depth
+ */
+ sglrReferenceContext.writeDepthOnly = function(access, s, x, y, depth) { access.raw().setPixDepth(depth, s, x, y); };
+
+ /**
+ * @param {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} access
+ * @param {number} s
+ * @param {number} x
+ * @param {number} y
+ * @param {number} stencil
+ * @param {number} writeMask
+ */
+ sglrReferenceContext.writeStencilOnly = function(access, s, x, y, stencil, writeMask) {
+ /** @type {number} */ var oldVal = access.raw().getPixelInt(s, x, y)[3];
+ access.raw().setPixStencil((oldVal & ~writeMask) | (stencil & writeMask), s, x, y);
+ };
+
+ /**
+ * @param {number} bits
+ * @param {number} s
+ * @return {number}
+ */
+ sglrReferenceContext.maskStencil = function(bits, s) { return s & ((1 << bits) - 1); };
+
+ /**
+ * @param {number} buffers
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clear = function(buffers) {
+ if (this.conditionalSetError((buffers & ~(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) != 0, gl.INVALID_VALUE))
+ return;
+
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf0 = this.getDrawColorbuffer();
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var depthBuf = this.getDrawDepthbuffer();
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var stencilBuf = this.getDrawStencilbuffer();
+ /** @type {boolean} */ var hasColor0 = /** @type {!boolean} */ (colorBuf0 && !colorBuf0.isEmpty());
+ /** @type {boolean} */ var hasDepth = /** @type {!boolean} */ (depthBuf && !depthBuf.isEmpty());
+ /** @type {boolean} */ var hasStencil = /** @type {!boolean} */ (stencilBuf && !stencilBuf.isEmpty());
+ /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff];
+
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access;
+ /** @type {boolean} */ var isSharedDepthStencil;
+
+ if (hasColor0 && (buffers & gl.COLOR_BUFFER_BIT) != 0) {
+ /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf0));
+ access = colorBuf0.getSubregion(colorArea);
+ /** @type {boolean} */ var isSRGB = colorBuf0.raw().getFormat().isSRGB();
+ /** @type {Array<number>} */ var c = (isSRGB && this.m_sRGBUpdateEnabled) ? tcuTextureUtil.linearToSRGB(this.m_clearColor) : this.m_clearColor;
+ /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3];
+ /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3];
+
+ if (!maskUsed)
+ access.clear(c);
+ else if (!maskZero) {
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ access.raw().setPixel(tcuTextureUtil.select(c, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y);
+ }
+ // else all channels masked out
+ }
+
+ if (hasDepth && (buffers & gl.DEPTH_BUFFER_BIT) != 0 && this.m_depthMask) {
+ /** @type {Array<number>} */ var depthArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(depthBuf));
+ access = depthBuf.getSubregion(depthArea);
+ isSharedDepthStencil = depthBuf.raw().getFormat().order != tcuTexture.ChannelOrder.D;
+
+ if (isSharedDepthStencil) {
+ // Slow path where stencil is masked out in write.
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ sglrReferenceContext.writeDepthOnly(access, s, x, y, this.m_clearDepth);
+ } else
+ access.clear([this.m_clearDepth, 0, 0, 0]);
+ }
+
+ if (hasStencil && (buffers & gl.STENCIL_BUFFER_BIT) != 0) {
+ /** @type {Array<number>} */ var stencilArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(stencilBuf));
+ access = stencilBuf.getSubregion(stencilArea);
+ /** @type {number} */ var stencilBits = stencilBuf.raw().getFormat().getNumStencilBits();
+ /** @type {number} */ var stencil = sglrReferenceContext.maskStencil(stencilBits, this.m_clearStencil);
+ isSharedDepthStencil = stencilBuf.raw().getFormat().order != tcuTexture.ChannelOrder.S;
+
+ if (isSharedDepthStencil || ((this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask & ((1 << stencilBits) - 1)) != ((1 << stencilBits) - 1))) {
+ // Slow path where depth or stencil is masked out in write.
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ sglrReferenceContext.writeStencilOnly(access, s, x, y, stencil, this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask);
+ } else
+ access.clear([0, 0, 0, stencil]);
+ }
+ };
+
+ /**
+ * @param {number} buffer
+ * @param {number} drawbuffer
+ * @param {Array<number>} value
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clearBufferiv = function(buffer, drawbuffer, value) {
+ if (this.conditionalSetError(buffer != gl.COLOR && buffer != gl.STENCIL, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(drawbuffer != 0, gl.INVALID_VALUE))
+ return;
+
+ /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff];
+
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access;
+
+ if (buffer == gl.COLOR) {
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf = this.getDrawColorbuffer();
+ /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3];
+ /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3];
+
+ if (!colorBuf.isEmpty() && !maskZero) {
+ /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf));
+ access = colorBuf.getSubregion(colorArea);
+
+ if (!maskUsed)
+ access.clear(value);
+ else {
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ access.raw().setPixel(tcuTextureUtil.select(value, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y);
+ }
+ }
+ } else {
+ if (buffer !== gl.STENCIL)
+ throw new Error('Unexpected buffer type: ' + buffer);
+
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var stencilBuf = this.getDrawStencilbuffer();
+
+ if (!stencilBuf.isEmpty() && this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask != 0) {
+ /** @type {Array<number>} */ var area = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(stencilBuf));
+ access = stencilBuf.getSubregion(area);
+ /** @type {number} */ var stencil = value[0];
+
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ sglrReferenceContext.writeStencilOnly(access, s, x, y, stencil, this.m_stencil[rrDefs.FaceType.FACETYPE_FRONT].writeMask);
+ }
+ }
+ };
+
+ /**
+ * @param {number} buffer
+ * @param {number} drawbuffer
+ * @param {Array<number>} value
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clearBufferfv = function(buffer, drawbuffer, value) {
+ if (this.conditionalSetError(buffer != gl.COLOR && buffer != gl.DEPTH, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(drawbuffer != 0, gl.INVALID_VALUE))
+ return;
+
+ /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff];
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access;
+ if (buffer == gl.COLOR) {
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf = this.getDrawColorbuffer();
+ /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3];
+ /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3];
+
+ if (!colorBuf.isEmpty() && !maskZero) {
+ /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf));
+ access = colorBuf.getSubregion(colorArea);
+ var color = value;
+
+ if (this.m_sRGBUpdateEnabled && access.raw().getFormat().isSRGB())
+ color = tcuTextureUtil.linearToSRGB(color);
+
+ if (!maskUsed)
+ access.clear(color);
+ else {
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ access.raw().setPixel(tcuTextureUtil.select(color, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y);
+ }
+ }
+ } else {
+ if (buffer !== gl.DEPTH)
+ throw new Error('Unexpected buffer type: ' + buffer);
+
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var depthBuf = this.getDrawDepthbuffer();
+
+ if (!depthBuf.isEmpty() && this.m_depthMask) {
+ /** @type {Array<number>} */ var area = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(depthBuf));
+ access = depthBuf.getSubregion(area);
+ /** @type {number} */ var depth = value[0];
+
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ sglrReferenceContext.writeDepthOnly(access, s, x, y, depth);
+ }
+ }
+ };
+
+ /**
+ * @param {number} buffer
+ * @param {number} drawbuffer
+ * @param {Array<number>} value
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clearBufferuiv = function(buffer, drawbuffer, value) {
+ if (this.conditionalSetError(buffer != gl.COLOR, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(drawbuffer != 0, gl.INVALID_VALUE))
+ return;
+
+ /** @type {Array<number>} */ var baseArea = this.m_scissorEnabled ? this.m_scissorBox : [0, 0, 0x7fffffff, 0x7fffffff];
+
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf = this.getDrawColorbuffer();
+ /** @type {boolean} */ var maskUsed = !this.m_colorMask[0] || !this.m_colorMask[1] || !this.m_colorMask[2] || !this.m_colorMask[3];
+ /** @type {boolean} */ var maskZero = !this.m_colorMask[0] && !this.m_colorMask[1] && !this.m_colorMask[2] && !this.m_colorMask[3];
+
+ if (!colorBuf.isEmpty() && !maskZero) {
+ /** @type {Array<number>} */ var colorArea = deMath.intersect(baseArea, sglrReferenceContext.getBufferRect(colorBuf));
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var access = colorBuf.getSubregion(colorArea);
+
+ if (!maskUsed)
+ access.clear(value);
+ else {
+ for (var y = 0; y < access.raw().getDepth(); y++)
+ for (var x = 0; x < access.raw().getHeight(); x++)
+ for (var s = 0; s < access.getNumSamples(); s++)
+ access.raw().setPixel(tcuTextureUtil.select(value, access.raw().getPixel(s, x, y), this.m_colorMask), s, x, y);
+ }
+ }
+ };
+
+ /**
+ * @param {number} buffer
+ * @param {number} drawbuffer
+ * @param {number} depth
+ * @param {number} stencil
+ */
+ sglrReferenceContext.ReferenceContext.prototype.clearBufferfi = function(buffer, drawbuffer, depth, stencil) {
+ if (this.conditionalSetError(buffer != gl.DEPTH_STENCIL, gl.INVALID_ENUM))
+ return;
+ this.clearBufferfv(gl.DEPTH, drawbuffer, [depth]);
+ this.clearBufferiv(gl.STENCIL, drawbuffer, [stencil]);
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} attachment
+ * @param {sglrReferenceContext.TexTarget} textarget
+ * @param {sglrReferenceContext.TextureContainer} texture
+ * @param {number} level
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.framebufferTexture2D = function(target, attachment, textarget, texture, level) {
+ if (attachment == gl.DEPTH_STENCIL_ATTACHMENT) {
+ // Attach to both depth and stencil.
+ this.framebufferTexture2D(target, gl.DEPTH_ATTACHMENT, textarget, texture, level);
+ this.framebufferTexture2D(target, gl.STENCIL_ATTACHMENT, textarget, texture, level);
+ } else {
+ /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.mapGLAttachmentPoint(attachment);
+ /** @type {sglrReferenceContext.TexTarget} */ var fboTexTarget = sglrReferenceContext.mapGLFboTexTarget(textarget);
+
+ if (this.conditionalSetError(target != gl.FRAMEBUFFER &&
+ target != gl.DRAW_FRAMEBUFFER &&
+ target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(point == undefined, gl.INVALID_ENUM))
+ return;
+
+ // Select binding point.
+ /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding;
+ if (this.conditionalSetError(!framebufferBinding, gl.INVALID_OPERATION))
+ return;
+
+ if (texture) {
+ if (this.conditionalSetError(level != 0, gl.INVALID_VALUE))
+ return;
+
+ if (texture.getType() == sglrReferenceContext.TextureType.TYPE_2D) {
+ if (this.conditionalSetError(fboTexTarget != sglrReferenceContext.TexTarget.TEXTARGET_2D, gl.INVALID_OPERATION))
+ return;
+ } else {
+ if (!texture.getType() == sglrReferenceContext.TextureType.TYPE_CUBE_MAP)
+ throw new Error('Unsupported texture type');
+ if (this.conditionalSetError(!deMath.deInRange32(fboTexTarget, sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_POSITIVE_X, sglrReferenceContext.TexTarget.TEXTARGET_CUBE_MAP_NEGATIVE_Z), gl.INVALID_OPERATION))
+ return;
+ }
+ }
+
+ /** @type {sglrReferenceContext.Attachment} */ var fboAttachment = new sglrReferenceContext.Attachment();
+
+ if (texture) {
+ fboAttachment.type = sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE;
+ fboAttachment.object = texture;
+ fboAttachment.texTarget = fboTexTarget;
+ fboAttachment.level = level;
+ }
+ framebufferBinding.setAttachment(point, fboAttachment);
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} attachment
+ * @param {sglrReferenceContext.TextureContainer} texture
+ * @param {number} level
+ * @param {number} layer
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.framebufferTextureLayer = function(target, attachment, texture, level, layer) {
+ if (attachment == gl.DEPTH_STENCIL_ATTACHMENT) {
+ // Attach to both depth and stencil.
+ this.framebufferTextureLayer(target, gl.DEPTH_ATTACHMENT, texture, level, layer);
+ this.framebufferTextureLayer(target, gl.STENCIL_ATTACHMENT, texture, level, layer);
+ } else {
+ /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.mapGLAttachmentPoint(attachment);
+
+ if (this.conditionalSetError(target != gl.FRAMEBUFFER &&
+ target != gl.DRAW_FRAMEBUFFER &&
+ target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(point === undefined, gl.INVALID_ENUM))
+ return;
+
+ // Select binding point.
+ /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding;
+ if (this.conditionalSetError(!framebufferBinding, gl.INVALID_OPERATION))
+ return;
+
+ if (texture) {
+ if (this.conditionalSetError(level != 0, gl.INVALID_VALUE))
+ return;
+
+ if (this.conditionalSetError(texture.getType() != sglrReferenceContext.TextureType.TYPE_2D_ARRAY &&
+ texture.getType() != sglrReferenceContext.TextureType.TYPE_3D &&
+ texture.getType() != sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY, gl.INVALID_OPERATION))
+ return;
+
+ if (texture.getType() == sglrReferenceContext.TextureType.TYPE_2D_ARRAY || texture.getType() == sglrReferenceContext.TextureType.TYPE_CUBE_MAP_ARRAY) {
+ if (this.conditionalSetError((layer < 0) || (layer >= gl.MAX_ARRAY_TEXTURE_LAYERS), gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError((level < 0) || (level > Math.floor(Math.log2(gl.MAX_TEXTURE_SIZE))), gl.INVALID_VALUE))
+ return;
+ } else if (texture.getType() == sglrReferenceContext.TextureType.TYPE_3D) {
+ if (this.conditionalSetError((layer < 0) || (layer >= gl.MAX_3D_TEXTURE_SIZE), gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError((level < 0) || (level > Math.floor(Math.log2(gl.MAX_3D_TEXTURE_SIZE))), gl.INVALID_VALUE))
+ return;
+ }
+ }
+
+ /** @type {sglrReferenceContext.Attachment} */ var fboAttachment = new sglrReferenceContext.Attachment();
+
+ if (texture) {
+ fboAttachment.type = sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_TEXTURE;
+ fboAttachment.object = texture;
+ fboAttachment.texTarget = sglrReferenceContext.texLayeredTypeToTarget(texture.getType());
+ fboAttachment.level = level;
+ fboAttachment.layer = layer;
+ }
+ framebufferBinding.setAttachment(point, fboAttachment);
+
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} attachment
+ * @param {number} renderbuffertarget
+ * @param {sglrReferenceContext.Renderbuffer} renderbuffer
+ */
+ sglrReferenceContext.ReferenceContext.prototype.framebufferRenderbuffer = function(target, attachment, renderbuffertarget, renderbuffer) {
+ if (attachment == gl.DEPTH_STENCIL_ATTACHMENT) {
+ // Attach both to depth and stencil.
+ this.framebufferRenderbuffer(target, gl.DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer);
+ this.framebufferRenderbuffer(target, gl.STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer);
+ } else {
+ /** @type {sglrReferenceContext.AttachmentPoint} */ var point = sglrReferenceContext.mapGLAttachmentPoint(attachment);
+
+ if (this.conditionalSetError(target != gl.FRAMEBUFFER &&
+ target != gl.DRAW_FRAMEBUFFER &&
+ target != gl.READ_FRAMEBUFFER, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(point == undefined, gl.INVALID_ENUM))
+ return;
+
+ // Select binding point.
+ /** @type {sglrReferenceContext.Framebuffer} */ var framebufferBinding = (target == gl.FRAMEBUFFER || target == gl.DRAW_FRAMEBUFFER) ? this.m_drawFramebufferBinding : this.m_readFramebufferBinding;
+ if (this.conditionalSetError(!framebufferBinding, gl.INVALID_OPERATION))
+ return;
+
+ if (renderbuffer) {
+ if (this.conditionalSetError(renderbuffertarget != gl.RENDERBUFFER, gl.INVALID_ENUM))
+ return;
+ }
+
+ /** @type {sglrReferenceContext.Attachment} */ var fboAttachment = new sglrReferenceContext.Attachment();
+
+ if (renderbuffer) {
+ fboAttachment.type = sglrReferenceContext.AttachmentType.ATTACHMENTTYPE_RENDERBUFFER;
+ fboAttachment.object = renderbuffer;
+ }
+ framebufferBinding.setAttachment(point, fboAttachment);
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} internalformat
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.ReferenceContext.prototype.renderbufferStorage = function(target, internalformat, width, height) {
+ /** @type {tcuTexture.TextureFormat} */ var format = gluTextureUtil.mapGLInternalFormat(internalformat);
+
+ if (this.conditionalSetError(target != gl.RENDERBUFFER, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError(!this.m_renderbufferBinding, gl.INVALID_OPERATION))
+ return;
+ if (this.conditionalSetError(!deMath.deInRange32(width, 0, this.m_limits.maxRenderbufferSize) ||
+ !deMath.deInRange32(height, 0, this.m_limits.maxRenderbufferSize),
+ gl.INVALID_OPERATION))
+ return;
+ if (this.conditionalSetError(!format, gl.INVALID_ENUM))
+ return;
+
+ this.m_renderbufferBinding.setStorage(format, width, height);
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} samples
+ * @param {number} internalformat
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.ReferenceContext.prototype.renderbufferStorageMultisample = function(target, samples, internalformat, width, height) {
+ this.renderbufferStorage(target, internalformat, width, height);
+ };
+
+ /**
+ * @param {rrRenderer.PrimitiveType} derivedType
+ * @return {rrRenderer.PrimitiveType}
+ * @throws {Error}
+ */
+ sglrReferenceContext.getPrimitiveBaseType = function(derivedType) {
+ switch (derivedType) {
+ case rrRenderer.PrimitiveType.TRIANGLES:
+ case rrRenderer.PrimitiveType.TRIANGLE_STRIP:
+ case rrRenderer.PrimitiveType.TRIANGLE_FAN:
+ return rrRenderer.PrimitiveType.TRIANGLES;
+
+ case rrRenderer.PrimitiveType.LINES:
+ case rrRenderer.PrimitiveType.LINE_STRIP:
+ case rrRenderer.PrimitiveType.LINE_LOOP:
+ return rrRenderer.PrimitiveType.LINES;
+
+ case rrRenderer.PrimitiveType.POINTS:
+ return rrRenderer.PrimitiveType.POINTS;
+
+ default:
+ throw new Error('Unrecognized primitive type:' + derivedType);
+ }
+ };
+
+ /**
+ * createProgram
+ * @param {sglrShaderProgram.ShaderProgram} program
+ * @return {sglrShaderProgram.ShaderProgram}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.createProgram = function(program) {
+ return program;
+ };
+
+ /**
+ * deleteProgram
+ * @param {sglrShaderProgram.ShaderProgram} program
+ */
+ sglrReferenceContext.ReferenceContext.prototype.deleteProgram = function(program) {};
+
+ /**
+ * @param {sglrShaderProgram.ShaderProgram} program
+ */
+ sglrReferenceContext.ReferenceContext.prototype.useProgram = function(program) {
+ this.m_currentProgram = program;
+ };
+
+ /**
+ * Draws quads from vertex arrays
+ * @param {number} primitive GL primitive type to draw with.
+ * @param {number} first First vertex to begin drawing with
+ * @param {number} count How many vertices to draw (not counting vertices before first)
+ */
+ sglrReferenceContext.ReferenceContext.prototype.drawArrays = function(primitive, first, count) {
+ this.drawQuads(primitive, first, count, 1);
+ };
+
+ /**
+ * Draws quads from vertex arrays
+ * @param {number} primitive GL primitive type to draw with.
+ * @param {(number|rrRenderer.DrawIndices)} first First vertex to begin drawing with
+ * @param {number} count Number of vertices
+ * @param {number=} instances Number of instances
+ */
+ sglrReferenceContext.ReferenceContext.prototype.drawQuads = function(primitive, first, count, instances) {
+ // undefined results
+ if (!this.m_currentProgram)
+ return;
+
+ if (typeof instances === 'undefined')
+ instances = 1;
+
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var colorBuf0 = this.getDrawColorbuffer();
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var depthBuf = this.getDrawDepthbuffer();
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var stencilBuf = this.getDrawStencilbuffer();
+ /** @type {boolean} */ var hasStencil = /** @type {!boolean} */ (stencilBuf && !stencilBuf.isEmpty());
+ /** @type {number} */ var stencilBits = (hasStencil) ? stencilBuf.raw().getFormat().getNumStencilBits() : 0;
+
+ /** @type {rrRenderer.RenderTarget} */ var renderTarget = new rrRenderer.RenderTarget(colorBuf0,
+ depthBuf,
+ stencilBuf);
+ /** @type {sglrShaderProgram.ShaderProgram} */ var program = this.m_currentProgram;
+
+ /*new rrRenderer.Program(
+ * this.m_currentProgram.getVertexShader(),
+ * this.m_currentProgram.getFragmentShader());*/
+
+ /** @type {rrRenderState.ViewportState} */ var viewportState = new rrRenderState.ViewportState(colorBuf0);
+ /** @type {rrRenderState.RenderState} */ var state = new rrRenderState.RenderState(viewportState);
+
+ /** @type {Array<rrVertexAttrib.VertexAttrib>} */ var vertexAttribs = [];
+
+ // Gen state
+ /** @type {rrRenderer.PrimitiveType} */ var baseType = rrRenderer.PrimitiveType.TRIANGLES;
+ /** @type {boolean} */ var polygonOffsetEnabled =
+ (baseType == rrRenderer.PrimitiveType.TRIANGLES) ?
+ (this.m_polygonOffsetFillEnabled) :
+ (false);
+
+ //state.cullMode = m_cullMode
+
+ state.fragOps.scissorTestEnabled = this.m_scissorEnabled;
+ state.fragOps.scissorRectangle = new rrRenderState.WindowRectangle(this.m_scissorBox);
+
+ state.fragOps.numStencilBits = stencilBits;
+ state.fragOps.stencilTestEnabled = this.m_stencilTestEnabled;
+
+ for (var key in rrDefs.FaceType) {
+ /** @type {number} */ var faceType = rrDefs.FaceType[key];
+ state.fragOps.stencilStates[faceType].compMask = this.m_stencil[faceType].opMask;
+ state.fragOps.stencilStates[faceType].writeMask = this.m_stencil[faceType].writeMask;
+ state.fragOps.stencilStates[faceType].ref = this.m_stencil[faceType].ref;
+ state.fragOps.stencilStates[faceType].func = sglrReferenceUtils.mapGLTestFunc(this.m_stencil[faceType].func);
+ state.fragOps.stencilStates[faceType].sFail = sglrReferenceUtils.mapGLStencilOp(this.m_stencil[faceType].opStencilFail);
+ state.fragOps.stencilStates[faceType].dpFail = sglrReferenceUtils.mapGLStencilOp(this.m_stencil[faceType].opDepthFail);
+ state.fragOps.stencilStates[faceType].dpPass = sglrReferenceUtils.mapGLStencilOp(this.m_stencil[faceType].opDepthPass);
+ }
+
+ state.fragOps.depthTestEnabled = this.m_depthTestEnabled;
+ state.fragOps.depthFunc = sglrReferenceUtils.mapGLTestFunc(this.m_depthFunc);
+ state.fragOps.depthMask = this.m_depthMask;
+
+ state.fragOps.blendMode = this.m_blendEnabled ? rrRenderState.BlendMode.STANDARD : rrRenderState.BlendMode.NONE;
+ state.fragOps.blendRGBState.equation = sglrReferenceUtils.mapGLBlendEquation(this.m_blendModeRGB);
+ state.fragOps.blendRGBState.srcFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorSrcRGB);
+ state.fragOps.blendRGBState.dstFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorDstRGB);
+ state.fragOps.blendAState.equation = sglrReferenceUtils.mapGLBlendEquation(this.m_blendModeAlpha);
+ state.fragOps.blendAState.srcFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorSrcAlpha);
+ state.fragOps.blendAState.dstFunc = sglrReferenceUtils.mapGLBlendFunc(this.m_blendFactorDstAlpha);
+ state.fragOps.blendColor = this.m_blendColor;
+
+ state.fragOps.colorMask = this.m_colorMask;
+
+ state.viewport.rect = new rrRenderState.WindowRectangle(this.m_viewport);
+ state.viewport.zn = this.m_depthRangeNear;
+ state.viewport.zf = this.m_depthRangeFar;
+
+ //state.point.pointSize = this.m_pointSize;
+ state.line.lineWidth = this.m_lineWidth;
+
+ state.fragOps.polygonOffsetEnabled = polygonOffsetEnabled;
+ state.fragOps.polygonOffsetFactor = this.m_polygonOffsetFactor;
+ state.fragOps.polygonOffsetUnits = this.m_polygonOffsetUnits;
+
+ state.provokingVertexConvention = (this.m_provokingFirstVertexConvention) ? (rrDefs.ProvokingVertex.PROVOKINGVERTEX_FIRST) : (rrDefs.ProvokingVertex.PROVOKINGVERTEX_LAST);
+
+ // gen attributes
+ /** @type {sglrReferenceContext.VertexArray} */ var vao = this.m_vertexArrayBinding;
+ for (var ndx = 0; ndx < vao.m_arrays.length; ++ndx) {
+ vertexAttribs[ndx] = new rrVertexAttrib.VertexAttrib();
+ if (!vao.m_arrays[ndx].enabled) {
+ vertexAttribs[ndx].type = rrVertexAttrib.VertexAttribType.DONT_CARE; // reading with wrong type is allowed, but results are undefined
+ vertexAttribs[ndx].generic = this.m_currentAttribs[ndx];
+ } else {
+ vertexAttribs[ndx].type = (vao.m_arrays[ndx].integer) ?
+ (sglrReferenceUtils.mapGLPureIntegerVertexAttributeType(vao.m_arrays[ndx].type)) :
+ (sglrReferenceUtils.mapGLFloatVertexAttributeType(vao.m_arrays[ndx].type, vao.m_arrays[ndx].normalized, vao.m_arrays[ndx].size));
+ vertexAttribs[ndx].size = sglrReferenceUtils.mapGLSize(vao.m_arrays[ndx].size);
+ vertexAttribs[ndx].stride = vao.m_arrays[ndx].stride;
+ vertexAttribs[ndx].instanceDivisor = vao.m_arrays[ndx].divisor;
+ vertexAttribs[ndx].pointer = vao.m_arrays[ndx].bufferBinding.getData();
+ vertexAttribs[ndx].offset = vao.m_arrays[ndx].offset;
+ vertexAttribs[ndx].componentCount = vao.m_arrays[ndx].size;
+ }
+ }
+
+ // Set shader samplers
+ for (var uniformNdx = 0; uniformNdx < this.m_currentProgram.m_uniforms.length; ++uniformNdx) {
+ /** @type {number} */ var texNdx = this.m_currentProgram.m_uniforms[uniformNdx].value[0];
+
+ switch (this.m_currentProgram.m_uniforms[uniformNdx].type) {
+ case gluShaderUtil.DataType.SAMPLER_2D:
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D:
+ case gluShaderUtil.DataType.INT_SAMPLER_2D: {
+ /** @type {sglrReferenceContext.Texture2D} */ var tex;
+
+ if (texNdx >= 0 && texNdx < this.m_textureUnits.length)
+ tex = /** @type {sglrReferenceContext.Texture2D} */ (this.m_textureUnits[texNdx].tex2DBinding.texture);
+
+ if (tex && tex.isComplete()) {
+ tex.updateView();
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = tex;
+ } else
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTex2D.texture;
+
+ break;
+ }
+ case gluShaderUtil.DataType.SAMPLER_CUBE:
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE:
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE: {
+ /** @type {sglrReferenceContext.TextureCube} */ var texCube;
+
+ if (texNdx >= 0 && texNdx < this.m_textureUnits.length)
+ texCube = /** @type {sglrReferenceContext.TextureCube} */ (this.m_textureUnits[texNdx].texCubeBinding.texture);
+
+ if (texCube && texCube.isComplete()) {
+ texCube.updateView();
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = texCube;
+ } else
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTexCube.texture;
+
+ break;
+ }
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY: {
+ /** @type {sglrReferenceContext.Texture2DArray} */ var tex2DArray;
+
+ if (texNdx >= 0 && texNdx < this.m_textureUnits.length)
+ tex2DArray = /** @type {sglrReferenceContext.Texture2DArray} */ (this.m_textureUnits[texNdx].tex2DArrayBinding.texture);
+
+ if (tex2DArray && tex2DArray.isComplete()) {
+ tex2DArray.updateView();
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = tex2DArray;
+ } else
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTex2DArray.texture;
+
+ break;
+ }
+ case gluShaderUtil.DataType.SAMPLER_3D:
+ case gluShaderUtil.DataType.UINT_SAMPLER_3D:
+ case gluShaderUtil.DataType.INT_SAMPLER_3D: {
+ /** @type {sglrReferenceContext.Texture3D} */ var tex3D;
+
+ if (texNdx >= 0 && texNdx < this.m_textureUnits.length)
+ tex3D = /** @type {sglrReferenceContext.Texture3D} */ (this.m_textureUnits[texNdx].tex3DBinding.texture);
+
+ if (tex3D && tex3D.isComplete()) {
+ tex3D.updateView();
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = tex3D;
+ } else
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler = this.m_emptyTex3D.texture;
+
+ break;
+ }
+ /* TODO: Port
+ case gluShaderUtil.DataType.SAMPLER_CUBE_ARRAY:
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE_ARRAY:
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE_ARRAY:{
+ rc::TextureCubeArray* tex = DE_NULL;
+
+ if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.length)
+ tex = (this.m_textureUnits[texNdx].texCubeArrayBinding) ? (this.m_textureUnits[texNdx].texCubeArrayBinding) : (&this.m_textureUnits[texNdx].defaultCubeArrayTex);
+
+ if (tex && tex.isComplete()) {
+ tex.updateView();
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler.texCubeArray = tex;
+ } else
+ this.m_currentProgram.m_uniforms[uniformNdx].sampler.texCubeArray = &this.m_emptyTexCubeArray;
+
+ break;
+ }
+ */
+ default:
+ // nothing
+ break;
+ }
+ }
+
+ var primitiveType = sglrReferenceUtils.mapGLPrimitiveType(primitive);
+
+ var renderFunction = rrRenderer.drawTriangles;
+ if (primitiveType == rrRenderer.PrimitiveType.LINES ||
+ primitiveType == rrRenderer.PrimitiveType.LINE_STRIP ||
+ primitiveType == rrRenderer.PrimitiveType.LINE_LOOP)
+ renderFunction = rrRenderer.drawLines;
+ else if (primitiveType == rrRenderer.PrimitiveType.POINTS)
+ renderFunction = rrRenderer.drawPoints;
+
+ for (var instanceID = 0; instanceID < instances; instanceID++)
+ renderFunction(state, renderTarget, program, vertexAttribs, primitiveType, first, count, instanceID);
+ };
+
+ /**
+ * @param {Array<number>} rect
+ * @return {boolean}
+ */
+ sglrReferenceContext.isEmpty = function(rect) { return rect[2] == 0 || rect[3] == 0; };
+
+ /**
+ * @param {number} mask
+ * @param {Array<number>} srcRect
+ * @param {Array<number>} dstRect
+ * @param {boolean} flipX
+ * @param {boolean} flipY
+ * @throws {Error}
+ */
+ sglrReferenceContext.ReferenceContext.prototype.blitResolveMultisampleFramebuffer = function(mask, srcRect, dstRect, flipX, flipY) {
+ throw new Error('Unimplemented');
+ };
+
+ /**
+ * @param {number} srcX0
+ * @param {number} srcY0
+ * @param {number} srcX1
+ * @param {number} srcY1
+ * @param {number} dstX0
+ * @param {number} dstY0
+ * @param {number} dstX1
+ * @param {number} dstY1
+ * @param {number} mask
+ * @param {number} filter
+ */
+ sglrReferenceContext.ReferenceContext.prototype.blitFramebuffer = function(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) {
+ // p0 in inclusive, p1 exclusive.
+ // Negative width/height means swap.
+ /** @type {boolean} */ var swapSrcX = srcX1 < srcX0;
+ /** @type {boolean} */ var swapSrcY = srcY1 < srcY0;
+ /** @type {boolean} */ var swapDstX = dstX1 < dstX0;
+ /** @type {boolean} */ var swapDstY = dstY1 < dstY0;
+ /** @type {number} */ var srcW = Math.abs(srcX1 - srcX0);
+ /** @type {number} */ var srcH = Math.abs(srcY1 - srcY0);
+ /** @type {number} */ var dstW = Math.abs(dstX1 - dstX0);
+ /** @type {number} */ var dstH = Math.abs(dstY1 - dstY0);
+ /** @type {boolean} */ var scale = srcW != dstW || srcH != dstH;
+ /** @type {number} */ var srcOriginX = swapSrcX ? srcX1 : srcX0;
+ /** @type {number} */ var srcOriginY = swapSrcY ? srcY1 : srcY0;
+ /** @type {number} */ var dstOriginX = swapDstX ? dstX1 : dstX0;
+ /** @type {number} */ var dstOriginY = swapDstY ? dstY1 : dstY0;
+ /** @type {Array<number>} */ var srcRect = [srcOriginX, srcOriginY, srcW, srcH];
+ /** @type {Array<number>} */ var dstRect = [dstOriginX, dstOriginY, dstW, dstH];
+
+ if (this.conditionalSetError(filter != gl.NEAREST && filter != gl.LINEAR, gl.INVALID_ENUM))
+ return;
+ if (this.conditionalSetError((mask & (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) != 0 && filter != gl.NEAREST, gl.INVALID_OPERATION))
+ return;
+
+ // Validate that both targets are complete.
+ if (this.conditionalSetError(this.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
+ this.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE, gl.INVALID_OPERATION))
+ return;
+
+ // Check samples count is valid
+ if (this.conditionalSetError(this.getDrawColorbuffer().getNumSamples() != 1, gl.INVALID_OPERATION))
+ return;
+
+ // Check size restrictions of multisampled case
+ if (this.getReadColorbuffer().getNumSamples() != 1) {
+ // Src and Dst rect dimensions must be the same
+ if (this.conditionalSetError(srcW != dstW || srcH != dstH, gl.INVALID_OPERATION))
+ return;
+
+ // sglrReferenceContext.Framebuffer formats must match
+ if (mask & gl.COLOR_BUFFER_BIT)
+ if (this.conditionalSetError(this.getReadColorbuffer().raw().getFormat() != this.getDrawColorbuffer().raw().getFormat(), gl.INVALID_OPERATION))
+ return;
+ if (mask & gl.DEPTH_BUFFER_BIT)
+ if (this.conditionalSetError(this.getReadDepthbuffer().raw().getFormat() != this.getDrawDepthbuffer().raw().getFormat(), gl.INVALID_OPERATION))
+ return;
+ if (mask & gl.STENCIL_BUFFER_BIT)
+ if (this.conditionalSetError(this.getReadStencilbuffer().raw().getFormat() != this.getDrawStencilbuffer().raw().getFormat(), gl.INVALID_OPERATION))
+ return;
+ }
+
+ // Compute actual source rect.
+ srcRect = (mask & gl.COLOR_BUFFER_BIT) ? deMath.intersect(srcRect, sglrReferenceContext.getBufferRect(this.getReadColorbuffer())) : srcRect;
+ srcRect = (mask & gl.DEPTH_BUFFER_BIT) ? deMath.intersect(srcRect, sglrReferenceContext.getBufferRect(this.getReadDepthbuffer())) : srcRect;
+ srcRect = (mask & gl.STENCIL_BUFFER_BIT) ? deMath.intersect(srcRect, sglrReferenceContext.getBufferRect(this.getReadStencilbuffer())) : srcRect;
+
+ // Compute destination rect.
+ dstRect = (mask & gl.COLOR_BUFFER_BIT) ? deMath.intersect(dstRect, sglrReferenceContext.getBufferRect(this.getDrawColorbuffer())) : dstRect;
+ dstRect = (mask & gl.DEPTH_BUFFER_BIT) ? deMath.intersect(dstRect, sglrReferenceContext.getBufferRect(this.getDrawDepthbuffer())) : dstRect;
+ dstRect = (mask & gl.STENCIL_BUFFER_BIT) ? deMath.intersect(dstRect, sglrReferenceContext.getBufferRect(this.getDrawStencilbuffer())) : dstRect;
+ dstRect = this.m_scissorEnabled ? deMath.intersect(dstRect, this.m_scissorBox) : dstRect;
+
+ if (sglrReferenceContext.isEmpty(srcRect) || sglrReferenceContext.isEmpty(dstRect))
+ return; // Don't attempt copy.
+
+ // Multisampled read buffer is a special case
+ if (this.getReadColorbuffer().getNumSamples() != 1) {
+ /** @type {boolean} */ var swapX = swapSrcX ^ swapDstX ? true : false;
+ /** @type {boolean} */ var swapY = swapSrcY ^ swapDstY ? true : false;
+ var error = this.blitResolveMultisampleFramebuffer(mask, srcRect, dstRect, swapX, swapY);
+
+ if (error != gl.NO_ERROR)
+ this.setError(error);
+
+ return;
+ }
+
+ // \note Multisample pixel buffers can now be accessed like non-multisampled because multisample read buffer case is already handled. => sample count must be 1
+
+ // Coordinate transformation:
+ // Dst offset space -> dst rectangle space -> src rectangle space -> src offset space.
+ /** @type {tcuMatrix.Matrix} */ var matrix = tcuMatrixUtil.translationMatrix([srcX0 - srcRect[0], srcY0 - srcRect[1]]);
+ matrix = tcuMatrix.multiply(matrix, tcuMatrix.matrixFromVector(3, 3, [(srcX1 - srcX0) / (dstX1 - dstX0), (srcY1 - srcY0) / (dstY1 - dstY0), 1]));
+ matrix = tcuMatrix.multiply(matrix, tcuMatrixUtil.translationMatrix([dstRect[0] - dstX0, dstRect[1] - dstY0]));
+
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @return {number}
+ */
+ var transform = function(x, y) { return matrix.get(x, y); };
+
+ /** @type {number} */ var dX;
+ /** @type {number} */ var dY;
+ /** @type {number} */ var sX;
+ /** @type {number} */ var sY;
+ /** @type {tcuTexture.PixelBufferAccess|rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src;
+ /** @type {tcuTexture.PixelBufferAccess|rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var dst;
+
+ if (mask & gl.COLOR_BUFFER_BIT) {
+ src = tcuTextureUtil.getSubregion(this.getReadColorbuffer().toSinglesampleAccess(), srcRect[0], srcRect[1], 0, srcRect[2], srcRect[3], 1);
+ dst = tcuTextureUtil.getSubregion(this.getDrawColorbuffer().toSinglesampleAccess(), dstRect[0], dstRect[1], 0, dstRect[2], dstRect[3], 1);
+ /** @type {tcuTexture.TextureChannelClass} */ var dstClass = tcuTexture.getTextureChannelClass(dst.getFormat().type);
+ /** @type {boolean} */ var dstIsFloat = dstClass == tcuTexture.TextureChannelClass.FLOATING_POINT ||
+ dstClass == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT ||
+ dstClass == tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT;
+ /** @type {tcuTexture.FilterMode} */ var sFilter = (scale && filter == gl.LINEAR) ? tcuTexture.FilterMode.LINEAR : tcuTexture.FilterMode.NEAREST;
+ /** @type {tcuTexture.Sampler} */ var sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ sFilter, sFilter, 0.0 /* lod threshold */, false /* non-normalized coords */);
+ /** @type {boolean} */ var srcIsSRGB = src.getFormat().order == tcuTexture.ChannelOrder.sRGB || src.getFormat().order == tcuTexture.ChannelOrder.sRGBA;
+ /** @type {boolean} */ var dstIsSRGB = dst.getFormat().order == tcuTexture.ChannelOrder.sRGB || dst.getFormat().order == tcuTexture.ChannelOrder.sRGBA;
+ /** @type {boolean} */ var convertSRGB = this.m_sRGBUpdateEnabled;
+
+ // \note We don't check for unsupported conversions, unlike spec requires.
+
+ for (var yo = 0; yo < dstRect[3]; yo++) {
+ for (var xo = 0; xo < dstRect[2]; xo++) {
+ dX = xo + 0.5;
+ dY = yo + 0.5;
+
+ // \note Only affine part is used.
+ sX = transform(0, 0) * dX + transform(0, 1) * dY + transform(0, 2);
+ sY = transform(1, 0) * dX + transform(1, 1) * dY + transform(1, 2);
+
+ // do not copy pixels outside the modified source region (modified by buffer intersection)
+ if (sX < 0.0 || sX >= srcRect[2] ||
+ sY < 0.0 || sY >= srcRect[3])
+ continue;
+
+ if (dstIsFloat || srcIsSRGB || filter == tcuTexture.FilterMode.LINEAR) {
+ /** @type {Array<number>} */ var p = src.sample2D(sampler, sampler.minFilter, sX, sY, 0);
+ dst.setPixel((dstIsSRGB && convertSRGB) ? tcuTextureUtil.linearToSRGB(p) : p, xo, yo);
+ } else
+ dst.setPixelInt(src.getPixelInt(Math.floor(sX), Math.floor(sY)), xo, yo);
+ }
+ }
+ }
+
+ if ((mask & gl.DEPTH_BUFFER_BIT) && this.m_depthMask) {
+ src = this.getReadDepthbuffer().getSubregion(srcRect);
+ dst = this.getDrawDepthbuffer().getSubregion(dstRect);
+
+ for (var yo = 0; yo < dstRect[3]; yo++) {
+ for (var xo = 0; xo < dstRect[2]; xo++) {
+ var sampleNdx = 0; // multisample read buffer case is already handled
+
+ dX = xo + 0.5;
+ dY = yo + 0.5;
+ sX = transform(0, 0) * dX + transform(0, 1) * dY + transform(0, 2);
+ sY = transform(1, 0) * dX + transform(1, 1) * dY + transform(1, 2);
+
+ sglrReferenceContext.writeDepthOnly(dst, sampleNdx, xo, yo, src.raw().getPixel(sampleNdx, Math.floor(sX), Math.floor(sY))[0]);
+ }
+ }
+ }
+
+ if (mask & gl.STENCIL_BUFFER_BIT) {
+ src = this.getReadStencilbuffer().getSubregion(srcRect);
+ dst = this.getDrawStencilbuffer().getSubregion(dstRect);
+
+ for (var yo = 0; yo < dstRect[3]; yo++) {
+ for (var xo = 0; xo < dstRect[2]; xo++) {
+ var sampleNdx = 0; // multisample read buffer case is already handled
+
+ dX = xo + 0.5;
+ dY = yo + 0.5;
+ sX = transform(0, 0) * dX + transform(0, 1) * dY + transform(0, 2);
+ sY = transform(1, 0) * dX + transform(1, 1) * dY + transform(1, 2);
+
+ 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);
+ }
+ }
+ }
+ };
+
+ /**
+ * @param {number} internalFormat
+ * @return {tcuTexture.TextureFormat}
+ */
+ sglrReferenceContext.mapInternalFormat = function(internalFormat) {
+ switch (internalFormat) {
+ case gl.ALPHA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.A, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.LUMINANCE: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.L, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.LUMINANCE_ALPHA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.LA, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.RGB: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGB, tcuTexture.ChannelType.UNORM_INT8);
+ case gl.RGBA: return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8);
+
+ default:
+ return gluTextureUtil.mapGLInternalFormat(internalFormat);
+ }
+ };
+
+ /**
+ * @param {tcuTexture.PixelBufferAccess} dst
+ * @param {tcuTexture.ConstPixelBufferAccess} src
+ */
+ sglrReferenceContext.depthValueFloatClampCopy = function(dst, src) {
+ /** @type {number} */ var width = dst.getWidth();
+ /** @type {number} */ var height = dst.getHeight();
+ /** @type {number} */ var depth = dst.getDepth();
+
+ DE_ASSERT(src.getWidth() == width && src.getHeight() == height && src.getDepth() == depth);
+
+ // clamping copy
+ for (var z = 0; z < depth; z++)
+ for (var y = 0; y < height; y++)
+ for (var x = 0; x < width; x++) {
+ /** @type {Array<number>} */ var data = src.getPixel(x, y, z);
+ dst.setPixel([deMath.clamp(data[0], 0.0, 1.0), data[1], data[2], data[3]], x, y, z);
+ }
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} level
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.ReferenceContext.prototype.texImage2DDelegate = function (target, level, internalFormat, width, height) {
+ var format;
+ var dataType;
+
+ switch (internalFormat)
+ {
+ case gl.ALPHA:
+ case gl.LUMINANCE:
+ case gl.LUMINANCE_ALPHA:
+ case gl.RGB:
+ case gl.RGBA:
+ format = internalFormat;
+ dataType = GL.UNSIGNED_BYTE;
+ break;
+ default:
+ {
+ var transferFmt = gluTextureUtil.getTransferFormat(gluTextureUtil.mapGLInternalFormat(internalFormat));
+ format = transferFmt.format;
+ dataType = transferFmt.dataType;
+ break;
+ }
+ }
+ this.texImage2D(target, level, internalFormat, width, height, 0, format, dataType, null);
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} level
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} border
+ * @param {number} format
+ * @param {number} type
+ * @param {number} pixels
+ */
+ sglrReferenceContext.ReferenceContext.prototype.texImage2D = function(target, level, internalFormat, width, height, border, format, type, pixels) {
+ this.texImage3D(target, level, internalFormat, width, height, 1, border, format, type, pixels);
+ };
+
+ sglrReferenceContext.ReferenceContext.prototype.texImage3D = function(target, level, internalFormat, width, height, depth, border, format, type, pixels) {
+ /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture];
+ /** @type {ArrayBuffer} */ var data = null;
+ /** @type {number} */ var offset = 0;
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst;
+ /** @type {tcuTexture.ConstPixelBufferAccess} */ var src;
+ if (this.m_pixelUnpackBufferBinding) {
+ if (this.conditionalSetError(typeof pixels !== 'number', gl.INVALID_VALUE))
+ return;
+ data = this.m_pixelUnpackBufferBinding.getData();
+ offset = pixels;
+ } else if (pixels) {
+ if (pixels instanceof ArrayBuffer) {
+ data = pixels;
+ offset = 0;
+ } else {
+ data = pixels.buffer;
+ offset = pixels.byteOffset;
+ }
+ }
+ /** @type {boolean} */ var isDstFloatDepthFormat = (internalFormat == gl.DEPTH_COMPONENT32F || internalFormat == gl.DEPTH32F_STENCIL8); // depth components are limited to [0,1] range
+
+ if (this.conditionalSetError(border != 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(width < 0 || height < 0 || depth < 0 || level < 0, gl.INVALID_VALUE))
+ return;
+
+ // Map storage format.
+ /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat);
+ if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM))
+ return;
+
+ // Map transfer format.
+ /** @type {tcuTexture.TextureFormat} */ var transferFmt = gluTextureUtil.mapGLTransferFormat(format, type);
+ if (this.conditionalSetError(!transferFmt, gl.INVALID_ENUM))
+ return;
+
+ if (target == gl.TEXTURE_2D) {
+ // Validate size and level.
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize || depth != 1, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.log2(this.m_limits.maxTexture2DSize), gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture2D} */
+ var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture);
+
+ if (texture.isImmutable()) {
+ if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_OPERATION))
+ return;
+
+ //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level));
+ dst = texture.getLevel(level);
+
+ if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) ||
+ width != dst.getWidth() ||
+ height != dst.getHeight(), gl.INVALID_OPERATION))
+ return;
+ } else
+ texture.allocLevel(level, storageFmt, width, height);
+
+ if (data) {
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ rowPitch: rowPitch,
+ data: data,
+ offset: offset + skip});
+
+ //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level));
+ dst = texture.getLevel(level);
+
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(dst, src);
+ else
+ tcuTextureUtil.copy(dst, src);
+ } else {
+ // No data supplied, clear to black.
+
+ //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level));
+ dst = texture.getLevel(level);
+ dst.clear([0.0, 0.0, 0.0, 1.0]);
+ }
+ } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) {
+ // Validate size and level.
+ if (this.conditionalSetError(width != height || width > this.m_limits.maxTextureCubeSize || depth != 1, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTextureCubeSize)), gl.INVALID_VALUE))
+ return;
+
+ var textureCube = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture);
+
+ var face = sglrReferenceContext.mapGLCubeFace(target);
+
+ if (textureCube.isImmutable()) {
+ if (this.conditionalSetError(!textureCube.hasFace(level, face), gl.INVALID_OPERATION))
+ return;
+
+ dst = textureCube.getFace(level, face);
+
+ if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) ||
+ width != dst.getWidth() ||
+ height != dst.getHeight(), gl.INVALID_OPERATION))
+ return;
+ } else
+ textureCube.allocLevel(level, face, storageFmt, width, height);
+
+ if (data) {
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ rowPitch: rowPitch,
+ data: data,
+ offset: offset + skip});
+
+ dst = textureCube.getFace(level, face);
+
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(dst, src);
+ else
+ tcuTextureUtil.copy(dst, src);
+ } else {
+ // No data supplied, clear to black.
+ dst = textureCube.getFace(level, face);
+ dst.clear([0.0, 0.0, 0.0, 1.0]);
+ }
+ } else if (target == gl.TEXTURE_2D_ARRAY) {
+ // Validate size and level.
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize ||
+ height > this.m_limits.maxTexture2DSize ||
+ depth > this.m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture2DSize)), gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture2DArray} */
+ var texture2DArray = /** @type {sglrReferenceContext.Texture2DArray} */ (unit.tex2DArrayBinding.texture);
+
+ if (texture2DArray.isImmutable()) {
+ if (this.conditionalSetError(!texture2DArray.hasLevel(level), gl.INVALID_OPERATION))
+ return;
+
+ dst = texture2DArray.getLevel(level);
+ if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) ||
+ width != dst.getWidth() ||
+ height != dst.getHeight() ||
+ depth != dst.getDepth(), gl.INVALID_OPERATION))
+ return;
+ } else
+ texture2DArray.allocLevel(level, storageFmt, width, height, depth);
+
+ if (data) {
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var slicePitch = imageHeight * rowPitch;
+ var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch +
+ this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ depth: depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: offset + skip});
+
+ dst = texture2DArray.getLevel(level);
+
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(dst, src);
+ else
+ tcuTextureUtil.copy(dst, src);
+ } else {
+ // No data supplied, clear to black.
+ dst = texture2DArray.getLevel(level);
+ dst.clear([0.0, 0.0, 0.0, 1.0]);
+ }
+ } else if (target == gl.TEXTURE_3D) {
+ // Validate size and level.
+ if (this.conditionalSetError(width > this.m_limits.maxTexture3DSize ||
+ height > this.m_limits.maxTexture3DSize ||
+ depth > this.m_limits.maxTexture3DSize, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture3DSize)), gl.INVALID_VALUE))
+ return;
+
+ var texture3D = /** @type {sglrReferenceContext.Texture3D} */ (unit.tex3DBinding.texture);
+
+ if (texture3D.isImmutable()) {
+ if (this.conditionalSetError(!texture3D.hasLevel(level), gl.INVALID_OPERATION))
+ return;
+
+ dst = texture3D.getLevel(level);
+ if (this.conditionalSetError(!storageFmt.isEqual(dst.getFormat()) ||
+ width != dst.getWidth() ||
+ height != dst.getHeight() ||
+ depth != dst.getDepth(), gl.INVALID_OPERATION))
+ return;
+ } else
+ texture3D.allocLevel(level, storageFmt, width, height, depth);
+
+ if (data) {
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var slicePitch = imageHeight * rowPitch;
+ var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch +
+ this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ depth: depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: offset + skip});
+
+ dst = texture3D.getLevel(level);
+
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(dst, src);
+ else
+ tcuTextureUtil.copy(dst, src);
+
+ } else {
+ // No data supplied, clear to black.
+ dst = texture3D.getLevel(level);
+ dst.clear([0.0, 0.0, 0.0, 1.0]);
+ }
+ }
+ // else if (target == gl.TEXTURE_CUBE_MAP_ARRAY)
+ // {
+ // // Validate size and level.
+ // RC_IF_ERROR(width != height ||
+ // width > m_limits.maxTexture2DSize ||
+ // depth % 6 != 0 ||
+ // depth > m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE, RC_RET_VOID);
+ // RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), gl.INVALID_VALUE, RC_RET_VOID);
+
+ // TextureCubeArray* texture = unit.texCubeArrayBinding ? unit.texCubeArrayBinding : &unit.defaultCubeArrayTex;
+
+ // if (texture->isImmutable())
+ // {
+ // RC_IF_ERROR(!texture->hasLevel(level), gl.INVALID_OPERATION, RC_RET_VOID);
+
+ // ConstPixelBufferAccess dst(texture->getLevel(level));
+ // RC_IF_ERROR(storageFmt != dst.getFormat() ||
+ // width != dst.getWidth() ||
+ // height != dst.getHeight() ||
+ // depth != dst.getDepth(), gl.INVALID_OPERATION, RC_RET_VOID);
+ // }
+ // else
+ // texture->allocLevel(level, storageFmt, width, height, depth);
+
+ // if (unpackPtr)
+ // {
+ // ConstPixelBufferAccess src = getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
+ // PixelBufferAccess dst (texture->getLevel(level));
+
+ // if (isDstFloatDepthFormat)
+ // sglrReferenceContext.depthValueFloatClampCopy(dst, src);
+ // else
+ // tcu::copy(dst, src);
+ // }
+ // else
+ // {
+ // // No data supplied, clear to black.
+ // PixelBufferAccess dst = texture->getLevel(level);
+ // tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+ // }
+ // } /**/
+ else
+ this.setError(gl.INVALID_ENUM);
+ };
+
+ sglrReferenceContext.ReferenceContext.prototype.texSubImage2D = function(target, level, xoffset, yoffset, width, height, format, type, pixels) {
+ this.texSubImage3D(target, level, xoffset, yoffset, 0, width, height, 1, format, type, pixels);
+ };
+
+ sglrReferenceContext.ReferenceContext.prototype.texSubImage3D = function(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) {
+ /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture];
+ /** @type {ArrayBuffer} */ var data = null;
+ /** @type {number} */ var offset = 0;
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst;
+ /** @type {tcuTexture.PixelBufferAccess} */ var sub;
+ /** @type {tcuTexture.ConstPixelBufferAccess} */ var src;
+ /** @type {boolean} */ var isDstFloatDepthFormat;
+ if (this.m_pixelUnpackBufferBinding) {
+ if (this.conditionalSetError(typeof pixels !== 'number', gl.INVALID_VALUE))
+ return;
+ data = this.m_pixelUnpackBufferBinding.getData();
+ offset = pixels;
+ } else if (pixels) {
+ if (pixels instanceof ArrayBuffer) {
+ data = pixels;
+ offset = 0;
+ } else {
+ data = pixels.buffer;
+ offset = pixels.byteOffset;
+ }
+ }
+
+ if (this.conditionalSetError(xoffset < 0 || yoffset < 0 || zoffset < 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(width < 0 || height < 0 || depth < 0 || level < 0, gl.INVALID_VALUE))
+ return;
+
+ // Map transfer format.
+ /** @type {tcuTexture.TextureFormat} */ var transferFmt = gluTextureUtil.mapGLTransferFormat(format, type);
+ if (this.conditionalSetError(!transferFmt, gl.INVALID_ENUM))
+ return;
+
+ if (target == gl.TEXTURE_2D) {
+ // Validate size and level.
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize || depth != 1, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.log2(this.m_limits.maxTexture2DSize), gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture2D} */
+ var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture);
+
+ if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_OPERATION))
+ return;
+
+ //NOTE: replaces this: var dst = tcuTexture.PixelBufferAccess.newFromTextureLevel(texture.getLevel(level));
+ dst = texture.getLevel(level);
+
+ if (this.conditionalSetError(xoffset + width > dst.getWidth() ||
+ yoffset + height > dst.getHeight() ||
+ zoffset + depth > dst.getDepth(),
+ gl.INVALID_VALUE))
+ return;
+
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ rowPitch: rowPitch,
+ data: data,
+ offset: offset + skip});
+
+ sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth);
+ isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range
+
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(sub, src);
+ else
+ tcuTextureUtil.copy(sub, src);
+ } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) {
+ var textureCube = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture);
+
+ var face = sglrReferenceContext.mapGLCubeFace(target);
+
+ if (this.conditionalSetError(!textureCube.hasFace(level, face), gl.INVALID_OPERATION))
+ return;
+
+ dst = textureCube.getFace(level, face);
+
+ if (this.conditionalSetError(xoffset + width > dst.getWidth() ||
+ yoffset + height > dst.getHeight() ||
+ zoffset + depth > dst.getDepth(),
+ gl.INVALID_VALUE))
+ return;
+
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var skip = this.m_pixelUnpackSkipRows * rowPitch + this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ rowPitch: rowPitch,
+ slicePitach: slicePitch,
+ data: data,
+ offset: offset + skip});
+
+ sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth);
+ isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range
+
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(sub, src);
+ else
+ tcuTextureUtil.copy(sub, src);
+ } else if (target == gl.TEXTURE_2D_ARRAY) {
+ // Validate size and level.
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize ||
+ height > this.m_limits.maxTexture2DSize ||
+ depth > this.m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture2DSize)), gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture2DArray} */
+ var texture2DArray = /** @type {sglrReferenceContext.Texture2DArray} */ (unit.tex2DArrayBinding.texture);
+
+ if (this.conditionalSetError(!texture2DArray.hasLevel(level), gl.INVALID_OPERATION))
+ return;
+
+ dst = texture2DArray.getLevel(level);
+ if (this.conditionalSetError(xoffset + width > dst.getWidth() ||
+ yoffset + height > dst.getHeight() ||
+ zoffset + depth > dst.getDepth(),
+ gl.INVALID_VALUE))
+ return;
+
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var slicePitch = imageHeight * rowPitch;
+ var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch +
+ this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ depth: depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: offset + skip});
+
+ sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth);
+ isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range
+
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(sub, src);
+ else
+ tcuTextureUtil.copy(sub, src);
+ } else if (target == gl.TEXTURE_3D) {
+ // Validate size and level.
+ if (this.conditionalSetError(width > this.m_limits.maxTexture3DSize ||
+ height > this.m_limits.maxTexture3DSize ||
+ depth > this.m_limits.maxTexture3DSize, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture3DSize)), gl.INVALID_VALUE))
+ return;
+
+ var texture3D = /** @type {sglrReferenceContext.Texture3D} */ (unit.tex3DBinding.texture);
+
+ if (this.conditionalSetError(!texture3D.hasLevel(level), gl.INVALID_OPERATION))
+ return;
+
+ dst = texture3D.getLevel(level);
+ if (this.conditionalSetError(xoffset + width > dst.getWidth() ||
+ yoffset + height > dst.getHeight() ||
+ zoffset + depth > dst.getDepth(),
+ gl.INVALID_VALUE))
+ return;
+
+ var rowLen = this.m_pixelUnpackRowLength > 0 ? this.m_pixelUnpackRowLength : width;
+ var imageHeight = this.m_pixelUnpackImageHeight > 0 ? this.m_pixelUnpackImageHeight : height;
+ var rowPitch = deMath.deAlign32(rowLen * transferFmt.getPixelSize(), this.m_pixelUnpackAlignment);
+ var slicePitch = imageHeight * rowPitch;
+ var skip = this.m_pixelUnpackSkipImages * slicePitch + this.m_pixelUnpackSkipRows * rowPitch +
+ this.m_pixelUnpackSkipPixels * transferFmt.getPixelSize();
+ src = new tcuTexture.ConstPixelBufferAccess({
+ format: transferFmt,
+ width: width,
+ height: height,
+ depth: depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: offset + skip});
+
+ sub = tcuTextureUtil.getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth);
+
+ isDstFloatDepthFormat = (dst.getFormat().order == tcuTexture.ChannelOrder.D || dst.getFormat().order == tcuTexture.ChannelOrder.DS); // depth components are limited to [0,1] range
+ if (isDstFloatDepthFormat)
+ sglrReferenceContext.depthValueFloatClampCopy(sub, src);
+ else
+ tcuTextureUtil.copy(sub, src);
+ } else
+ this.setError(gl.INVALID_ENUM);
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} level
+ * @param {number} internalFormat
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ * @param {number} border
+ */
+ sglrReferenceContext.ReferenceContext.prototype.copyTexImage2D = function(target, level, internalFormat, x, y, width, height, border) {
+ /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture];
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src = this.getReadColorbuffer();
+
+ if (this.conditionalSetError(border != 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(width < 0 || height < 0 || level < 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(src.isEmpty(), gl.INVALID_OPERATION))
+ return;
+
+ // Map storage format.
+ /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat);
+ if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM))
+ return;
+
+ if (target == gl.TEXTURE_2D) {
+ // Validate size and level.
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTexture2DSize)), gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture2D} */
+ var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture);
+
+ if (texture.isImmutable()) {
+ if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_OPERATION))
+ return;
+
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getLevel(level);
+ if (this.conditionalSetError(storageFmt != dst.getFormat() || width != dst.getWidth() || height != dst.getHeight(), gl.INVALID_OPERATION))
+ return;
+ } else {
+ texture.allocLevel(level, storageFmt, width, height);
+ }
+
+ // Copy from current framebuffer.
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getLevel(level);
+ for (var yo = 0; yo < height; yo++) {
+ for (var xo = 0; xo < width; xo++) {
+ if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth()))
+ continue; // Undefined pixel.
+
+ dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo, yo);
+ }
+ }
+ } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) {
+ // Validate size and level.
+ if (this.conditionalSetError(width != height || width > this.m_limits.maxTextureCubeSize, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(level > Math.floor(Math.log2(this.m_limits.maxTextureCubeSize)), gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.TextureCube} */
+ var texture = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture);
+ var face = sglrReferenceContext.mapGLCubeFace(target);
+
+ if (texture.isImmutable()) {
+ if (this.conditionalSetError(!texture.hasFace(level, face), gl.INVALID_OPERATION))
+ return;
+
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getFace(level, face);
+ if (this.conditionalSetError(storageFmt != dst.getFormat() || width != dst.getWidth() || height != dst.getHeight(), gl.INVALID_OPERATION))
+ return;
+ } else {
+ texture.allocLevel(level, face, storageFmt, width, height);
+ }
+
+ // Copy from current framebuffer.
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getFace(level, face);
+ for (var yo = 0; yo < height; yo++) {
+ for (var xo = 0; xo < width; xo++) {
+ if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth()))
+ continue; // Undefined pixel.
+
+ dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo, yo);
+ }
+ }
+ } else {
+ this.setError(gl.INVALID_ENUM);
+ }
+ }
+
+ /**
+ * @param {number} target
+ * @param {number} level
+ * @param {number} xoffset
+ * @param {number} yoffset
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ */
+ sglrReferenceContext.ReferenceContext.prototype.copyTexSubImage2D = function(target, level, xoffset, yoffset, x, y, width, height) {
+ /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture];
+ /** @type {rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess} */ var src = this.getReadColorbuffer();
+
+ if (this.conditionalSetError(xoffset < 0 || yoffset < 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(width < 0 || height < 0 || level < 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(src.isEmpty(), gl.INVALID_OPERATION))
+ return;
+
+ if (target == gl.TEXTURE_2D) {
+ /** @type {sglrReferenceContext.Texture2D} */
+ var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture);
+
+ if (this.conditionalSetError(!texture.hasLevel(level), gl.INVALID_VALUE))
+ return;
+
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getLevel(level);
+
+ if (this.conditionalSetError(xoffset + width > dst.getWidth() || yoffset + height > dst.getHeight(), gl.INVALID_VALUE))
+ return;
+
+ for (var yo = 0; yo < height; yo++) {
+ for (var xo = 0; xo < width; xo++) {
+ if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth()))
+ continue;
+
+ dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo+xoffset, yo+yoffset);
+ }
+ }
+ } else if (target == gl.TEXTURE_CUBE_MAP_NEGATIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_X ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Y ||
+ target == gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ||
+ target == gl.TEXTURE_CUBE_MAP_POSITIVE_Z) {
+ /** @type {sglrReferenceContext.TextureCube} */
+ var texture = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture);
+ var face = sglrReferenceContext.mapGLCubeFace(target);
+
+ if (this.conditionalSetError(!texture.hasFace(level, face), gl.INVALID_VALUE))
+ return;
+
+ /** @type {tcuTexture.PixelBufferAccess} */ var dst = texture.getFace(level, face);
+
+ if (this.conditionalSetError(xoffset + width > dst.getWidth() || yoffset + height > dst.getHeight(), gl.INVALID_VALUE))
+ return;
+
+ for (var yo = 0; yo < height; yo++) {
+ for (var xo = 0; xo < width; xo++) {
+ if (!deMath.deInBounds32(x+xo, 0, src.raw().getHeight()) || !deMath.deInBounds32(y+yo, 0, src.raw().getDepth()))
+ continue;
+
+ dst.setPixel(src.resolveMultisamplePixel(x+xo, y+yo), xo+xoffset, yo+yoffset);
+ }
+ }
+ } else {
+ this.setError(gl.INVALID_ENUM);
+ }
+ }
+
+ sglrReferenceContext.ReferenceContext.prototype.texStorage3D = function(target, levels, internalFormat, width, height, depth) {
+ /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture];
+
+ if (this.conditionalSetError(width <= 0 || height <= 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(levels < 1 || levels > Math.floor(Math.log2(Math.max(width, height))) + 1, gl.INVALID_VALUE))
+ return;
+
+ // Map storage format.
+ /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat);
+ if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM))
+ return;
+
+ if (target == gl.TEXTURE_2D_ARRAY) {
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize ||
+ height > this.m_limits.maxTexture2DSize ||
+ depth >= this.m_limits.maxTexture2DArrayLayers, gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture2DArray} */
+ var textureArray = /** @type {sglrReferenceContext.Texture2DArray} */ (unit.tex2DArrayBinding.texture);
+ if (this.conditionalSetError(textureArray.isImmutable(), gl.INVALID_OPERATION))
+ return;
+
+ textureArray.clearLevels();
+ textureArray.setImmutable();
+
+ for (var level = 0; level < levels; level++) {
+ var levelW = Math.max(1, width >> level);
+ var levelH = Math.max(1, height >> level);
+
+ textureArray.allocLevel(level, storageFmt, levelW, levelH, depth);
+ }
+ } else if (target == gl.TEXTURE_3D) {
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize ||
+ height > this.m_limits.maxTexture2DSize ||
+ depth >= this.m_limits.maxTexture3DSize, gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture3D} */
+ var texture3D = /** @type {sglrReferenceContext.Texture3D} */ (unit.tex3DBinding.texture);
+ if (this.conditionalSetError(texture3D.isImmutable(), gl.INVALID_OPERATION))
+ return;
+
+ texture3D.clearLevels();
+ texture3D.setImmutable();
+
+ for (var level = 0; level < levels; level++) {
+ var levelW = Math.max(1, width >> level);
+ var levelH = Math.max(1, height >> level);
+ var levelD = Math.max(1, depth >> level);
+
+ texture3D.allocLevel(level, storageFmt, levelW, levelH, levelD);
+ }
+ } else
+ this.setError(gl.INVALID_ENUM);
+ };
+
+ sglrReferenceContext.ReferenceContext.prototype.texStorage2D = function(target, levels, internalFormat, width, height) {
+ /** @type {sglrReferenceContext.TextureUnit} */var unit = this.m_textureUnits[this.m_activeTexture];
+
+ if (this.conditionalSetError(width <= 0 || height <= 0, gl.INVALID_VALUE))
+ return;
+ if (this.conditionalSetError(levels < 1 || levels > Math.floor(Math.log2(Math.max(width, height))) + 1, gl.INVALID_VALUE))
+ return;
+
+ // Map storage format.
+ /** @type {tcuTexture.TextureFormat} */ var storageFmt = sglrReferenceContext.mapInternalFormat(internalFormat);
+ if (this.conditionalSetError(!storageFmt, gl.INVALID_ENUM))
+ return;
+
+ if (target == gl.TEXTURE_2D) {
+ if (this.conditionalSetError(width > this.m_limits.maxTexture2DSize || height > this.m_limits.maxTexture2DSize, gl.INVALID_VALUE))
+ return;
+
+ /** @type {sglrReferenceContext.Texture2D} */
+ var texture = /** @type {sglrReferenceContext.Texture2D} */ (unit.tex2DBinding.texture);
+ if (this.conditionalSetError(texture.isImmutable(), gl.INVALID_OPERATION))
+ return;
+
+ texture.clearLevels();
+ texture.setImmutable();
+
+ for (var level = 0; level < levels; level++) {
+ var levelW = Math.max(1, width >> level);
+ var levelH = Math.max(1, height >> level);
+
+ texture.allocLevel(level, storageFmt, levelW, levelH);
+ }
+ } else if (target == gl.TEXTURE_CUBE_MAP) {
+ if (this.conditionalSetError(width != height || width > this.m_limits.maxTextureCubeSize, gl.INVALID_VALUE))
+ return;
+ var textureCube = /** @type {sglrReferenceContext.TextureCube} */ (unit.texCubeBinding.texture);
+ if (this.conditionalSetError(textureCube.isImmutable(), gl.INVALID_OPERATION))
+ return;
+
+ textureCube.clearLevels();
+ textureCube.setImmutable();
+
+ for (var level = 0; level < levels; level++) {
+ var levelW = Math.max(1, width >> level);
+ var levelH = Math.max(1, height >> level);
+
+ for (var face in tcuTexture.CubeFace)
+ textureCube.allocLevel(level, tcuTexture.CubeFace[face], storageFmt, levelW, levelH);
+ }
+ } else
+ this.setError(gl.INVALID_ENUM);
+ };
+
+ /**
+ * @param {number} value
+ * @return {?tcuTexture.WrapMode}
+ */
+ sglrReferenceContext.mapGLWrapMode = function(value) {
+ switch (value) {
+ case gl.CLAMP_TO_EDGE: return tcuTexture.WrapMode.CLAMP_TO_EDGE;
+ case gl.REPEAT: return tcuTexture.WrapMode.REPEAT_GL;
+ case gl.MIRRORED_REPEAT: return tcuTexture.WrapMode.MIRRORED_REPEAT_GL;
+ }
+ return null;
+ };
+
+ /**
+ * @param {number} value
+ * @return {?tcuTexture.FilterMode}
+ */
+ sglrReferenceContext.mapGLFilterMode = function(value) {
+ switch (value) {
+ case gl.NEAREST: return tcuTexture.FilterMode.NEAREST;
+ case gl.LINEAR: return tcuTexture.FilterMode.LINEAR;
+ case gl.NEAREST_MIPMAP_NEAREST: return tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST;
+ case gl.NEAREST_MIPMAP_LINEAR: return tcuTexture.FilterMode.NEAREST_MIPMAP_LINEAR;
+ case gl.LINEAR_MIPMAP_NEAREST: return tcuTexture.FilterMode.LINEAR_MIPMAP_NEAREST;
+ case gl.LINEAR_MIPMAP_LINEAR: return tcuTexture.FilterMode.LINEAR_MIPMAP_LINEAR;
+ }
+ return null;
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} pname
+ * @param {number} value
+ */
+ sglrReferenceContext.ReferenceContext.prototype.texParameteri = function(target, pname, value) {
+ /** @type {sglrReferenceContext.TextureUnit} */ var unit = this.m_textureUnits[this.m_activeTexture];
+ /** @type {sglrReferenceContext.TextureContainer} */ var container = null;
+
+ switch (target) {
+ case gl.TEXTURE_2D: container = unit.tex2DBinding; break;
+ case gl.TEXTURE_CUBE_MAP: container = unit.texCubeBinding; break;
+ case gl.TEXTURE_2D_ARRAY: container = unit.tex2DArrayBinding; break;
+ case gl.TEXTURE_3D: container = unit.tex3DBinding; break;
+
+ default: this.setError(gl.INVALID_ENUM);
+ }
+
+ if (!container)
+ return;
+
+ /** @type {sglrReferenceContext.Texture} */
+ var texture = container.texture;
+
+ switch (pname) {
+ case gl.TEXTURE_WRAP_S: {
+ /** @type {?tcuTexture.WrapMode} */ var wrapS = sglrReferenceContext.mapGLWrapMode(value);
+ if (this.conditionalSetError(null == wrapS, gl.INVALID_VALUE))
+ return;
+ texture.getSampler().wrapS = /** @type {tcuTexture.WrapMode} */ (wrapS);
+ break;
+ }
+
+ case gl.TEXTURE_WRAP_T: {
+ /** @type {?tcuTexture.WrapMode} */ var wrapT = sglrReferenceContext.mapGLWrapMode(value);
+ if (this.conditionalSetError(null == wrapT, gl.INVALID_VALUE))
+ return;
+ texture.getSampler().wrapT = /** @type {tcuTexture.WrapMode} */ (wrapT);
+ break;
+ }
+
+ case gl.TEXTURE_WRAP_R: {
+ /** @type {?tcuTexture.WrapMode} */ var wrapR = sglrReferenceContext.mapGLWrapMode(value);
+ if (this.conditionalSetError(null == wrapR, gl.INVALID_VALUE))
+ return;
+ texture.getSampler().wrapR = /** @type {tcuTexture.WrapMode} */ (wrapR);
+ break;
+ }
+
+ case gl.TEXTURE_MIN_FILTER: {
+ /** @type {?tcuTexture.FilterMode} */ var minMode = sglrReferenceContext.mapGLFilterMode(value);
+ if (this.conditionalSetError(null == minMode, gl.INVALID_VALUE))
+ return;
+ texture.getSampler().minFilter = /** @type {tcuTexture.FilterMode} */ (minMode);
+ break;
+ }
+
+ case gl.TEXTURE_MAG_FILTER: {
+ /** @type {?tcuTexture.FilterMode} */ var magMode = sglrReferenceContext.mapGLFilterMode(value);
+ if (this.conditionalSetError(null == magMode, gl.INVALID_VALUE))
+ return;
+ texture.getSampler().magFilter = /** @type {tcuTexture.FilterMode} */ (magMode);
+ break;
+ }
+
+ case gl.TEXTURE_MAX_LEVEL: {
+ if (this.conditionalSetError(value < 0, gl.INVALID_VALUE))
+ return;
+ texture.setMaxLevel(value);
+ break;
+ }
+
+ default:
+ this.setError(gl.INVALID_ENUM);
+ return;
+ }
+ };
+
+ sglrReferenceContext.ReferenceContext.prototype.invalidateFramebuffer = function(target, attachments) {};
+ sglrReferenceContext.ReferenceContext.prototype.invalidateSubFramebuffer = function(target, attachments, x, y, width, height) {};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContextTest.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContextTest.js
new file mode 100644
index 0000000000..cc8abf5969
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContextTest.js
@@ -0,0 +1,834 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('framework.opengl.simplereference.sglrReferenceContextTest');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.opengl.simplereference.sglrShaderProgram');
+goog.require('framework.referencerenderer.rrFragmentOperations');
+goog.require('framework.referencerenderer.rrGenericVector');
+goog.require('framework.referencerenderer.rrShadingContext');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+goog.require('framework.referencerenderer.rrVertexPacket');
+
+goog.scope(function() {
+ var sglrReferenceContextTest = framework.opengl.simplereference.sglrReferenceContextTest;
+ var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuLogImage = framework.common.tcuLogImage;
+ var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
+ var rrGenericVector = framework.referencerenderer.rrGenericVector;
+ var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+ var rrShadingContext = framework.referencerenderer.rrShadingContext;
+ var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
+ var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
+ var tcuRGBA = framework.common.tcuRGBA;
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ */
+ sglrReferenceContextTest.ClearContext = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ };
+
+ sglrReferenceContextTest.ClearContext.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ sglrReferenceContextTest.ClearContext.prototype.constructor = sglrReferenceContextTest.ClearContext;
+
+ sglrReferenceContextTest.ClearContext.prototype.init = function() {};
+
+ sglrReferenceContextTest.ClearContext.prototype.iterate = function() {
+
+ var width = 200;
+ var height = 188;
+ var samples = 1;
+ var limits = new sglrReferenceContext.ReferenceContextLimits(gl);
+ var format = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(format, 24, 8, width, height, samples);
+ var ctx = new sglrReferenceContext.ReferenceContext(limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
+ ctx.clearColor(1, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ var pixels = new tcuSurface.Surface(width, height);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ var numFailedPixels = 0;
+ var redPixel = new gluDrawUtil.Pixel([255, 0, 0, 255]);
+ for (var x = 0; x < width; x++)
+ for (var y = 0; y < height; y++) {
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(x, y));
+ if (!pixel.equals(redPixel))
+ numFailedPixels += 1;
+ }
+
+ var access = pixels.getAccess();
+
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ ctx.scissor(width / 4, height / 4, width / 2, height / 2);
+ ctx.enable(gl.SCISSOR_TEST);
+ ctx.clearColor(0, 1, 1, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ numFailedPixels = 0;
+ var greenBluePixel = new gluDrawUtil.Pixel([0, 255, 255, 255]);
+ for (var x = 0; x < width; x++)
+ for (var y = 0; y < height; y++) {
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(x, y));
+ if ((x >= width / 4 && x < width - width / 4) && (y >= height / 4 && y < height - height / 4)) {
+ if (!pixel.equals(greenBluePixel))
+ numFailedPixels += 1;
+ } else
+ if (!pixel.equals(redPixel))
+ numFailedPixels += 1;
+ }
+
+ access = pixels.getAccess();
+
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ */
+ sglrReferenceContextTest.Framebuffer = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ };
+
+ sglrReferenceContextTest.Framebuffer.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ sglrReferenceContextTest.Framebuffer.prototype.constructor = sglrReferenceContextTest.Framebuffer;
+
+ sglrReferenceContextTest.Framebuffer.prototype.init = function() {};
+
+ sglrReferenceContextTest.Framebuffer.prototype.iterate = function() {
+ var limits = new sglrReferenceContext.ReferenceContextLimits(gl);
+ var format = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ var width = 200;
+ var height = 188;
+ var samples = 1;
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(format, 24, 8, width, height, samples);
+ var ctx = new sglrReferenceContext.ReferenceContext(limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
+ ctx.clearColor(0, 0, 1, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ var fbo = ctx.createFramebuffer();
+ var rbo = ctx.createRenderbuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, width, height);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+ bufferedLogToConsole('Framebuffer status: ' + (ctx.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE));
+ ctx.clearColor(1, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ var pixels = new tcuSurface.Surface(width, height);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+ var numFailedPixels = 0;
+ var redPixel = new gluDrawUtil.Pixel([255, 0, 0, 255]);
+ for (var x = 0; x < width; x++)
+ for (var y = 0; y < height; y++) {
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(x, y));
+ if (!pixel.equals(redPixel))
+ numFailedPixels += 1;
+ }
+ var access = pixels.getAccess();
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ ctx.scissor(width / 4, height / 4, width / 2, height / 2);
+ ctx.enable(gl.SCISSOR_TEST);
+ ctx.clearColor(0, 1, 1, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ numFailedPixels = 0;
+ var greenBluePixel = new gluDrawUtil.Pixel([0, 255, 255, 255]);
+ for (var x = 0; x < width; x++)
+ for (var y = 0; y < height; y++) {
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(x, y));
+ if ((x >= width / 4 && x < width - width / 4) && (y >= height / 4 && y < height - height / 4)) {
+ if (!pixel.equals(greenBluePixel))
+ numFailedPixels += 1;
+ } else
+ if (!pixel.equals(redPixel))
+ numFailedPixels += 1;
+ }
+
+ access = pixels.getAccess();
+
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ var bluePixel = new gluDrawUtil.Pixel([0, 0, 255, 255]);
+ for (var x = 0; x < width; x++)
+ for (var y = 0; y < height; y++) {
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(x, y));
+ if (!pixel.equals(bluePixel))
+ numFailedPixels += 1;
+ }
+ access = pixels.getAccess();
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ */
+ sglrReferenceContextTest.Shader = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ };
+
+ sglrReferenceContextTest.Shader.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ sglrReferenceContextTest.Shader.prototype.constructor = sglrReferenceContextTest.Shader;
+
+ sglrReferenceContextTest.Shader.prototype.init = function() {};
+
+ sglrReferenceContextTest.Shader.prototype.iterate = function() {
+ var limits = new sglrReferenceContext.ReferenceContextLimits(gl);
+ var format = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ var width = 200;
+ var height = 188;
+ var samples = 1;
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(format, 24, 8, width, height, samples);
+ var ctx = new sglrReferenceContext.ReferenceContext(limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
+ ctx.clearColor(0, 0, 1, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ var vertices = [
+ -0.5, 0.5,
+ 0.5, 0.5,
+ -0.5, -0.5,
+ 0.5, 0.5,
+ 0.5, -0.5,
+ -0.5, -0.5
+ ];
+
+ var vertices32 = new Float32Array(vertices);
+
+ var squareVerticesBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, vertices32, gl.STATIC_DRAW);
+
+ var colors = [
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1
+ ];
+
+ var colors32 = new Float32Array(colors);
+
+ var squareColorsBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, colors32, gl.STATIC_DRAW);
+
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var progDecl = new sglrShaderProgram.ShaderProgramDeclaration();
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexPosition', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexColor', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexSource(new sglrShaderProgram.VertexSource(''));
+
+ progDecl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushFragmentSource(new sglrShaderProgram.FragmentSource(''));
+
+ /** @type {sglrReferenceContextTest.ContextShaderProgram} */ var program = new sglrReferenceContextTest.ContextShaderProgram(progDecl);
+
+ //Create program
+ ctx.createProgram(program);
+
+ //Use program
+ ctx.useProgram(program);
+
+ var vertexPositionAttribute = ctx.getAttribLocation(program, 'aVertexPosition');
+ var vertexColorAttribute = ctx.getAttribLocation(program, 'aVertexColor');
+ ctx.enableVertexAttribArray(vertexPositionAttribute);
+ ctx.enableVertexAttribArray(vertexColorAttribute);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.vertexAttribPointer(vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
+
+ ctx.drawQuads(gl.TRIANGLES, 0, 6);
+
+ var pixels = new tcuSurface.Surface(width, height);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ var numFailedPixels = 0;
+
+ var redPixel = new gluDrawUtil.Pixel([255, 0, 0, 255]);
+ var bluePixel = new gluDrawUtil.Pixel([0, 0, 255, 255]);
+
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(0, 0));
+ if (!pixel.equals(bluePixel))
+ numFailedPixels += 1;
+
+ pixel = new gluDrawUtil.Pixel(pixels.getPixel(100, 94));
+ if (!pixel.equals(redPixel))
+ numFailedPixels += 1;
+
+ var access = pixels.getAccess();
+
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ */
+ sglrReferenceContextTest.TriangleStrip = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ };
+
+ sglrReferenceContextTest.TriangleStrip.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ sglrReferenceContextTest.TriangleStrip.prototype.constructor = sglrReferenceContextTest.TriangleStrip;
+
+ sglrReferenceContextTest.TriangleStrip.prototype.init = function() {};
+
+ sglrReferenceContextTest.TriangleStrip.prototype.iterate = function() {
+ var limits = new sglrReferenceContext.ReferenceContextLimits(gl);
+ var format = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ var width = 200;
+ var height = 188;
+ var samples = 1;
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(format, 24, 8, width, height, samples);
+ var ctx = new sglrReferenceContext.ReferenceContext(limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
+ ctx.clearColor(0, 0, 1, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ var vertices = [
+ -0.5, 0.5,
+ 0.5, 0.5,
+ -0.5, 0,
+ 0.5, 0,
+ -0.5, -0.5,
+ 0.5, -0.5
+ ];
+
+ var vertices32 = new Float32Array(vertices);
+
+ var squareVerticesBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, vertices32, gl.STATIC_DRAW);
+
+ var colors = [
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1
+ ];
+
+ var colors32 = new Float32Array(colors);
+
+ var squareColorsBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, colors32, gl.STATIC_DRAW);
+
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var progDecl = new sglrShaderProgram.ShaderProgramDeclaration();
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexPosition', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexColor', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexSource(new sglrShaderProgram.VertexSource(''));
+
+ progDecl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushFragmentSource(new sglrShaderProgram.FragmentSource(''));
+
+ /** @type {sglrReferenceContextTest.ContextShaderProgram} */ var program = new sglrReferenceContextTest.ContextShaderProgram(progDecl);
+
+ //Create program
+ ctx.createProgram(program);
+
+ //Use program
+ ctx.useProgram(program);
+
+ var vertexPositionAttribute = ctx.getAttribLocation(program, 'aVertexPosition');
+ var vertexColorAttribute = ctx.getAttribLocation(program, 'aVertexColor');
+ ctx.enableVertexAttribArray(vertexPositionAttribute);
+ ctx.enableVertexAttribArray(vertexColorAttribute);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.vertexAttribPointer(vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
+
+ ctx.drawQuads(gl.TRIANGLE_STRIP, 0, 6);
+
+ var pixels = new tcuSurface.Surface(width, height);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ var numFailedPixels = 0;
+
+ var redPixel = new gluDrawUtil.Pixel([255, 0, 0, 255]);
+ var bluePixel = new gluDrawUtil.Pixel([0, 0, 255, 255]);
+
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(0, 0));
+ if (!pixel.equals(bluePixel))
+ numFailedPixels += 1;
+
+ pixel = new gluDrawUtil.Pixel(pixels.getPixel(100, 94));
+ if (!pixel.equals(redPixel))
+ numFailedPixels += 1;
+
+ var access = pixels.getAccess();
+
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ */
+ sglrReferenceContextTest.TriangleFan = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ };
+
+ sglrReferenceContextTest.TriangleFan.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ sglrReferenceContextTest.TriangleFan.prototype.constructor = sglrReferenceContextTest.TriangleFan;
+
+ sglrReferenceContextTest.TriangleFan.prototype.init = function() {};
+
+ sglrReferenceContextTest.TriangleFan.prototype.iterate = function() {
+ var limits = new sglrReferenceContext.ReferenceContextLimits(gl);
+ var format = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ var width = 200;
+ var height = 188;
+ var samples = 1;
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(format, 24, 8, width, height, samples);
+ var ctx = new sglrReferenceContext.ReferenceContext(limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
+ ctx.clearColor(0, 0, 1, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ var vertices = [
+ -0.5, 0,
+ -0.5, 0.5,
+ 0.5, 0.5,
+ 0.5, 0,
+ 0.5, -0.5,
+ -0.5, -0.5
+ ];
+
+ var vertices32 = new Float32Array(vertices);
+
+ var squareVerticesBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, vertices32, gl.STATIC_DRAW);
+
+ var colors = [
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1,
+ 1, 0, 0, 1
+ ];
+
+ var colors32 = new Float32Array(colors);
+
+ var squareColorsBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, colors32, gl.STATIC_DRAW);
+
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var progDecl = new sglrShaderProgram.ShaderProgramDeclaration();
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexPosition', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexColor', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexSource(new sglrShaderProgram.VertexSource(''));
+
+ progDecl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushFragmentSource(new sglrShaderProgram.FragmentSource(''));
+
+ /** @type {sglrReferenceContextTest.ContextShaderProgram} */ var program = new sglrReferenceContextTest.ContextShaderProgram(progDecl);
+
+ //Create program
+ ctx.createProgram(program);
+
+ //Use program
+ ctx.useProgram(program);
+
+ var vertexPositionAttribute = ctx.getAttribLocation(program, 'aVertexPosition');
+ var vertexColorAttribute = ctx.getAttribLocation(program, 'aVertexColor');
+ ctx.enableVertexAttribArray(vertexPositionAttribute);
+ ctx.enableVertexAttribArray(vertexColorAttribute);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.vertexAttribPointer(vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
+
+ ctx.drawQuads(gl.TRIANGLE_FAN, 0, 6);
+
+ var pixels = new tcuSurface.Surface(width, height);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ var numFailedPixels = 0;
+
+ var redPixel = new gluDrawUtil.Pixel([255, 0, 0, 255]);
+ var bluePixel = new gluDrawUtil.Pixel([0, 0, 255, 255]);
+
+ var pixel = new gluDrawUtil.Pixel(pixels.getPixel(0, 0));
+ if (!pixel.equals(bluePixel))
+ numFailedPixels += 1;
+
+ pixel = new gluDrawUtil.Pixel(pixels.getPixel(100, 94));
+ if (!pixel.equals(redPixel))
+ numFailedPixels += 1;
+
+ var access = pixels.getAccess();
+
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ */
+ sglrReferenceContextTest.DrawElements = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ };
+
+ sglrReferenceContextTest.DrawElements.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ sglrReferenceContextTest.DrawElements.prototype.constructor = sglrReferenceContextTest.DrawElements;
+
+ sglrReferenceContextTest.DrawElements.prototype.init = function() {};
+
+ sglrReferenceContextTest.DrawElements.prototype.iterate = function() {
+ var limits = new sglrReferenceContext.ReferenceContextLimits(gl);
+ var format = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ var width = 200;
+ var height = 188;
+ var samples = 1;
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(format, 24, 8, width, height, samples);
+ var ctx = new sglrReferenceContext.ReferenceContext(limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
+ ctx.clearColor(0, 0, 1, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ var vertices = [
+ -0.5, 0.5,
+ 0, 0.5,
+ 0.4, 0.5,
+
+ -0.5, 0.1,
+ 0, 0.1,
+ 0.4, 0.1,
+
+ -0.5, -0.7,
+ 0, -0.7,
+ 0.4, -0.7
+ ];
+
+ var vertices32 = new Float32Array(vertices);
+
+ var squareVerticesBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, vertices32, gl.STATIC_DRAW);
+
+ var indices = [
+ 0, 1, 3, 1, 3, 4,
+ 1, 2, 4, 2, 4, 5,
+ 3, 4, 6, 4, 6, 7,
+ 4, 5, 7, 5, 7, 8
+ ];
+ var indicesBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
+ ctx.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
+
+ var colors = [
+ 1, 0, 0, 1,
+ 0, 1, 0, 1,
+ 0, 0, 1, 1,
+ 1, 1, 1, 1,
+ 1, 1, 0, 1,
+ 0, 1, 1, 1,
+ 1, 0, 1, 1,
+ 0.5, 0.5, 0.5, 1,
+ 0, 0, 0, 0
+ ];
+
+ var colors32 = new Float32Array(colors);
+
+ var squareColorsBuffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.bufferData(gl.ARRAY_BUFFER, colors32, gl.STATIC_DRAW);
+
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var progDecl = new sglrShaderProgram.ShaderProgramDeclaration();
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexPosition', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('aVertexColor', rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushVertexSource(new sglrShaderProgram.VertexSource(''));
+
+ progDecl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
+
+ progDecl.pushFragmentSource(new sglrShaderProgram.FragmentSource(''));
+
+ /** @type {sglrReferenceContextTest.ContextShaderProgram} */ var program = new sglrReferenceContextTest.ContextShaderProgram(progDecl);
+
+ //Create program
+ ctx.createProgram(program);
+
+ //Use program
+ ctx.useProgram(program);
+
+ var vertexPositionAttribute = ctx.getAttribLocation(program, 'aVertexPosition');
+ var vertexColorAttribute = ctx.getAttribLocation(program, 'aVertexColor');
+ ctx.enableVertexAttribArray(vertexPositionAttribute);
+ ctx.enableVertexAttribArray(vertexColorAttribute);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
+ ctx.vertexAttribPointer(vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+
+ ctx.bindBuffer(gl.ARRAY_BUFFER, squareColorsBuffer);
+ ctx.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
+
+ ctx.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
+
+ var pixels = new tcuSurface.Surface(width, height);
+ ctx.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels.getAccess().getDataPtr());
+
+ var numFailedPixels = 0;
+
+ var access = pixels.getAccess();
+
+ var pixelsTotest = [
+ // location, color
+ [2, 1], [0, 0, 255, 255],
+ // The red vertex is between 140 and 141 so account for some blending with the white vertex
+ [50, 140], [255, 5, 5, 255],
+ [50, 28], [255, 0, 255, 255],
+ [139, 28], [0, 0, 0, 255],
+ [50, 102], [255, 255, 255, 255],
+ [139, 102], [0, 255, 255, 255]
+ ];
+
+ var threshold = new tcuRGBA.RGBA([5, 5, 5, 5]);
+
+ for (var i = 0; i < pixelsTotest.length; i += 2) {
+ var location = pixelsTotest[i];
+ var reference = new tcuRGBA.RGBA(pixelsTotest[i + 1]);
+ var color = access.getPixelInt(location[0], location[1]);
+ var pixel = new tcuRGBA.RGBA(color);
+ if (!tcuRGBA.compareThreshold(pixel, reference, threshold))
+ numFailedPixels++;
+ }
+
+ tcuLogImage.logImage('Result', '', access);
+
+ if (numFailedPixels > 0)
+ testFailedOptions('Image comparison failed, got ' + numFailedPixels + ' non-equal pixels.', false);
+ else
+ testPassedOptions('Image comparison succeed', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {sglrShaderProgram.ShaderProgramDeclaration} progDecl
+ */
+ sglrReferenceContextTest.ContextShaderProgram = function(progDecl) {
+ sglrShaderProgram.ShaderProgram.call(this, progDecl);
+ };
+
+ sglrReferenceContextTest.ContextShaderProgram.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ sglrReferenceContextTest.ContextShaderProgram.prototype.constructor = sglrReferenceContextTest.ContextShaderProgram;
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ sglrReferenceContextTest.ContextShaderProgram.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {number} */ var varyingLocColor = 0;
+
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+
+ // Calc output color
+ /** @type {Array<number>} */ var coord = [1.0, 1.0];
+ /** @type {Array<number>} */ var color = [1.0, 1.0, 1.0];
+
+ for (var attribNdx = 0; attribNdx < this.getVertexShader().getInputs().length; attribNdx++) {
+ /** @type {number} */ var numComponents = inputs[attribNdx].componentCount;
+
+ var attribValue = rrVertexAttrib.readVertexAttrib(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx, this.getVertexShader().getInputs()[attribNdx].type);
+
+ if (attribNdx == 0) {
+ coord[0] = attribValue[0];
+ coord[1] = attribValue[1];
+ } else {
+ color[0] = attribValue[0] * attribValue[3];
+ color[1] = attribValue[1] * attribValue[3];
+ color[2] = attribValue[2] * attribValue[3];
+ }
+ }
+
+ // Transform position
+ packet.position = [coord[0], coord[1], 1.0, 1.0];
+
+ // Pass color to FS
+ packet.outputs[varyingLocColor] = [color[0], color[1], color[2], 1.0];
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packets
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ sglrReferenceContextTest.ContextShaderProgram.prototype.shadeFragments = function(packets, context) {
+ var varyingLocColor = 0;
+
+ // Normal shading
+ for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx)
+ packets[packetNdx].value = rrShadingContext.readTriangleVarying(packets[packetNdx], context, varyingLocColor);
+ };
+
+ sglrReferenceContextTest.init = function() {
+ var state = tcuTestCase.runner;
+ /** @type {tcuTestCase.DeqpTest} */ var testGroup = state.testCases;
+
+ /** @type {tcuTestCase.DeqpTest} */ var referenceContextGroup = tcuTestCase.newTest('reference_context', 'Test reference context');
+
+ referenceContextGroup.addChild(new sglrReferenceContextTest.ClearContext('clear_context', 'Clear Context Test'));
+ referenceContextGroup.addChild(new sglrReferenceContextTest.Framebuffer('Framebuffer', 'Framebuffer Test'));
+ referenceContextGroup.addChild(new sglrReferenceContextTest.Shader('Shaders', 'Drawing using TRIANGLES'));
+ referenceContextGroup.addChild(new sglrReferenceContextTest.TriangleStrip('TriangleStrip', 'Drawing using TRIANGLE_STRIP'));
+ referenceContextGroup.addChild(new sglrReferenceContextTest.TriangleFan('TriangleFan', 'Drawing using TRIANGLE_FAN'));
+ referenceContextGroup.addChild(new sglrReferenceContextTest.DrawElements('DrawElements', 'Drawing using DrawElements and TRIANGLES'));
+
+ testGroup.addChild(referenceContextGroup);
+
+ };
+
+ sglrReferenceContextTest.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'single_reference_context';
+ var testDescription = 'Single Reference Context Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ sglrReferenceContextTest.init();
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceUtils.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceUtils.js
new file mode 100644
index 0000000000..3b93dd8f9f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceUtils.js
@@ -0,0 +1,317 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Reference context utils
+ *//*--------------------------------------------------------------------*/
+
+'use strict';
+goog.provide('framework.opengl.simplereference.sglrReferenceUtils');
+goog.require('framework.common.tcuFloat');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.referencerenderer.rrDefs');
+goog.require('framework.referencerenderer.rrGenericVector');
+goog.require('framework.referencerenderer.rrRenderState');
+goog.require('framework.referencerenderer.rrRenderer');
+goog.require('framework.referencerenderer.rrShaders');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+
+goog.scope(function() {
+
+ var sglrReferenceUtils = framework.opengl.simplereference.sglrReferenceUtils;
+ var deMath = framework.delibs.debase.deMath;
+ var tcuFloat = framework.common.tcuFloat;
+ var rrGenericVector = framework.referencerenderer.rrGenericVector;
+ var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+ var rrRenderer = framework.referencerenderer.rrRenderer;
+ var rrDefs = framework.referencerenderer.rrDefs;
+ var rrShaders = framework.referencerenderer.rrShaders;
+ var rrRenderState = framework.referencerenderer.rrRenderState;
+
+ /**
+ * @param {number} type (32-bit, unsigend)
+ * @return {rrVertexAttrib.VertexAttribType}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLPureIntegerVertexAttributeType = function(type) {
+ switch (type) {
+ case gl.UNSIGNED_BYTE: return rrVertexAttrib.VertexAttribType.PURE_UINT8;
+ case gl.UNSIGNED_SHORT: return rrVertexAttrib.VertexAttribType.PURE_UINT16;
+ case gl.UNSIGNED_INT: return rrVertexAttrib.VertexAttribType.PURE_UINT32;
+ case gl.BYTE: return rrVertexAttrib.VertexAttribType.PURE_INT8;
+ case gl.SHORT: return rrVertexAttrib.VertexAttribType.PURE_INT16;
+ case gl.INT: return rrVertexAttrib.VertexAttribType.PURE_INT32;
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+
+ /**
+ * @param {number} type (32-bit, unsigend)
+ * @param {boolean} normalizedInteger
+ * @param {number} size
+ * @return {rrVertexAttrib.VertexAttribType} converted value from type to VertexAttribType
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLFloatVertexAttributeType = function(type, normalizedInteger, size) {
+
+ /** @type {boolean} */ var useClampingNormalization = true;
+
+ switch (type) {
+ case gl.FLOAT:
+ return rrVertexAttrib.VertexAttribType.FLOAT;
+ case gl.HALF_FLOAT:
+ return rrVertexAttrib.VertexAttribType.HALF;
+ /* Not supported in WebGL 1/2 case gl.FIXED:
+ return rrVertexAttrib.VertexAttribType.FIXED;
+ case gl.DOUBLE:
+ return rrVertexAttrib.VertexAttribType.DOUBLE; */
+ case gl.UNSIGNED_BYTE:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_UINT8;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_UNORM8;
+
+ case gl.UNSIGNED_SHORT:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_UINT16;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_UNORM16;
+
+ case gl.UNSIGNED_INT:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_UINT32;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_UNORM32;
+
+ case gl.UNSIGNED_INT_2_10_10_10_REV:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_UINT_2_10_10_10_REV;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_UNORM_2_10_10_10_REV;
+
+ case gl.BYTE:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_INT8;
+ else if (useClampingNormalization)
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM8_CLAMP;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM8_SCALE;
+
+ case gl.SHORT:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_INT16;
+ else if (useClampingNormalization)
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM16_CLAMP;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM16_SCALE;
+
+ case gl.INT:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_INT32;
+ else if (useClampingNormalization)
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM32_CLAMP;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM32_SCALE;
+
+ case gl.INT_2_10_10_10_REV:
+ if (!normalizedInteger)
+ return rrVertexAttrib.VertexAttribType.NONPURE_INT_2_10_10_10_REV;
+ else if (useClampingNormalization)
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM_2_10_10_10_REV_CLAMP;
+ else
+ return rrVertexAttrib.VertexAttribType.NONPURE_SNORM_2_10_10_10_REV_SCALE;
+
+ default:
+ throw new Error('Value to do mapping not compatible');
+
+ }
+
+ };
+
+ /**
+ * @param {number} size
+ * @return {number}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLSize = function(size) {
+ switch (size) {
+ case 1: return 1;
+ case 2: return 2;
+ case 3: return 3;
+ case 4: return 4;
+ /* NOT in GL
+ case gl.BGRA: return 4;
+ */
+
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+
+ /**
+ * @param {number} type (32-bit, unsigned)
+ * @return {rrRenderer.PrimitiveType}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLPrimitiveType = function(type) {
+ switch (type) {
+ case gl.TRIANGLES: return rrRenderer.PrimitiveType.TRIANGLES;
+ case gl.TRIANGLE_STRIP: return rrRenderer.PrimitiveType.TRIANGLE_STRIP;
+ case gl.TRIANGLE_FAN: return rrRenderer.PrimitiveType.TRIANGLE_FAN;
+ case gl.LINES: return rrRenderer.PrimitiveType.LINES;
+ case gl.LINE_STRIP: return rrRenderer.PrimitiveType.LINE_STRIP;
+ case gl.LINE_LOOP: return rrRenderer.PrimitiveType.LINE_LOOP;
+ case gl.POINTS: return rrRenderer.PrimitiveType.POINTS;
+
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+
+ /**
+ * @param {number} type (32-bit, unsigned)
+ * @return {rrDefs.IndexType}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLIndexType = function(type) {
+ switch (type) {
+ case gl.UNSIGNED_BYTE: return rrDefs.IndexType.INDEXTYPE_UINT8;
+ case gl.UNSIGNED_SHORT: return rrDefs.IndexType.INDEXTYPE_UINT16;
+ case gl.UNSIGNED_INT: return rrDefs.IndexType.INDEXTYPE_UINT32;
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+
+ /**
+ * @param {number} func (deUint32)
+ * @return {rrRenderState.TestFunc}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLTestFunc = function(func) {
+ switch (func) {
+ case gl.ALWAYS: return rrRenderState.TestFunc.ALWAYS;
+ case gl.EQUAL: return rrRenderState.TestFunc.EQUAL;
+ case gl.GEQUAL: return rrRenderState.TestFunc.GEQUAL;
+ case gl.GREATER: return rrRenderState.TestFunc.GREATER;
+ case gl.LEQUAL: return rrRenderState.TestFunc.LEQUAL;
+ case gl.LESS: return rrRenderState.TestFunc.LESS;
+ case gl.NEVER: return rrRenderState.TestFunc.NEVER;
+ case gl.NOTEQUAL: return rrRenderState.TestFunc.NOTEQUAL;
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+
+ /**
+ * @param {number} op (deUint32)
+ * @return {rrRenderState.StencilOp}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLStencilOp = function(op) {
+ switch (op) {
+ case gl.KEEP: return rrRenderState.StencilOp.KEEP;
+ case gl.ZERO: return rrRenderState.StencilOp.ZERO;
+ case gl.REPLACE: return rrRenderState.StencilOp.REPLACE;
+ case gl.INCR: return rrRenderState.StencilOp.INCR;
+ case gl.DECR: return rrRenderState.StencilOp.DECR;
+ case gl.INCR_WRAP: return rrRenderState.StencilOp.INCR_WRAP;
+ case gl.DECR_WRAP: return rrRenderState.StencilOp.DECR_WRAP;
+ case gl.INVERT: return rrRenderState.StencilOp.INVERT;
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+
+ /**
+ * @param {number} equation (deUint32)
+ * @return {rrRenderState.BlendEquation}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLBlendEquation = function(equation) {
+ switch (equation) {
+ case gl.FUNC_ADD: return rrRenderState.BlendEquation.ADD;
+ case gl.FUNC_SUBTRACT: return rrRenderState.BlendEquation.SUBTRACT;
+ case gl.FUNC_REVERSE_SUBTRACT: return rrRenderState.BlendEquation.REVERSE_SUBTRACT;
+ case gl.MIN: return rrRenderState.BlendEquation.MIN;
+ case gl.MAX: return rrRenderState.BlendEquation.MAX;
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+
+ /**
+ * @param {number} equation (deUint32)
+ * @return {rrRenderState.BlendEquationAdvanced}
+ * @throws {Error}
+ */
+ /*sglrReferenceUtils.mapGLBlendEquationAdvanced = function(equation) {
+ switch (equation) {
+ case gl.MULTIPLY_KHR: return rrRenderState.BlendEquationAdvanced.MULTIPLY;
+ case gl.SCREEN_KHR: return rrRenderState.BlendEquationAdvanced.SCREEN;
+ case gl.OVERLAY_KHR: return rrRenderState.BlendEquationAdvanced.OVERLAY;
+ case gl.DARKEN_KHR: return rrRenderState.BlendEquationAdvanced.DARKEN;
+ case gl.LIGHTEN_KHR: return rrRenderState.BlendEquationAdvanced.LIGHTEN;
+ case gl.COLORDODGE_KHR: return rrRenderState.BlendEquationAdvanced.COLORDODGE;
+ case gl.COLORBURN_KHR: return rrRenderState.BlendEquationAdvanced.COLORBURN;
+ case gl.HARDLIGHT_KHR: return rrRenderState.BlendEquationAdvanced.HARDLIGHT;
+ case gl.SOFTLIGHT_KHR: return rrRenderState.BlendEquationAdvanced.SOFTLIGHT;
+ case gl.DIFFERENCE_KHR: return rrRenderState.BlendEquationAdvanced.DIFFERENCE;
+ case gl.EXCLUSION_KHR: return rrRenderState.BlendEquationAdvanced.EXCLUSION;
+ case gl.HSL_HUE_KHR: return rrRenderState.BlendEquationAdvanced.HSL_HUE;
+ case gl.HSL_SATURATION_KHR: return rrRenderState.BlendEquationAdvanced.HSL_SATURATION;
+ case gl.HSL_COLOR_KHR: return rrRenderState.BlendEquationAdvanced.HSL_COLOR;
+ case gl.HSL_LUMINOSITY_KHR: return rrRenderState.BlendEquationAdvanced.HSL_LUMINOSITY;
+ default:
+ throw new Error("Value to do mapping not compatible");
+ }
+ };*/
+
+ /**
+ * @param {number} func (deUint32)
+ * @return {rrRenderState.BlendFunc}
+ * @throws {Error}
+ */
+ sglrReferenceUtils.mapGLBlendFunc = function(func) {
+ switch (func) {
+ case gl.ZERO: return rrRenderState.BlendFunc.ZERO;
+ case gl.ONE: return rrRenderState.BlendFunc.ONE;
+ case gl.SRC_COLOR: return rrRenderState.BlendFunc.SRC_COLOR;
+ case gl.ONE_MINUS_SRC_COLOR: return rrRenderState.BlendFunc.ONE_MINUS_SRC_COLOR;
+ case gl.DST_COLOR: return rrRenderState.BlendFunc.DST_COLOR;
+ case gl.ONE_MINUS_DST_COLOR: return rrRenderState.BlendFunc.ONE_MINUS_DST_COLOR;
+ case gl.SRC_ALPHA: return rrRenderState.BlendFunc.SRC_ALPHA;
+ case gl.ONE_MINUS_SRC_ALPHA: return rrRenderState.BlendFunc.ONE_MINUS_SRC_ALPHA;
+ case gl.DST_ALPHA: return rrRenderState.BlendFunc.DST_ALPHA;
+ case gl.ONE_MINUS_DST_ALPHA: return rrRenderState.BlendFunc.ONE_MINUS_DST_ALPHA;
+ case gl.CONSTANT_COLOR: return rrRenderState.BlendFunc.CONSTANT_COLOR;
+ case gl.ONE_MINUS_CONSTANT_COLOR: return rrRenderState.BlendFunc.ONE_MINUS_CONSTANT_COLOR;
+ case gl.CONSTANT_ALPHA: return rrRenderState.BlendFunc.CONSTANT_ALPHA;
+ case gl.ONE_MINUS_CONSTANT_ALPHA: return rrRenderState.BlendFunc.ONE_MINUS_CONSTANT_ALPHA;
+ case gl.SRC_ALPHA_SATURATE: return rrRenderState.BlendFunc.SRC_ALPHA_SATURATE;
+ // case gl.SRC1_COLOR: return rrRenderState.BlendFunc.SRC1_COLOR;
+ // case gl.ONE_MINUS_SRC1_COLOR: return rrRenderState.BlendFunc.ONE_MINUS_SRC1_COLOR;
+ // case gl.SRC1_ALPHA: return rrRenderState.BlendFunc.SRC1_ALPHA;
+ // case gl.ONE_MINUS_SRC1_ALPHA: return rrRenderState.BlendFunc.ONE_MINUS_SRC1_ALPHA;
+ default:
+ throw new Error('Value to do mapping not compatible');
+ }
+ };
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrShaderProgram.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrShaderProgram.js
new file mode 100644
index 0000000000..f5201a5315
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrShaderProgram.js
@@ -0,0 +1,336 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('framework.opengl.simplereference.sglrShaderProgram');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.referencerenderer.rrDefs');
+goog.require('framework.referencerenderer.rrFragmentOperations');
+goog.require('framework.referencerenderer.rrGenericVector');
+goog.require('framework.referencerenderer.rrShaders');
+goog.require('framework.referencerenderer.rrShadingContext');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+goog.require('framework.referencerenderer.rrVertexPacket');
+
+goog.scope(function() {
+
+ var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
+ var rrShaders = framework.referencerenderer.rrShaders;
+ var rrGenericVector = framework.referencerenderer.rrGenericVector;
+ var tcuTexture = framework.common.tcuTexture;
+ var deMath = framework.delibs.debase.deMath;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var rrDefs = framework.referencerenderer.rrDefs;
+ var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
+ var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+ var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
+ var rrShadingContext = framework.referencerenderer.rrShadingContext;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /**
+ * sglrShaderProgram.VaryingFlags
+ * @constructor
+ * @struct
+ */
+ sglrShaderProgram.VaryingFlags = function() {
+ this.NONE = true; //TODO: is NONE necessary?
+ this.FLATSHADE = false;
+ };
+
+ /**
+ * sglrShaderProgram.VertexAttribute
+ * @constructor
+ * @param {string} name_
+ * @param {rrGenericVector.GenericVecType} type_
+ */
+ sglrShaderProgram.VertexAttribute = function(name_, type_) {
+ this.name = name_;
+ this.type = type_;
+ };
+
+ /**
+ * sglrShaderProgram.VertexToFragmentVarying
+ * @constructor
+ * @param {rrGenericVector.GenericVecType} type_
+ * @param {sglrShaderProgram.VaryingFlags=} flags
+ */
+ sglrShaderProgram.VertexToFragmentVarying = function(type_, flags) {
+ this.type = type_;
+ this.flatshade = flags === undefined ? new sglrShaderProgram.VaryingFlags().FLATSHADE : flags.FLATSHADE;
+ };
+
+ /**
+ * sglrShaderProgram.FragmentOutput
+ * @constructor
+ * @param {rrGenericVector.GenericVecType} type_
+ */
+ sglrShaderProgram.FragmentOutput = function(type_) {
+ /** @type {rrGenericVector.GenericVecType} */ this.type = type_;
+ };
+
+ /**
+ * sglrShaderProgram.Uniform
+ * @constructor
+ * @param {string} name_
+ * @param {gluShaderUtil.DataType} type_
+ */
+ sglrShaderProgram.Uniform = function(name_, type_) {
+ /** @type {string} */ this.name = name_;
+ /** @type {gluShaderUtil.DataType} */ this.type = type_;
+ /** @type {Array<number>} */ this.value;
+ /** @type {?rrDefs.Sampler} */ this.sampler = null;
+ };
+
+ /**
+ * sglrShaderProgram.VertexSource
+ * @constructor
+ * @param {string} str
+ */
+ sglrShaderProgram.VertexSource = function(str) {
+ /** @type {string} */ this.source = str;
+ };
+
+ /**
+ * sglrShaderProgram.FragmentSource
+ * @constructor
+ * @param {string} str
+ */
+ sglrShaderProgram.FragmentSource = function(str) {
+ /** @type {string} */ this.source = str;
+ };
+
+ /**
+ * sglrShaderProgram.ShaderProgramDeclaration
+ * @constructor
+ */
+ sglrShaderProgram.ShaderProgramDeclaration = function() {
+ /** @type {Array<sglrShaderProgram.VertexAttribute>} */ this.m_vertexAttributes = [];
+ /** @type {Array<sglrShaderProgram.VertexToFragmentVarying>} */ this.m_vertexToFragmentVaryings = [];
+ /** @type {Array<sglrShaderProgram.FragmentOutput>} */ this.m_fragmentOutputs = [];
+ /** @type {Array<sglrShaderProgram.Uniform>} */ this.m_uniforms = [];
+ /** @type {string} */ this.m_vertexSource;
+ /** @type {string} */ this.m_fragmentSource;
+
+ /** @type {boolean} */ this.m_vertexShaderSet = false;
+ /** @type {boolean} */ this.m_fragmentShaderSet = false;
+ };
+
+ /**
+ * Add a vertex attribute to the shader program declaration.
+ * @param {sglrShaderProgram.VertexAttribute} v
+ * @return {sglrShaderProgram.ShaderProgramDeclaration}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.pushVertexAttribute = function(v) {
+ this.m_vertexAttributes.push(v);
+ return this;
+ };
+
+ /**
+ * Add a vertex to fragment varying to the shader program declaration.
+ * @param {sglrShaderProgram.VertexToFragmentVarying} v
+ * @return {sglrShaderProgram.ShaderProgramDeclaration}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.pushVertexToFragmentVarying = function(v) {
+ this.m_vertexToFragmentVaryings.push(v);
+ return this;
+ };
+
+ /**
+ * Add a fragment output to the shader program declaration.
+ * @param {sglrShaderProgram.FragmentOutput} v
+ * @return {sglrShaderProgram.ShaderProgramDeclaration}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.pushFragmentOutput = function(v) {
+ this.m_fragmentOutputs.push(v);
+ return this;
+ };
+
+ /**
+ * Add a uniform to the shader program declaration.
+ * @param {sglrShaderProgram.Uniform} v
+ * @return {sglrShaderProgram.ShaderProgramDeclaration}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.pushUniform = function(v) {
+ this.m_uniforms.push(v);
+ return this;
+ };
+
+ /**
+ * @param {sglrShaderProgram.VertexSource} c
+ * @return {sglrShaderProgram.ShaderProgramDeclaration}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.pushVertexSource = function(c) {
+ DE_ASSERT(!this.m_vertexShaderSet);
+ this.m_vertexSource = c.source;
+ this.m_vertexShaderSet = true;
+ return this;
+ };
+
+ /**
+ * @param {sglrShaderProgram.FragmentSource} c
+ * @return {sglrShaderProgram.ShaderProgramDeclaration}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.pushFragmentSource = function(c) {
+ DE_ASSERT(!this.m_fragmentSource);
+ /** @type {sglrShaderProgram.FragmentSource} */ this.m_fragmentSource = c.source;
+ /** @type {boolean} */ this.m_fragmentShaderSet = true;
+ return this;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.valid = function() {
+ if (!this.m_vertexShaderSet || !this.m_fragmentShaderSet)
+ return false;
+
+ if (this.m_fragmentOutputs.length == 0)
+ return false;
+
+ return true;
+ };
+
+ /**
+ * @return {number}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.getVertexInputCount = function() {
+ return this.m_vertexAttributes.length;
+ };
+
+ /**
+ * @return {number}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.getVertexOutputCount = function() {
+ return this.m_vertexToFragmentVaryings.length;
+ };
+
+ /**
+ * @return {number}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.getFragmentInputCount = function() {
+ return this.m_vertexToFragmentVaryings.length;
+ };
+
+ /**
+ * @return {number}
+ */
+ sglrShaderProgram.ShaderProgramDeclaration.prototype.getFragmentOutputCount = function() {
+ return this.m_fragmentOutputs.length;
+ };
+
+ /**
+ * @constructor
+ * @param {sglrShaderProgram.ShaderProgramDeclaration} decl
+ */
+ sglrShaderProgram.ShaderProgram = function(decl) {
+ /** @type {rrShaders.VertexShader} */ this.vertexShader = new rrShaders.VertexShader(decl.getVertexInputCount(), decl.getVertexOutputCount());
+ /** @type {rrShaders.FragmentShader} */ this.fragmentShader = new rrShaders.FragmentShader(decl.getFragmentInputCount(), decl.getFragmentOutputCount());
+
+ /** @type {Array<string>} */ this.m_attributeNames = [];
+ /** @type {Array<sglrShaderProgram.Uniform>} */ this.m_uniforms = [];
+ /** @type {string} */ this.m_vertSrc = decl.m_vertexSource;
+ /** @type {string} */ this.m_fragSrc = decl.m_fragmentSource;
+
+ DE_ASSERT(decl.valid());
+
+ // Set up shader IO
+
+ for (var ndx = 0; ndx < decl.m_vertexAttributes.length; ++ndx) {
+ this.vertexShader.m_inputs[ndx].type = decl.m_vertexAttributes[ndx].type;
+ this.m_attributeNames[ndx] = decl.m_vertexAttributes[ndx].name;
+ }
+
+ for (var ndx = 0; ndx < decl.m_vertexToFragmentVaryings.length; ++ndx) {
+ this.vertexShader.m_outputs[ndx].type = decl.m_vertexToFragmentVaryings[ndx].type;
+ this.vertexShader.m_outputs[ndx].flatshade = decl.m_vertexToFragmentVaryings[ndx].flatshade;
+
+ this.fragmentShader.m_inputs[ndx] = this.vertexShader.m_outputs[ndx];
+ }
+
+ for (var ndx = 0; ndx < decl.m_fragmentOutputs.length; ++ndx)
+ this.fragmentShader.m_outputs[ndx].type = decl.m_fragmentOutputs[ndx].type;
+
+ // Set up uniforms
+
+ for (var ndx = 0; ndx < decl.m_uniforms.length; ++ndx)
+ this.m_uniforms[ndx] = new sglrShaderProgram.Uniform(decl.m_uniforms[ndx].name, decl.m_uniforms[ndx].type);
+ };
+
+ /**
+ * @return {rrShaders.VertexShader}
+ */
+ sglrShaderProgram.ShaderProgram.prototype.getVertexShader = function() {
+ return this.vertexShader;
+ };
+
+ /**
+ * @return {rrShaders.FragmentShader}
+ */
+ sglrShaderProgram.ShaderProgram.prototype.getFragmentShader = function() {
+ return this.fragmentShader;
+ };
+
+ /**
+ * @param {string} name
+ * @return {sglrShaderProgram.Uniform}
+ * @throws {Error}
+ */
+ sglrShaderProgram.ShaderProgram.prototype.getUniformByName = function(name) {
+ DE_ASSERT(name);
+
+ for (var ndx = 0; ndx < this.m_uniforms.length; ++ndx)
+ if (this.m_uniforms[ndx].name == name)
+ return this.m_uniforms[ndx];
+
+ throw new Error('Invalid uniform name, uniform not found.');
+ };
+
+ /**
+ * shadeFragments - abstract function, to be implemented by children classes
+ * @param {Array<rrFragmentOperations.Fragment>} packets
+ * @param {rrShadingContext.FragmentShadingContext} context
+ * @throws {Error}
+ */
+ sglrShaderProgram.ShaderProgram.prototype.shadeFragments = function(packets, context) {
+ throw new Error('This function needs to be overwritten in a child class.');
+ };
+
+ /**
+ * shadeVertices - abstract function, to be implemented by children classes
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ * @throws {Error}
+ */
+ sglrShaderProgram.ShaderProgram.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ throw new Error('This function needs to be overwritten in a child class.');
+ };
+
+});