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.
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
) {
36 throw new Error('Assert failed');
41 * @param {number} minVal
42 * @param {number} maxVal
45 tcuTextureUtil
.linearInterpolate = function(t
, minVal
, maxVal
) {
46 return minVal
+ (maxVal
- minVal
) * t
;
49 /** tcuTextureUtil.linearChannelToSRGB
53 tcuTextureUtil
.linearChannelToSRGB = function(cl
) {
56 else if (cl
< 0.0031308)
59 return 1.055 * Math
.pow(cl
, 0.41666) - 0.055;
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]),
80 tcuTextureUtil
.sRGBChannelToLinear = function(cs
) {
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]),
100 * tcuTextureUtil.getSubregion
101 * @param {tcuTexture.PixelBufferAccess} access
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(),
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
);
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');
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();
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()];
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]);
249 dst
.setPixel([sum
, sum
, sum
, sum
], x
, y
);
254 * Create tcuTextureUtil.TextureFormatInfo.
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
) {
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;
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;
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
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');
326 for (var i
= 0; i
< cond
.length
; i
++)
328 if (a
.length
) dst
.push(a
[i
]);
331 if (b
.length
) dst
.push(b
[i
]);
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
345 * @param {tcuTexture.TextureFormat} format
346 * @return {tcuTextureUtil.TextureFormatInfo}
348 tcuTextureUtil
.getTextureFormatInfo = function(format
) {
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],
355 else if (format
.order
== tcuTexture
.ChannelOrder
.D
|| format
.order
== tcuTexture
.ChannelOrder
.DS
)
356 return new tcuTextureUtil
.TextureFormatInfo([0, 0, 0, 0],
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],
366 var cRange
= tcuTextureUtil
.getChannelValueRange(format
.type
);
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;
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];
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;
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
);
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;
493 access
.setPixel(colorB
, x
, 0);
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;
512 access
.setPixel(colorB
, x
, y
);
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;
533 access
.setPixel(colorB
, x
, y
, z
);
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;
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];
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
);
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
);
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.
661 case tcuTexture
.ChannelType
.SNORM_INT8
:
662 case tcuTexture
.ChannelType
.SNORM_INT16
:
663 // Normalized signed formats.
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];
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
]);
714 scale
[c
] = 1 / (maxVal
[c
] - minVal
[c
]);
715 bias
[c
] = 0 - minVal
[c
] * scale
[c
];