Bug 1945965 – remove new tab April Fools logo. r=home-newtab-reviewers,reemhamz
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / framework / common / tcuTextureUtil.js
blob40450ab380188693aa54108fbb37b4468e553cee
1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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 tcuTextureUtil.copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 'use strict';
22 goog.provide('framework.common.tcuTextureUtil');
23 goog.require('framework.common.tcuTexture');
24 goog.require('framework.delibs.debase.deMath');
25 goog.require('framework.delibs.debase.deRandom');
27 goog.scope(function() {
29 var tcuTextureUtil = framework.common.tcuTextureUtil;
30 var tcuTexture = framework.common.tcuTexture;
31 var deMath = framework.delibs.debase.deMath;
32 var deRandom = framework.delibs.debase.deRandom;
34 var DE_ASSERT = function(x) {
35 if (!x)
36 throw new Error('Assert failed');
39 /**
40 * @param {number} t
41 * @param {number} minVal
42 * @param {number} maxVal
43 * @return {number}
45 tcuTextureUtil.linearInterpolate = function(t, minVal, maxVal) {
46 return minVal + (maxVal - minVal) * t;
49 /** tcuTextureUtil.linearChannelToSRGB
50 * @param {number} cl
51 * @return {number}
53 tcuTextureUtil.linearChannelToSRGB = function(cl) {
54 if (cl <= 0.0)
55 return 0.0;
56 else if (cl < 0.0031308)
57 return 12.92 * cl;
58 else if (cl < 1.0)
59 return 1.055 * Math.pow(cl, 0.41666) - 0.055;
60 else
61 return 1.0;
64 /**
65 * Convert sRGB to linear colorspace
66 * @param {Array<number>} cs
67 * @return {Array<number>}
69 tcuTextureUtil.sRGBToLinear = function(cs) {
70 return [tcuTextureUtil.sRGBChannelToLinear(cs[0]),
71 tcuTextureUtil.sRGBChannelToLinear(cs[1]),
72 tcuTextureUtil.sRGBChannelToLinear(cs[2]),
73 cs[3]];
76 /**
77 * @param {number} cs
78 * @return {number}
80 tcuTextureUtil.sRGBChannelToLinear = function(cs) {
81 if (cs <= 0.04045)
82 return cs / 12.92;
83 else
84 return Math.pow((cs + 0.055) / 1.055, 2.4);
87 /** tcuTextureUtil.linearToSRGB
88 * @param {Array<number>} cl
89 * @return {Array<number>}
91 tcuTextureUtil.linearToSRGB = function(cl) {
92 return [tcuTextureUtil.linearChannelToSRGB(cl[0]),
93 tcuTextureUtil.linearChannelToSRGB(cl[1]),
94 tcuTextureUtil.linearChannelToSRGB(cl[2]),
95 cl[3]
99 /**
100 * tcuTextureUtil.getSubregion
101 * @param {tcuTexture.PixelBufferAccess} access
102 * @param {number} x
103 * @param {number} y
104 * @param {number} z
105 * @param {number} width
106 * @param {number} height
107 * @param {number} depth
108 * @return {tcuTexture.PixelBufferAccess}
110 tcuTextureUtil.getSubregion = function(access, x, y, z, width, height, depth) {
112 DE_ASSERT(deMath.deInBounds32(x, 0, access.getWidth()) && deMath.deInRange32(x + width, x, access.getWidth()));
113 DE_ASSERT(deMath.deInBounds32(y, 0, access.getHeight()) && deMath.deInRange32(y + height, y, access.getHeight()));
114 DE_ASSERT(deMath.deInBounds32(z, 0, access.getDepth()) && deMath.deInRange32(z + depth, z, access.getDepth()));
116 return new tcuTexture.PixelBufferAccess({
117 format: access.getFormat(),
118 width: width,
119 height: height,
120 depth: depth,
121 rowPitch: access.getRowPitch(),
122 slicePitch: access.getSlicePitch(),
123 offset: access.m_offset + access.getFormat().getPixelSize() * x + access.getRowPitch() * y + access.getSlicePitch() * z,
124 data: access.getBuffer()
129 * @param {tcuTexture.PixelBufferAccess} access
130 * @param {Array<number>} minVal
131 * @param {Array<number>} maxVal
133 tcuTextureUtil.fillWithComponentGradients1D = function(access, minVal, maxVal) {
134 DE_ASSERT(access.getHeight() == 1);
135 for (var x = 0; x < access.getWidth(); x++) {
136 var s = (x + 0.5) / access.getWidth();
138 var r = tcuTextureUtil.linearInterpolate(s, minVal[0], maxVal[0]);
139 var g = tcuTextureUtil.linearInterpolate(s, minVal[1], maxVal[1]);
140 var b = tcuTextureUtil.linearInterpolate(s, minVal[2], maxVal[2]);
141 var a = tcuTextureUtil.linearInterpolate(s, minVal[3], maxVal[3]);
143 access.setPixel([r, g, b, a], x, 0);
148 * @param {tcuTexture.PixelBufferAccess} access
149 * @param {Array<number>} minVal
150 * @param {Array<number>} maxVal
152 tcuTextureUtil.fillWithComponentGradients2D = function(access, minVal, maxVal) {
153 for (var y = 0; y < access.getHeight(); y++) {
154 var t = (y + 0.5) / access.getHeight();
155 for (var x = 0; x < access.getWidth(); x++) {
156 var s = (x + 0.5) / access.getWidth();
158 var r = tcuTextureUtil.linearInterpolate((s + t) * 0.5, minVal[0], maxVal[0]);
159 var g = tcuTextureUtil.linearInterpolate((s + (1 - t)) * 0.5, minVal[1], maxVal[1]);
160 var b = tcuTextureUtil.linearInterpolate(((1 - s) + t) * 0.5, minVal[2], maxVal[2]);
161 var a = tcuTextureUtil.linearInterpolate(((1 - s) + (1 - t)) * 0.5, minVal[3], maxVal[3]);
163 access.setPixel([r, g, b, a], x, y);
169 * @param {tcuTexture.PixelBufferAccess} dst
170 * @param {Array<number>} minVal
171 * @param {Array<number>} maxVal
173 tcuTextureUtil.fillWithComponentGradients3D = function(dst, minVal, maxVal) {
174 for (var z = 0; z < dst.getDepth(); z++) {
175 var p = (z + 0.5) / dst.getDepth();
176 var b = tcuTextureUtil.linearInterpolate(p, minVal[2], maxVal[2]);
177 for (var y = 0; y < dst.getHeight(); y++) {
178 var t = (y + 0.5) / dst.getHeight();
179 var g = tcuTextureUtil.linearInterpolate(t, minVal[1], maxVal[1]);
180 for (var x = 0; x < dst.getWidth(); x++) {
181 var s = (x + 0.5) / dst.getWidth();
182 var r = tcuTextureUtil.linearInterpolate(s, minVal[0], maxVal[0]);
183 var a = tcuTextureUtil.linearInterpolate(1 - (s + t + p) / 3, minVal[3], maxVal[3]);
184 dst.setPixel([r, g, b, a], x, y, z);
191 * @param {tcuTexture.PixelBufferAccess} access
192 * @param {Array<number>} minVal
193 * @param {Array<number>} maxVal
195 tcuTextureUtil.fillWithComponentGradients = function(access, minVal, maxVal) {
196 if (access.getHeight() == 1 && access.getDepth() == 1)
197 tcuTextureUtil.fillWithComponentGradients1D(access, minVal, maxVal);
198 else if (access.getDepth() == 1)
199 tcuTextureUtil.fillWithComponentGradients2D(access, minVal, maxVal);
200 else
201 tcuTextureUtil.fillWithComponentGradients3D(access, minVal, maxVal);
205 * @param {tcuTexture.PixelBufferAccess} dst
207 tcuTextureUtil.fillWithRGBAQuads = function(dst) {
208 checkMessage(dst.getDepth() == 1, 'Depth must be 1');
209 var width = dst.getWidth();
210 var height = dst.getHeight();
211 var left = width / 2;
212 var top = height / 2;
214 tcuTextureUtil.getSubregion(dst, 0, 0, 0, left, top, 1).clear([1.0, 0.0, 0.0, 1.0]);
215 tcuTextureUtil.getSubregion(dst, left, 0, 0, width - left, top, 1).clear([0.0, 1.0, 0.0, 1.0]);
216 tcuTextureUtil.getSubregion(dst, 0, top, 0, left, height - top, 1).clear([0.0, 0.0, 1.0, 0.0]);
217 tcuTextureUtil.getSubregion(dst, left, top, 0, width - left, height - top, 1).clear([0.5, 0.5, 0.5, 1.0]);
220 // \todo [2012-11-13 pyry] There is much better metaballs code in CL SIR value generators.
222 * @param {tcuTexture.PixelBufferAccess} dst
223 * @param {number} numBalls
224 * @param {number} seed
226 tcuTextureUtil.fillWithMetaballs = function(dst, numBalls, seed) {
227 checkMessage(dst.getDepth() == 1, 'Depth must be 1');
228 var points = [];
229 var rnd = new deRandom.Random(seed);
231 for (var i = 0; i < numBalls; i++) {
232 var x = rnd.getFloat();
233 var y = rnd.getFloat();
234 points[i] = [x, y];
237 for (var y = 0; y < dst.getHeight(); y++)
238 for (var x = 0; x < dst.getWidth(); x++) {
239 var p = [x / dst.getWidth(), y / dst.getHeight()];
241 var sum = 0.0;
242 for (var pointNdx = 0; pointNdx < points.length; pointNdx++) {
243 var d = deMath.subtract(p, points[pointNdx]);
244 var f = 0.01 / (d[0] * d[0] + d[1] * d[1]);
246 sum += f;
249 dst.setPixel([sum, sum, sum, sum], x, y);
254 * Create tcuTextureUtil.TextureFormatInfo.
255 * @constructor
256 * @param {Array<number>} valueMin
257 * @param {Array<number>} valueMax
258 * @param {Array<number>} lookupScale
259 * @param {Array<number>} lookupBias
261 tcuTextureUtil.TextureFormatInfo = function(valueMin, valueMax, lookupScale, lookupBias) {
262 /** @type {Array<number>} */ this.valueMin = valueMin;
263 /** @type {Array<number>} */ this.valueMax = valueMax;
264 /** @type {Array<number>} */ this.lookupScale = lookupScale;
265 /** @type {Array<number>} */ this.lookupBias = lookupBias;
269 * @param {?tcuTexture.ChannelType} channelType
270 * @return {Array<number>}
272 tcuTextureUtil.getChannelValueRange = function(channelType) {
273 var cMin = 0;
274 var cMax = 0;
276 switch (channelType) {
277 // Signed normalized formats.
278 case tcuTexture.ChannelType.SNORM_INT8:
279 case tcuTexture.ChannelType.SNORM_INT16: cMin = -1; cMax = 1; break;
281 // Unsigned normalized formats.
282 case tcuTexture.ChannelType.UNORM_INT8:
283 case tcuTexture.ChannelType.UNORM_INT16:
284 case tcuTexture.ChannelType.UNORM_SHORT_565:
285 case tcuTexture.ChannelType.UNORM_SHORT_4444:
286 case tcuTexture.ChannelType.UNORM_INT_101010:
287 case tcuTexture.ChannelType.UNORM_INT_1010102_REV: cMin = 0; cMax = 1; break;
289 // Misc formats.
290 case tcuTexture.ChannelType.SIGNED_INT8: cMin = -128; cMax = 127; break;
291 case tcuTexture.ChannelType.SIGNED_INT16: cMin = -32768; cMax = 32767; break;
292 case tcuTexture.ChannelType.SIGNED_INT32: cMin = -2147483648; cMax = 2147483647; break;
293 case tcuTexture.ChannelType.UNSIGNED_INT8: cMin = 0; cMax = 255; break;
294 case tcuTexture.ChannelType.UNSIGNED_INT16: cMin = 0; cMax = 65535; break;
295 case tcuTexture.ChannelType.UNSIGNED_INT32: cMin = 0; cMax = 4294967295; break;
296 case tcuTexture.ChannelType.HALF_FLOAT: cMin = -1e3; cMax = 1e3; break;
297 case tcuTexture.ChannelType.FLOAT: cMin = -1e5; cMax = 1e5; break;
298 case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV: cMin = 0; cMax = 1e4; break;
299 case tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV: cMin = 0; cMax = 1e5; break;
301 default:
302 DE_ASSERT(false);
305 return [cMin, cMax];
309 * Creates an array by choosing between 'a' and 'b' based on 'cond' array.
310 * @param {Array | number} a
311 * @param {Array | number} b
312 * @param {Array<boolean>} cond Condtions
313 * @return {Array}
315 tcuTextureUtil.select = function(a, b, cond) {
317 /*DE_ASSERT(!(a.length && !b.length)
318 || !(!a.length && b.length)
319 || !((a.length && b.length) && ((a.length != b.length) || (b.length != cond.length) || (a.length != cond.length))));*/
321 if (a.length && !b.length) throw new Error('second input parameter is not a vector');
322 if (!a.length && b.length) throw new Error('first input parameter is not a vector');
323 if ((a.length && b.length) && ((a.length != b.length) || (b.length != cond.length) || (a.length != cond.length))) throw new Error('different size vectors');
325 var dst = [];
326 for (var i = 0; i < cond.length; i++)
327 if (cond[i]) {
328 if (a.length) dst.push(a[i]);
329 else dst.push(a);
330 } else {
331 if (b.length) dst.push(b[i]);
332 else dst.push(b);
334 return dst;
338 * Get standard parameters for testing texture format
340 * Returns tcuTextureUtil.TextureFormatInfo that describes good parameters for exercising
341 * given TextureFormat. Parameters include value ranges per channel and
342 * suitable lookup scaling and bias in order to reduce result back to
343 * 0..1 range.
345 * @param {tcuTexture.TextureFormat} format
346 * @return {tcuTextureUtil.TextureFormatInfo}
348 tcuTextureUtil.getTextureFormatInfo = function(format) {
349 // Special cases.
350 if (format.isEqual(new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV)))
351 return new tcuTextureUtil.TextureFormatInfo([0, 0, 0, 0],
352 [1023, 1023, 1023, 3],
353 [1 / 1023, 1 / 1023, 1 / 1023, 1 / 3],
354 [0, 0, 0, 0]);
355 else if (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS)
356 return new tcuTextureUtil.TextureFormatInfo([0, 0, 0, 0],
357 [1, 1, 1, 0],
358 [1, 1, 1, 1],
359 [0, 0, 0, 0]); // Depth / stencil formats.
360 else if (format.isEqual(new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_5551)))
361 return new tcuTextureUtil.TextureFormatInfo([0, 0, 0, 0.5],
362 [1, 1, 1, 1.5],
363 [1, 1, 1, 1],
364 [0, 0, 0, 0]);
366 var cRange = tcuTextureUtil.getChannelValueRange(format.type);
367 var chnMask = null;
369 switch (format.order) {
370 case tcuTexture.ChannelOrder.R: chnMask = [true, false, false, false]; break;
371 case tcuTexture.ChannelOrder.A: chnMask = [false, false, false, true]; break;
372 case tcuTexture.ChannelOrder.L: chnMask = [true, true, true, false]; break;
373 case tcuTexture.ChannelOrder.LA: chnMask = [true, true, true, true]; break;
374 case tcuTexture.ChannelOrder.RG: chnMask = [true, true, false, false]; break;
375 case tcuTexture.ChannelOrder.RGB: chnMask = [true, true, true, false]; break;
376 case tcuTexture.ChannelOrder.RGBA: chnMask = [true, true, true, true]; break;
377 case tcuTexture.ChannelOrder.sRGB: chnMask = [true, true, true, false]; break;
378 case tcuTexture.ChannelOrder.sRGBA: chnMask = [true, true, true, true]; break;
379 case tcuTexture.ChannelOrder.D: chnMask = [true, true, true, false]; break;
380 case tcuTexture.ChannelOrder.DS: chnMask = [true, true, true, true]; break;
381 default:
382 DE_ASSERT(false);
385 var scale = 1 / (cRange[1] - cRange[0]);
386 var bias = -cRange[0] * scale;
388 return new tcuTextureUtil.TextureFormatInfo(tcuTextureUtil.select(cRange[0], 0, chnMask),
389 tcuTextureUtil.select(cRange[1], 0, chnMask),
390 tcuTextureUtil.select(scale, 1, chnMask),
391 tcuTextureUtil.select(bias, 0, chnMask));
394 /** tcuTextureUtil.getChannelBitDepth
395 * @param {?tcuTexture.ChannelType} channelType
396 * @return {Array<number>}
398 tcuTextureUtil.getChannelBitDepth = function(channelType) {
400 switch (channelType) {
401 case tcuTexture.ChannelType.SNORM_INT8: return [8, 8, 8, 8];
402 case tcuTexture.ChannelType.SNORM_INT16: return [16, 16, 16, 16];
403 case tcuTexture.ChannelType.SNORM_INT32: return [32, 32, 32, 32];
404 case tcuTexture.ChannelType.UNORM_INT8: return [8, 8, 8, 8];
405 case tcuTexture.ChannelType.UNORM_INT16: return [16, 16, 16, 16];
406 case tcuTexture.ChannelType.UNORM_INT32: return [32, 32, 32, 32];
407 case tcuTexture.ChannelType.UNORM_SHORT_565: return [5, 6, 5, 0];
408 case tcuTexture.ChannelType.UNORM_SHORT_4444: return [4, 4, 4, 4];
409 case tcuTexture.ChannelType.UNORM_SHORT_555: return [5, 5, 5, 0];
410 case tcuTexture.ChannelType.UNORM_SHORT_5551: return [5, 5, 5, 1];
411 case tcuTexture.ChannelType.UNORM_INT_101010: return [10, 10, 10, 0];
412 case tcuTexture.ChannelType.UNORM_INT_1010102_REV: return [10, 10, 10, 2];
413 case tcuTexture.ChannelType.SIGNED_INT8: return [8, 8, 8, 8];
414 case tcuTexture.ChannelType.SIGNED_INT16: return [16, 16, 16, 16];
415 case tcuTexture.ChannelType.SIGNED_INT32: return [32, 32, 32, 32];
416 case tcuTexture.ChannelType.UNSIGNED_INT8: return [8, 8, 8, 8];
417 case tcuTexture.ChannelType.UNSIGNED_INT16: return [16, 16, 16, 16];
418 case tcuTexture.ChannelType.UNSIGNED_INT32: return [32, 32, 32, 32];
419 case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV: return [10, 10, 10, 2];
420 case tcuTexture.ChannelType.UNSIGNED_INT_24_8: return [24, 0, 0, 8];
421 case tcuTexture.ChannelType.HALF_FLOAT: return [16, 16, 16, 16];
422 case tcuTexture.ChannelType.FLOAT: return [32, 32, 32, 32];
423 case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV: return [11, 11, 10, 0];
424 case tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV: return [9, 9, 9, 0];
425 case tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV: return [32, 0, 0, 8];
426 default:
427 DE_ASSERT(false);
428 return [0, 0, 0, 0];
432 /** tcuTextureUtil.getTextureFormatBitDepth
433 * @param {tcuTexture.TextureFormat} format
434 * @return {Array<number>}
436 tcuTextureUtil.getTextureFormatBitDepth = function(format) {
438 /** @type {Array<number>} */ var chnBits = tcuTextureUtil.getChannelBitDepth(format.type); // IVec4
439 /** @type {Array<boolean>} */ var chnMask = [false, false, false, false]; // BVec4
440 /** @type {Array<number>} */ var chnSwz = [0, 1, 2, 3]; // IVec4
442 switch (format.order) {
443 case tcuTexture.ChannelOrder.R: chnMask = [true, false, false, false]; break;
444 case tcuTexture.ChannelOrder.A: chnMask = [false, false, false, true]; break;
445 case tcuTexture.ChannelOrder.RA: chnMask = [true, false, false, true]; break;
446 case tcuTexture.ChannelOrder.L: chnMask = [true, true, true, false]; break;
447 case tcuTexture.ChannelOrder.I: chnMask = [true, true, true, true]; break;
448 case tcuTexture.ChannelOrder.LA: chnMask = [true, true, true, true]; break;
449 case tcuTexture.ChannelOrder.RG: chnMask = [true, true, false, false]; break;
450 case tcuTexture.ChannelOrder.RGB: chnMask = [true, true, true, false]; break;
451 case tcuTexture.ChannelOrder.RGBA: chnMask = [true, true, true, true]; break;
452 case tcuTexture.ChannelOrder.BGRA: chnMask = [true, true, true, true]; chnSwz = [2, 1, 0, 3]; break;
453 case tcuTexture.ChannelOrder.ARGB: chnMask = [true, true, true, true]; chnSwz = [1, 2, 3, 0]; break;
454 case tcuTexture.ChannelOrder.sRGB: chnMask = [true, true, true, false]; break;
455 case tcuTexture.ChannelOrder.sRGBA: chnMask = [true, true, true, true]; break;
456 case tcuTexture.ChannelOrder.D: chnMask = [true, false, false, false]; break;
457 case tcuTexture.ChannelOrder.DS: chnMask = [true, false, false, true]; break;
458 case tcuTexture.ChannelOrder.S: chnMask = [false, false, false, true]; break;
459 default:
460 DE_ASSERT(false);
463 return tcuTextureUtil.select(deMath.swizzle(chnBits, [chnSwz[0], chnSwz[1], chnSwz[2], chnSwz[3]]), [0, 0, 0, 0], chnMask);
467 /** tcuTextureUtil.fillWithGrid
468 * @const @param {tcuTexture.PixelBufferAccess} access
469 * @param {number} cellSize
470 * @param {Array<number>} colorA
471 * @param {Array<number>} colorB
473 tcuTextureUtil.fillWithGrid = function(access, cellSize, colorA, colorB) {
474 if (access.getHeight() == 1 && access.getDepth() == 1)
475 tcuTextureUtil.fillWithGrid1D(access, cellSize, colorA, colorB);
476 else if (access.getDepth() == 1)
477 tcuTextureUtil.fillWithGrid2D(access, cellSize, colorA, colorB);
478 else
479 tcuTextureUtil.fillWithGrid3D(access, cellSize, colorA, colorB);
482 /** tcuTextureUtil.fillWithGrid1D
483 * @const @param {tcuTexture.PixelBufferAccess} access
484 * @param {number} cellSize
485 * @param {Array<number>} colorA
486 * @param {Array<number>} colorB
488 tcuTextureUtil.fillWithGrid1D = function(access, cellSize, colorA, colorB) {
489 for (var x = 0; x < access.getWidth(); x++) {
490 var mx = Math.floor(x / cellSize) % 2;
492 if (mx)
493 access.setPixel(colorB, x, 0);
494 else
495 access.setPixel(colorA, x, 0);
499 /** tcuTextureUtil.fillWithGrid2D
500 * @const @param {tcuTexture.PixelBufferAccess} access
501 * @param {number} cellSize
502 * @param {Array<number>} colorA
503 * @param {Array<number>} colorB
505 tcuTextureUtil.fillWithGrid2D = function(access, cellSize, colorA, colorB) {
506 for (var y = 0; y < access.getHeight(); y++)
507 for (var x = 0; x < access.getWidth(); x++) {
508 var mx = Math.floor(x / cellSize) % 2;
509 var my = Math.floor(y / cellSize) % 2;
511 if (mx ^ my)
512 access.setPixel(colorB, x, y);
513 else
514 access.setPixel(colorA, x, y);
518 /** tcuTextureUtil.fillWithGrid3D
519 * @const @param {tcuTexture.PixelBufferAccess} access
520 * @param {number} cellSize
521 * @param {Array<number>} colorA
522 * @param {Array<number>} colorB
524 tcuTextureUtil.fillWithGrid3D = function(access, cellSize, colorA, colorB) {
525 for (var z = 0; z < access.getDepth(); z++)
526 for (var y = 0; y < access.getHeight(); y++)
527 for (var x = 0; x < access.getWidth(); x++) {
528 var mx = Math.floor(x / cellSize) % 2;
529 var my = Math.floor(y / cellSize) % 2;
530 var mz = Math.floor(z / cellSize) % 2;
532 if (mx ^ my ^ mz)
533 access.setPixel(colorB, x, y, z);
534 else
535 access.setPixel(colorA, x, y, z);
540 * @const @param {tcuTexture.TextureFormat} format
541 * @return {Array<number>}
543 tcuTextureUtil.getTextureFormatMantissaBitDepth = function(format) {
544 /** @type {Array<number>} */ var chnBits = tcuTextureUtil.getChannelMantissaBitDepth(format.type);
545 /** @type {Array<boolean>} */ var chnMask = [false, false, false, false];
546 /** @type {Array<number>} */ var chnSwz = [0, 1, 2, 3];
548 switch (format.order) {
549 case tcuTexture.ChannelOrder.R: chnMask = [true, false, false, false]; break;
550 case tcuTexture.ChannelOrder.A: chnMask = [false, false, false, true]; break;
551 case tcuTexture.ChannelOrder.RA: chnMask = [true, false, false, true]; break;
552 case tcuTexture.ChannelOrder.L: chnMask = [true, true, true, false]; break;
553 case tcuTexture.ChannelOrder.I: chnMask = [true, true, true, true]; break;
554 case tcuTexture.ChannelOrder.LA: chnMask = [true, true, true, true]; break;
555 case tcuTexture.ChannelOrder.RG: chnMask = [true, true, false, false]; break;
556 case tcuTexture.ChannelOrder.RGB: chnMask = [true, true, true, false]; break;
557 case tcuTexture.ChannelOrder.RGBA: chnMask = [true, true, true, true]; break;
558 case tcuTexture.ChannelOrder.BGRA: chnMask = [true, true, true, true]; chnSwz = [2, 1, 0, 3]; break;
559 case tcuTexture.ChannelOrder.ARGB: chnMask = [true, true, true, true]; chnSwz = [1, 2, 3, 0]; break;
560 case tcuTexture.ChannelOrder.sRGB: chnMask = [true, true, true, false]; break;
561 case tcuTexture.ChannelOrder.sRGBA: chnMask = [true, true, true, true]; break;
562 case tcuTexture.ChannelOrder.D: chnMask = [true, false, false, false]; break;
563 case tcuTexture.ChannelOrder.DS: chnMask = [true, false, false, true]; break;
564 case tcuTexture.ChannelOrder.S: chnMask = [false, false, false, true]; break;
565 default:
566 DE_ASSERT(false);
568 return tcuTextureUtil.select(deMath.swizzle(chnBits, [chnSwz[0], chnSwz[1], chnSwz[2], chnSwz[3]]), [0, 0, 0, 0], chnMask);
572 * @param {?tcuTexture.ChannelType} channelType
573 * @return {Array<number>}
575 tcuTextureUtil.getChannelMantissaBitDepth = function(channelType) {
576 switch (channelType) {
577 case tcuTexture.ChannelType.SNORM_INT8:
578 case tcuTexture.ChannelType.SNORM_INT16:
579 case tcuTexture.ChannelType.SNORM_INT32:
580 case tcuTexture.ChannelType.UNORM_INT8:
581 case tcuTexture.ChannelType.UNORM_INT16:
582 case tcuTexture.ChannelType.UNORM_INT32:
583 case tcuTexture.ChannelType.UNORM_SHORT_565:
584 case tcuTexture.ChannelType.UNORM_SHORT_4444:
585 case tcuTexture.ChannelType.UNORM_SHORT_555:
586 case tcuTexture.ChannelType.UNORM_SHORT_5551:
587 case tcuTexture.ChannelType.UNORM_INT_101010:
588 case tcuTexture.ChannelType.UNORM_INT_1010102_REV:
589 case tcuTexture.ChannelType.SIGNED_INT8:
590 case tcuTexture.ChannelType.SIGNED_INT16:
591 case tcuTexture.ChannelType.SIGNED_INT32:
592 case tcuTexture.ChannelType.UNSIGNED_INT8:
593 case tcuTexture.ChannelType.UNSIGNED_INT16:
594 case tcuTexture.ChannelType.UNSIGNED_INT32:
595 case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV:
596 case tcuTexture.ChannelType.UNSIGNED_INT_24_8:
597 case tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV:
598 return tcuTextureUtil.getChannelBitDepth(channelType);
599 case tcuTexture.ChannelType.HALF_FLOAT: return [10, 10, 10, 10];
600 case tcuTexture.ChannelType.FLOAT: return [23, 23, 23, 23];
601 case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV: return [6, 6, 5, 0];
602 case tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV: return [23, 0, 0, 8];
603 default:
604 throw new Error('Invalid channelType: ' + channelType);
609 * @param {tcuTexture.PixelBufferAccess} dst
610 * @param {tcuTexture.ConstPixelBufferAccess} src
612 tcuTextureUtil.copy = function(dst, src) {
613 var width = dst.getWidth();
614 var height = dst.getHeight();
615 var depth = dst.getDepth();
617 DE_ASSERT(src.getWidth() == width && src.getHeight() == height && src.getDepth() == depth);
619 if (src.getFormat().isEqual(dst.getFormat())) {
620 var srcData = src.getDataPtr();
621 var dstData = dst.getDataPtr();
623 if (srcData.length == dstData.length) {
624 dstData.set(srcData);
625 return;
628 var srcClass = tcuTexture.getTextureChannelClass(src.getFormat().type);
629 var dstClass = tcuTexture.getTextureChannelClass(dst.getFormat().type);
630 var srcIsInt = srcClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER || srcClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER;
631 var dstIsInt = dstClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER || dstClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER;
633 if (srcIsInt && dstIsInt) {
634 for (var z = 0; z < depth; z++)
635 for (var y = 0; y < height; y++)
636 for (var x = 0; x < width; x++)
637 dst.setPixelInt(src.getPixelInt(x, y, z), x, y, z);
638 } else {
639 for (var z = 0; z < depth; z++)
640 for (var y = 0; y < height; y++)
641 for (var x = 0; x < width; x++)
642 dst.setPixel(src.getPixel(x, y, z), x, y, z);
647 * @param {tcuTexture.ConstPixelBufferAccess} access
649 tcuTextureUtil.estimatePixelValueRange = function(access) {
650 var format = access.getFormat();
652 switch (format.type) {
653 case tcuTexture.ChannelType.UNORM_INT8:
654 case tcuTexture.ChannelType.UNORM_INT16:
655 // Normalized unsigned formats.
656 return [
657 [0, 0, 0, 0],
658 [1, 1, 1, 1]
661 case tcuTexture.ChannelType.SNORM_INT8:
662 case tcuTexture.ChannelType.SNORM_INT16:
663 // Normalized signed formats.
664 return [
665 [-1, -1, -1, -1],
666 [1, 1, 1, 1]
669 default:
670 // \note Samples every 4/8th pixel.
671 var minVal = [Infinity, Infinity, Infinity, Infinity];
672 var maxVal = [-Infinity, -Infinity, -Infinity, -Infinity];
674 for (var z = 0; z < access.getDepth(); z += 2) {
675 for (var y = 0; y < access.getHeight(); y += 2) {
676 for (var x = 0; x < access.getWidth(); x += 2) {
677 var p = access.getPixel(x, y, z);
679 minVal[0] = Math.min(minVal[0], p[0]);
680 minVal[1] = Math.min(minVal[1], p[1]);
681 minVal[2] = Math.min(minVal[2], p[2]);
682 minVal[3] = Math.min(minVal[3], p[3]);
684 maxVal[0] = Math.max(maxVal[0], p[0]);
685 maxVal[1] = Math.max(maxVal[1], p[1]);
686 maxVal[2] = Math.max(maxVal[2], p[2]);
687 maxVal[3] = Math.max(maxVal[3], p[3]);
691 return [minVal, maxVal];
696 * @param {tcuTexture.ConstPixelBufferAccess} access
697 * @return {{scale: Array<number>, bias: Array<number>}}
699 tcuTextureUtil.computePixelScaleBias = function(access) {
700 var limits = tcuTextureUtil.estimatePixelValueRange(access);
701 var minVal = limits[0];
702 var maxVal = limits[1];
704 var scale = [1, 1, 1, 1];
705 var bias = [0, 0, 0, 0];
707 var eps = 0.0001;
709 for (var c = 0; c < 4; c++) {
710 if (maxVal[c] - minVal[c] < eps) {
711 scale[c] = (maxVal[c] < eps) ? 1 : (1 / maxVal[c]);
712 bias[c] = (c == 3) ? (1 - maxVal[c] * scale[c]) : (0 - minVal[c] * scale[c]);
713 } else {
714 scale[c] = 1 / (maxVal[c] - minVal[c]);
715 bias[c] = 0 - minVal[c] * scale[c];
719 return {
720 scale: scale,
721 bias: bias