diff options
Diffstat (limited to '')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTexture.js | 380 |
1 files changed, 380 insertions, 0 deletions
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; +}; + +}); |