tcuTexVerifierUtil.js (10041B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ 20 21 'use strict'; 22 goog.provide('framework.common.tcuTexVerifierUtil'); 23 goog.require('framework.common.tcuFloat'); 24 goog.require('framework.common.tcuTexture'); 25 goog.require('framework.delibs.debase.deMath'); 26 goog.require('framework.delibs.debase.deUtil'); 27 28 goog.scope(function() { 29 30 var tcuTexVerifierUtil = framework.common.tcuTexVerifierUtil; 31 var deMath = framework.delibs.debase.deMath; 32 var deUtil = framework.delibs.debase.deUtil; 33 var tcuFloat = framework.common.tcuFloat; 34 var tcuTexture = framework.common.tcuTexture; 35 36 /** 37 * @param {number} value 38 * @param {number} numAccurateBits 39 * @return {number} 40 */ 41 tcuTexVerifierUtil.computeFloatingPointError = function(value, numAccurateBits) { 42 /** @type {number} */ var numGarbageBits = 23 - numAccurateBits; 43 /** @type {number} */ var mask = (1 << numGarbageBits) - 1; 44 /** @type {number} */ var exp = tcuFloat.newFloat32(value).exponent(); 45 46 /** @type {tcuFloat.deFloat} */ var v1 = new tcuFloat.deFloat(); 47 /** @type {tcuFloat.deFloat} */ var v2 = new tcuFloat.deFloat(); 48 return v1.construct(1, exp, 1 << 23 | mask).getValue() - v2.construct(1, exp, 1 << 23).getValue(); 49 }; 50 51 /** 52 * @param {number} numAccurateBits 53 * @return {number} 54 */ 55 tcuTexVerifierUtil.computeFixedPointError = function(numAccurateBits) { 56 return tcuTexVerifierUtil.computeFloatingPointError(1.0, numAccurateBits); 57 }; 58 59 /** 60 * @param {Array<number>} numAccurateBits 61 * @return {Array<number>} 62 */ 63 tcuTexVerifierUtil.computeFixedPointError_Vector = function(numAccurateBits) { 64 /** @type {Array<number>} */ var res = []; 65 for (var ndx = 0; ndx < numAccurateBits.length; ndx++) 66 res[ndx] = tcuTexVerifierUtil.computeFixedPointError(numAccurateBits[ndx]); 67 return res; 68 }; 69 70 /** 71 * @param {Array<number>} value 72 * @param {Array<number>} numAccurateBits 73 * @return {Array<number>} 74 */ 75 tcuTexVerifierUtil.computeFloatingPointError_Vector = function(value, numAccurateBits) { 76 assertMsgOptions(value.length === numAccurateBits.length, '', false, true); 77 /** @type {Array<number>} */ var res = []; 78 for (var ndx = 0; ndx < value.length; ndx++) 79 res[ndx] = tcuTexVerifierUtil.computeFloatingPointError(value[ndx], numAccurateBits[ndx]); 80 return res; 81 }; 82 83 // Sampler introspection 84 85 /** 86 * @param {tcuTexture.FilterMode} mode 87 * @return {boolean} 88 */ 89 tcuTexVerifierUtil.isNearestMipmapFilter = function(mode) { 90 return mode == tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST || mode == tcuTexture.FilterMode.LINEAR_MIPMAP_NEAREST; 91 }; 92 93 /** 94 * @param {tcuTexture.FilterMode} mode 95 * @return {boolean} 96 */ 97 tcuTexVerifierUtil.isLinearMipmapFilter = function(mode) { 98 return mode == tcuTexture.FilterMode.NEAREST_MIPMAP_LINEAR || mode == tcuTexture.FilterMode.LINEAR_MIPMAP_LINEAR; 99 }; 100 101 /** 102 * @param {tcuTexture.FilterMode} mode 103 * @return {boolean} 104 */ 105 tcuTexVerifierUtil.isMipmapFilter = function(mode) { 106 return tcuTexVerifierUtil.isNearestMipmapFilter(mode) || tcuTexVerifierUtil.isLinearMipmapFilter(mode); 107 }; 108 109 /** 110 * @param {tcuTexture.FilterMode} mode 111 * @return {boolean} 112 */ 113 tcuTexVerifierUtil.isLinearFilter = function(mode) { 114 return mode == tcuTexture.FilterMode.LINEAR || mode == tcuTexture.FilterMode.LINEAR_MIPMAP_NEAREST || mode == tcuTexture.FilterMode.LINEAR_MIPMAP_LINEAR; 115 }; 116 117 /** 118 * @param {tcuTexture.FilterMode} mode 119 * @return {boolean} 120 */ 121 tcuTexVerifierUtil.isNearestFilter = function(mode) { 122 return !tcuTexVerifierUtil.isLinearFilter(mode); 123 }; 124 125 /** 126 * @param {tcuTexture.FilterMode} mode 127 * @return {tcuTexture.FilterMode} 128 */ 129 tcuTexVerifierUtil.getLevelFilter = function(mode) { 130 return tcuTexVerifierUtil.isLinearFilter(mode) ? tcuTexture.FilterMode.LINEAR : tcuTexture.FilterMode.NEAREST; 131 }; 132 133 /** 134 * @param {tcuTexture.WrapMode} mode 135 * @return {boolean} 136 */ 137 tcuTexVerifierUtil.isWrapModeSupported = function(mode) { 138 return mode != tcuTexture.WrapMode.MIRRORED_REPEAT_CL && mode != tcuTexture.WrapMode.REPEAT_CL; 139 }; 140 141 /** 142 * 143 * @param {boolean} normalizedCoords 144 * @param {number} dim 145 * @param {number} coord 146 * @param {number} coordBits 147 * @param {number} uvBits 148 * @return {Array<number>} 149 */ 150 tcuTexVerifierUtil.computeNonNormalizedCoordBounds = function(normalizedCoords, dim, coord, coordBits, uvBits) { 151 /** @type {number} */ var coordErr = tcuTexVerifierUtil.computeFloatingPointError(coord, coordBits); 152 /** @type {number} */ var minN = coord - coordErr; 153 /** @type {number} */ var maxN = coord + coordErr; 154 /** @type {number} */ var minA = normalizedCoords ? minN * dim : minN; 155 /** @type {number} */ var maxA = normalizedCoords ? maxN * dim : maxN; 156 /** @type {number} */ var minC = minA - tcuTexVerifierUtil.computeFixedPointError(uvBits); 157 /** @type {number} */ var maxC = maxA + tcuTexVerifierUtil.computeFixedPointError(uvBits); 158 assertMsgOptions(minC <= maxC, '', false, true); 159 return [minC, maxC]; 160 }; 161 162 /** 163 * @param {Array<number>} coord 164 * @param {Array<number>} bits 165 * @return {?Array<tcuTexture.CubeFace>} 166 */ 167 tcuTexVerifierUtil.getPossibleCubeFaces = function(coord, bits) { 168 169 /** @type {Array<tcuTexture.CubeFace>} */ var faces = []; 170 171 /** @type {number} */ var x = coord[0]; 172 /** @type {number} */ var y = coord[1]; 173 /** @type {number} */ var z = coord[2]; 174 /** @type {number} */ var ax = Math.abs(x); 175 /** @type {number} */ var ay = Math.abs(y); 176 /** @type {number} */ var az = Math.abs(z); 177 /** @type {number} */ var ex = tcuTexVerifierUtil.computeFloatingPointError(x, bits[0]); 178 /** @type {number} */ var ey = tcuTexVerifierUtil.computeFloatingPointError(y, bits[1]); 179 /** @type {number} */ var ez = tcuTexVerifierUtil.computeFloatingPointError(z, bits[2]); 180 /** @type {number} */ var numFaces = 0; 181 182 if (ay + ey < ax - ex && az + ez < ax - ex) { 183 if (x >= ex) faces.push(tcuTexture.CubeFace.CUBEFACE_POSITIVE_X); 184 if (x <= ex) faces.push(tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X); 185 } else if (ax + ex < ay - ey && az + ez < ay - ey) { 186 if (y >= ey) faces.push(tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y); 187 if (y <= ey) faces.push(tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y); 188 } else if (ax + ex < az - ez && ay + ey < az - ez) { 189 if (z >= ez) faces.push(tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z); 190 if (z <= ez) faces.push(tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z); 191 } else { 192 // One or more components are equal (or within error bounds). Allow all faces where major axis is not zero. 193 if (ax > ex) { 194 faces.push(tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X); 195 faces.push(tcuTexture.CubeFace.CUBEFACE_POSITIVE_X); 196 } 197 198 if (ay > ey) { 199 faces.push(tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y); 200 faces.push(tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y); 201 } 202 203 if (az > ez) { 204 faces.push(tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z); 205 faces.push(tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z); 206 } 207 } 208 209 return faces.length == 0 ? null : faces; 210 }; 211 212 /** 213 * @param {tcuTexture.Sampler} sampler 214 * @return {tcuTexture.Sampler} 215 */ 216 tcuTexVerifierUtil.getUnnormalizedCoordSampler = function(sampler) { 217 var copy = /** @type {tcuTexture.Sampler} */ (deUtil.clone(sampler)); 218 copy.normalizedCoords = false; 219 return copy; 220 }; 221 222 /** 223 * @param {number} a 224 * @param {number} b 225 * @return {number} 226 */ 227 tcuTexVerifierUtil.imod = function(a, b) { 228 return deMath.imod(a, b); 229 }; 230 231 /** 232 * @param {number} a 233 * @return {number} 234 */ 235 tcuTexVerifierUtil.mirror = function(a) { 236 return deMath.mirror(a); 237 }; 238 239 /** 240 * @param {tcuTexture.WrapMode} mode 241 * @param {number} c 242 * @param {number} size 243 * @return {number} 244 */ 245 tcuTexVerifierUtil.wrap = function(mode, c, size) { 246 switch (mode) { 247 // \note CL and GL modes are handled identically here, as verification process accounts for 248 // accuracy differences caused by different methods (wrapping vs. denormalizing first). 249 case tcuTexture.WrapMode.CLAMP_TO_EDGE: 250 return deMath.clamp(c, 0, size - 1); 251 252 case tcuTexture.WrapMode.REPEAT_GL: 253 case tcuTexture.WrapMode.REPEAT_CL: 254 return deMath.imod(c, size); 255 256 case tcuTexture.WrapMode.MIRRORED_REPEAT_GL: 257 case tcuTexture.WrapMode.MIRRORED_REPEAT_CL: 258 return (size - 1) - deMath.mirror(deMath.imod(c, 2 * size) - size); 259 260 default: 261 throw new Error('Wrap mode not supported.'); 262 } 263 }; 264 265 });