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 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('functional.gles3.es3fFboTestUtil');
23 goog.require('framework.common.tcuMatrix');
24 goog.require('framework.common.tcuRGBA');
25 goog.require('framework.common.tcuSurface');
26 goog.require('framework.common.tcuTexture');
27 goog.require('framework.common.tcuTextureUtil');
28 goog.require('framework.delibs.debase.deMath');
29 goog.require('framework.opengl.gluShaderUtil');
30 goog.require('framework.opengl.gluTextureUtil');
31 goog.require('framework.opengl.simplereference.sglrGLContext');
32 goog.require('framework.opengl.simplereference.sglrReferenceContext');
33 goog.require('framework.opengl.simplereference.sglrShaderProgram');
34 goog.require('framework.referencerenderer.rrFragmentOperations');
35 goog.require('framework.referencerenderer.rrGenericVector');
36 goog.require('framework.referencerenderer.rrShadingContext');
37 goog.require('framework.referencerenderer.rrVertexAttrib');
38 goog.require('framework.referencerenderer.rrVertexPacket');
40 goog.scope(function() {
42 var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
43 var tcuTexture = framework.common.tcuTexture;
44 var tcuTextureUtil = framework.common.tcuTextureUtil;
45 var tcuRGBA = framework.common.tcuRGBA;
46 var gluTextureUtil = framework.opengl.gluTextureUtil;
47 var deMath = framework.delibs.debase.deMath;
48 var rrShadingContext = framework.referencerenderer.rrShadingContext;
49 var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
50 var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
51 var gluShaderUtil = framework.opengl.gluShaderUtil;
52 var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
53 var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
54 var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
55 var rrGenericVector = framework.referencerenderer.rrGenericVector;
56 var tcuMatrix = framework.common.tcuMatrix;
57 var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
58 var tcuSurface = framework.common.tcuSurface;
60 var DE_ASSERT = function(x) {
62 throw new Error('Assert failed');
66 * Defines the exception type for a test failure.
68 * @param {number} reason The error code.
70 es3fFboTestUtil.FboIncompleteException = function(reason) {
72 this.name = 'es3fFboTestUtil.FboIncompleteException';
75 /** @typedef { (WebGL2RenderingContext|sglrReferenceContext.ReferenceContext)} */
76 es3fFboTestUtil.Context;
78 es3fFboTestUtil.FboIncompleteException.prototype.getReason = function() {return this.reason; };
81 * @param {gluShaderUtil.DataType} type
82 * @return {rrGenericVector.GenericVecType}
84 es3fFboTestUtil.mapDataTypeToGenericVecType = function(type) {
86 case gluShaderUtil.DataType.FLOAT_VEC4: return rrGenericVector.GenericVecType.FLOAT;
87 case gluShaderUtil.DataType.INT_VEC4: return rrGenericVector.GenericVecType.INT32;
88 case gluShaderUtil.DataType.UINT_VEC4: return rrGenericVector.GenericVecType.UINT32;
90 throw new Error('Unrecognized type: ' + type);
95 * @param {Array<number>} input
96 * @param {{max: number, min: number}} type min, max information
97 * @return {Array<number>}
99 es3fFboTestUtil.castVectorSaturate = function(input, type) {
101 (input[0] + 0.5 >= type.max) ? (type.max) : ((input[0] - 0.5 <= type.min) ? (type.min) : Math.round(input[0])),
102 (input[1] + 0.5 >= type.max) ? (type.max) : ((input[1] - 0.5 <= type.min) ? (type.min) : Math.round(input[1])),
103 (input[2] + 0.5 >= type.max) ? (type.max) : ((input[2] - 0.5 <= type.min) ? (type.min) : Math.round(input[2])),
104 (input[3] + 0.5 >= type.max) ? (type.max) : ((input[3] - 0.5 <= type.min) ? (type.min) : Math.round(input[3]))
109 * es3fFboTestUtil.FlatColorShader inherits from sglrShaderProgram
111 * @extends {sglrShaderProgram.ShaderProgram}
112 * @param {gluShaderUtil.DataType} outputType
113 * @param {number=} pointSize
115 es3fFboTestUtil.FlatColorShader = function(outputType, pointSize) {
116 pointSize = pointSize || 1;
117 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
118 var decl = new sglrShaderProgram.ShaderProgramDeclaration();
119 /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
121 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
122 decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
123 decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
124 decl.pushUniform(new sglrShaderProgram.Uniform('u_color', gluShaderUtil.DataType.FLOAT_VEC4));
125 decl.pushVertexSource(new sglrShaderProgram.VertexSource(
126 '#version 300 es\n' +
127 'in highp vec4 a_position;\n' +
128 'void main (void)\n' +
130 ' gl_Position = a_position;\n' +
131 ' gl_PointSize = ' + pointSize + '.0;\n' +
133 decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
134 '#version 300 es\n' +
135 'uniform highp vec4 u_color;\n' +
136 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
137 'void main (void)\n' +
139 ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(u_color);\n' +
141 sglrShaderProgram.ShaderProgram.call(this, decl);
142 this.m_pointSize = pointSize;
145 es3fFboTestUtil.FlatColorShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
146 es3fFboTestUtil.FlatColorShader.prototype.constructor = es3fFboTestUtil.FlatColorShader;
149 * @param {(WebGL2RenderingContext|sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext)} context
150 * @param program GL program object
151 * @param {Array<number>} color
153 es3fFboTestUtil.FlatColorShader.prototype.setColor = function(context, program, color) {
154 /** @type {number} */ var location = context.getUniformLocation(program, 'u_color');
156 context.useProgram(program);
157 context.uniform4fv(location, color);
161 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
162 * @param {Array<rrVertexPacket.VertexPacket>} packets
163 * @param {number} numPackets
165 es3fFboTestUtil.FlatColorShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
166 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
167 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
168 packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
169 packet.pointSize = this.m_pointSize;
174 * @param {Array<rrFragmentOperations.Fragment>} packet
175 * @param {rrShadingContext.FragmentShadingContext} context
177 es3fFboTestUtil.FlatColorShader.prototype.shadeFragments = function(packet, context) {
178 var numPackets = packet.length;
179 /** @const {Array<number>} */ var color = this.m_uniforms[0].value;
180 /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
181 /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
183 if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4) {
184 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx)
185 packet[packetNdx].value = color;
186 } else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4) {
187 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx)
188 packet[packetNdx].value = icolor;
189 } else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4) {
190 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx)
191 packet[packetNdx].value = uicolor;
193 throw new Error('Invalid output type: ' + this.m_outputType);
197 * es3fFboTestUtil.GradientShader inherits from sglrShaderProgram
199 * @extends {sglrShaderProgram.ShaderProgram}
200 * @param {gluShaderUtil.DataType} outputType
202 es3fFboTestUtil.GradientShader = function(outputType) {
203 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
204 var decl = new sglrShaderProgram.ShaderProgramDeclaration();
205 /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
206 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
207 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
208 decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
209 decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
210 decl.pushUniform(new sglrShaderProgram.Uniform('u_gradientMin', gluShaderUtil.DataType.FLOAT_VEC4));
211 decl.pushUniform(new sglrShaderProgram.Uniform('u_gradientMax', gluShaderUtil.DataType.FLOAT_VEC4));
212 decl.pushVertexSource(new sglrShaderProgram.VertexSource(
213 '#version 300 es\n' +
214 'in highp vec4 a_position;\n' +
215 'in highp vec4 a_coord;\n' +
216 'out highp vec4 v_coord;\n' +
217 'void main (void)\n' +
219 ' gl_Position = a_position;\n' +
220 ' v_coord = a_coord;\n' +
222 decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
223 '#version 300 es\n' +
224 'in highp vec4 v_coord;\n' +
225 'uniform highp vec4 u_gradientMin;\n' +
226 'uniform highp vec4 u_gradientMax;\n' +
227 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
228 'void main (void)\n' +
230 ' highp float x = v_coord.x;\n' +
231 ' highp float y = v_coord.y;\n' +
232 ' highp float f0 = (x + y) * 0.5;\n' +
233 ' highp float f1 = 0.5 + (x - y) * 0.5;\n' +
234 ' highp vec4 fv = vec4(f0, f1, 1.0f-f0, 1.0f-f1);\n' +
235 ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(u_gradientMin + (u_gradientMax-u_gradientMin)*fv);\n' +
237 sglrShaderProgram.ShaderProgram.call(this, decl);
240 es3fFboTestUtil.GradientShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
241 es3fFboTestUtil.GradientShader.prototype.constructor = es3fFboTestUtil.GradientShader;
244 * @param {es3fFboTestUtil.Context} ctx GL-like context
245 * @param program GL program
246 * @param {Array<number>} gradientMin
247 * @param {Array<number>} gradientMax
249 es3fFboTestUtil.GradientShader.prototype.setGradient = function(ctx, program, gradientMin, gradientMax) {
250 ctx.useProgram(program);
251 ctx.uniform4fv(ctx.getUniformLocation(program, 'u_gradientMin'), gradientMin);
252 ctx.uniform4fv(ctx.getUniformLocation(program, 'u_gradientMax'), gradientMax);
256 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
257 * @param {Array<rrVertexPacket.VertexPacket>} packets
258 * @param {number} numPackets
260 es3fFboTestUtil.GradientShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
261 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
262 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
264 packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
265 packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
270 * @param {Array<rrFragmentOperations.Fragment>} packet
271 * @param {rrShadingContext.FragmentShadingContext} context
273 es3fFboTestUtil.GradientShader.prototype.shadeFragments = function(packet, context) {
274 var numPackets = packet.length;
275 /** @const {Array<number>} */ var gradientMin = this.m_uniforms[0].value;
276 /** @const {Array<number>} */ var gradientMax = this.m_uniforms[1].value;
278 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
279 /** @const {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
280 /** @const {number} */ var x = coord[0];
281 /** @const {number} */ var y = coord[1];
282 /** @const {number} */ var f0 = (x + y) * 0.5;
283 /** @const {number} */ var f1 = 0.5 + (x - y) * 0.5;
284 /** @const {Array<number>} */ var fv = [f0, f1, 1.0 - f0, 1.0 - f1];
286 /** @const {Array<number>} */ var color = deMath.add(gradientMin, deMath.multiply(deMath.subtract(gradientMax, gradientMin), fv));
287 /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
288 /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
290 if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
291 packet[packetNdx].value = color;
292 else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
293 packet[packetNdx].value = icolor;
294 else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
295 packet[packetNdx].value = uicolor;
297 throw new Error('Invalid output type: ' + this.m_outputType);
302 * @param {Array<gluShaderUtil.DataType>} samplerTypes
303 * @param {gluShaderUtil.DataType} outputType
306 es3fFboTestUtil.genTexFragmentShader = function(samplerTypes, outputType) {
307 /** @type {string} */ var precision = 'highp';
308 /** @type {string} */ var src = '';
310 src = '#version 300 es\n' +
311 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color0;\n' +
312 'in highp vec2 v_coord;\n';
314 for (var samplerNdx = 0; samplerNdx < samplerTypes.length; samplerNdx++) {
315 src += 'uniform ' + precision + ' ' + gluShaderUtil.getDataTypeName(samplerTypes[samplerNdx]) + ' u_sampler' + samplerNdx + ';\n' +
316 'uniform ' + precision + ' vec4 u_texScale' + samplerNdx + ';\n' +
317 'uniform ' + precision + ' vec4 u_texBias' + samplerNdx + ';\n';
320 // Output scale & bias
321 src += 'uniform ' + precision + ' vec4 u_outScale0;\n' +
322 'uniform ' + precision + ' vec4 u_outBias0;\n';
325 'void main (void)\n' +
327 ' ' + precision + ' vec4 out0 = vec4(0.0);\n';
329 // Texture input fetch and combine.
330 for (var inNdx = 0; inNdx < samplerTypes.length; inNdx++)
331 src += '\tout0 += vec4(' +
332 'texture(u_sampler' + inNdx + ', v_coord)) * u_texScale' + inNdx + ' + u_texBias' + inNdx + ';\n';
335 src += ' o_color0 = ' + gluShaderUtil.getDataTypeName(outputType) + '(out0 * u_outScale0 + u_outBias0);\n' +
342 * @param {Array<gluShaderUtil.DataType>} samplerTypes
343 * @param {gluShaderUtil.DataType} outputType
344 * @return {sglrShaderProgram.ShaderProgramDeclaration}
346 es3fFboTestUtil.genTexture2DShaderDecl = function(samplerTypes, outputType) {
347 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
348 var decl = new sglrShaderProgram.ShaderProgramDeclaration();
350 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
351 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
352 decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
353 decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
355 decl.pushVertexSource(new sglrShaderProgram.VertexSource(
356 '#version 300 es\n' +
357 'in highp vec4 a_position;\n' +
358 'in highp vec2 a_coord;\n' +
359 'out highp vec2 v_coord;\n' +
360 'void main(void)\n' +
362 ' gl_Position = a_position;\n' +
363 ' v_coord = a_coord;\n' +
366 decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(es3fFboTestUtil.genTexFragmentShader(samplerTypes, outputType)));
368 decl.pushUniform(new sglrShaderProgram.Uniform('u_outScale0', gluShaderUtil.DataType.FLOAT_VEC4));
369 decl.pushUniform(new sglrShaderProgram.Uniform('u_outBias0', gluShaderUtil.DataType.FLOAT_VEC4));
371 for (var ndx = 0; ndx < samplerTypes.length; ++ndx) {
372 decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler' + ndx, samplerTypes[ndx]));
373 decl.pushUniform(new sglrShaderProgram.Uniform('u_texScale' + ndx, gluShaderUtil.DataType.FLOAT_VEC4));
374 decl.pushUniform(new sglrShaderProgram.Uniform('u_texBias' + ndx, gluShaderUtil.DataType.FLOAT_VEC4));
381 * For use in es3fFboTestUtil.Texture2DShader
384 es3fFboTestUtil.Input = function() {
385 /** @type {number} */ this.unitNdx;
386 /** @type {Array<number>} */ this.scale;
387 /** @type {Array<number>} */ this.bias;
391 * es3fFboTestUtil.Texture2DShader inherits from sglrShaderProgram
393 * @extends {sglrShaderProgram.ShaderProgram}
394 * @param {Array<gluShaderUtil.DataType>} samplerTypes
395 * @param {gluShaderUtil.DataType} outputType
396 * @param {Array<number>=} outScale - default [1.0, 1.0, 1.0, 1.0]
397 * @param {Array<number>=} outBias - default [0.0, 0.0, 0.0, 0.0]
399 es3fFboTestUtil.Texture2DShader = function(samplerTypes, outputType, outScale, outBias) {
400 if (outScale === undefined) outScale = [1.0, 1.0, 1.0, 1.0];
401 if (outBias === undefined) outBias = [0.0, 0.0, 0.0, 0.0];
402 sglrShaderProgram.ShaderProgram.call(this, es3fFboTestUtil.genTexture2DShaderDecl(samplerTypes, outputType));
403 /** @type {Array<es3fFboTestUtil.Input>} */ this.m_inputs = [];
404 /** @type {Array<number>} */ this.m_outScale = outScale;
405 /** @type {Array<number>} */ this.m_outBias = outBias;
406 /** @const {gluShaderUtil.DataType} */ this.m_outputType = outputType;
407 for (var ndx = 0; ndx < samplerTypes.length; ndx++) {
408 var input = new es3fFboTestUtil.Input();
410 input.scale = [1.0, 1.0, 1.0, 1.0];
411 input.bias = [0.0, 0.0, 0.0, 0.0];
412 this.m_inputs[ndx] = input;
416 es3fFboTestUtil.Texture2DShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
417 es3fFboTestUtil.Texture2DShader.prototype.constructor = es3fFboTestUtil.Texture2DShader;
420 * @param {number} inputNdx
421 * @param {number} unitNdx
423 es3fFboTestUtil.Texture2DShader.prototype.setUnit = function(inputNdx, unitNdx) {
424 this.m_inputs[inputNdx].unitNdx = unitNdx;
428 * @param {number} inputNdx
429 * @param {Array<number>} scale
430 * @param {Array<number>} bias
432 es3fFboTestUtil.Texture2DShader.prototype.setTexScaleBias = function(inputNdx, scale, bias) {
433 this.m_inputs[inputNdx].scale = scale;
434 this.m_inputs[inputNdx].bias = bias;
438 * @param {Array<number>} scale
439 * @param {Array<number>} bias
441 es3fFboTestUtil.Texture2DShader.prototype.setOutScaleBias = function(scale, bias) {
442 this.m_outScale = scale;
443 this.m_outBias = bias;
447 * @param context GL-like context
450 es3fFboTestUtil.Texture2DShader.prototype.setUniforms = function(context, program) {
451 context.useProgram(program);
453 for (var texNdx = 0; texNdx < this.m_inputs.length; texNdx++) {
454 /** @type {string} */ var samplerName = 'u_sampler' + texNdx;
455 /** @type {string} */ var scaleName = 'u_texScale' + texNdx;
456 /** @type {string} */ var biasName = 'u_texBias' + texNdx;
458 context.uniform1i(context.getUniformLocation(program, samplerName), this.m_inputs[texNdx].unitNdx);
459 context.uniform4fv(context.getUniformLocation(program, scaleName), this.m_inputs[texNdx].scale);
460 context.uniform4fv(context.getUniformLocation(program, biasName), this.m_inputs[texNdx].bias);
463 context.uniform4fv(context.getUniformLocation(program, 'u_outScale0'), this.m_outScale);
464 context.uniform4fv(context.getUniformLocation(program, 'u_outBias0'), this.m_outBias);
468 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
469 * @param {Array<rrVertexPacket.VertexPacket>} packets
470 * @param {number} numPackets
472 es3fFboTestUtil.Texture2DShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
473 // TODO: implement rrVertexAttrib.readVertexAttribFloat
474 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
475 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
476 packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
477 packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
482 * @param {Array<rrFragmentOperations.Fragment>} packet
483 * @param {rrShadingContext.FragmentShadingContext} context
485 es3fFboTestUtil.Texture2DShader.prototype.shadeFragments = function(packet, context) {
486 var numPackets = packet.length;
487 /** @type {Array<number>} */ var outScale = this.m_uniforms[0].value;
488 /** @type {Array<number>} */ var outBias = this.m_uniforms[1].value;
492 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
494 /** @const {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
495 texCoords = [coord[0], coord[1]];
498 colors = [0.0, 0.0, 0.0, 0.0];
500 // sample each texture
501 for (var ndx = 0; ndx < this.m_inputs.length; ndx++) {
502 var tex = this.m_uniforms[2 + ndx * 3].sampler;
503 var ratioX = tex.m_view.getWidth() / context.getWidth();
504 var ratioY = tex.m_view.getHeight() / context.getHeight();
505 var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
507 /** @const {Array<number>} */ var scale = this.m_uniforms[2 + ndx * 3 + 1].value;
508 /** @const {Array<number>} */ var bias = this.m_uniforms[2 + ndx * 3 + 2].value;
510 var tmpColors = tex.sample(texCoords, lod);
512 colors = deMath.add(colors, deMath.add(deMath.multiply(tmpColors, scale), bias));
516 /** @const {Array<number>} */ var color = deMath.add(deMath.multiply(colors, outScale), outBias);
517 /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
518 /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
520 if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
521 packet[packetNdx].value = color;
522 else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
523 packet[packetNdx].value = icolor;
524 else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
525 packet[packetNdx].value = uicolor;
530 * es3fFboTestUtil.TextureCubeShader inherits from sglrShaderProgram
532 * @extends {sglrShaderProgram.ShaderProgram}
533 * @param {gluShaderUtil.DataType} samplerType
534 * @param {gluShaderUtil.DataType} outputType
536 es3fFboTestUtil.TextureCubeShader = function(samplerType, outputType) {
537 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
538 var decl = new sglrShaderProgram.ShaderProgramDeclaration();
539 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
540 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
541 decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
542 decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
543 decl.pushUniform(new sglrShaderProgram.Uniform('u_coordMat', gluShaderUtil.DataType.FLOAT_MAT3));
544 decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler0', samplerType));
545 decl.pushUniform(new sglrShaderProgram.Uniform('u_scale', gluShaderUtil.DataType.FLOAT_VEC4));
546 decl.pushUniform(new sglrShaderProgram.Uniform('u_bias', gluShaderUtil.DataType.FLOAT_VEC4));
547 decl.pushVertexSource(new sglrShaderProgram.VertexSource(
548 '#version 300 es\n' +
549 'in highp vec4 a_position;\n' +
550 'in mediump vec2 a_coord;\n' +
551 'uniform mat3 u_coordMat;\n' +
552 'out mediump vec3 v_coord;\n' +
553 'void main (void)\n' +
555 ' gl_Position = a_position;\n' +
556 ' v_coord = u_coordMat * vec3(a_coord, 1.0);\n' +
558 decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
559 '#version 300 es\n' +
560 'uniform highp ' + gluShaderUtil.getDataTypeName(samplerType) + ' u_sampler0;\n' +
561 'uniform highp vec4 u_scale;\n' +
562 'uniform highp vec4 u_bias;\n' +
563 'in mediump vec3 v_coord;\n' +
564 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
565 'void main (void)\n' +
567 ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(vec4(texture(u_sampler0, v_coord)) * u_scale + u_bias);\n' +
569 sglrShaderProgram.ShaderProgram.call(this, decl);
570 /** @type {Array<number>} */ this.m_texScale = [1.0, 1.0, 1.0, 1.0];
571 /** @type {Array<number>} */ this.m_texBias = [0.0, 0.0, 0.0, 0.0];
572 /** @type {tcuMatrix.Mat3} */ this.m_coordMat;
573 /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
576 es3fFboTestUtil.TextureCubeShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
577 es3fFboTestUtil.TextureCubeShader.prototype.constructor = es3fFboTestUtil.TextureCubeShader;
580 * @param {tcuTexture.CubeFace} face
582 es3fFboTestUtil.TextureCubeShader.prototype.setFace = function(face) {
583 /** @const {Array<Array<number>>} */ var s_cubeTransforms = [
584 // Face -X: (x, y, 1) -> (-1, -(2*y-1), +(2*x-1))
588 // Face +X: (x, y, 1) -> (+1, -(2*y-1), -(2*x-1))
592 // Face -Y: (x, y, 1) -> (+(2*x-1), -1, -(2*y-1))
596 // Face +Y: (x, y, 1) -> (+(2*x-1), +1, +(2*y-1))
600 // Face -Z: (x, y, 1) -> (-(2*x-1), -(2*y-1), -1)
604 // Face +Z: (x, y, 1) -> (+(2*x-1), -(2*y-1), +1)
608 this.m_coordMat = /** @type {tcuMatrix.Mat3} */ (tcuMatrix.matrixFromArray(3, 3, s_cubeTransforms[face]));
612 * @param {Array<number>} scale
613 * @param {Array<number>} bias
615 es3fFboTestUtil.TextureCubeShader.prototype.setTexScaleBias = function(scale, bias) {
616 this.m_texScale = scale;
617 this.m_texBias = bias;
621 * @param ctx GL-like context
624 es3fFboTestUtil.TextureCubeShader.prototype.setUniforms = function(ctx, program) {
625 ctx.useProgram(program);
627 ctx.uniform1i(ctx.getUniformLocation(program, 'u_sampler0'), 0);
628 ctx.uniformMatrix3fv(ctx.getUniformLocation(program, 'u_coordMat'), false, this.m_coordMat.getColumnMajorData());
629 ctx.uniform4fv(ctx.getUniformLocation(program, 'u_scale'), this.m_texScale);
630 ctx.uniform4fv(ctx.getUniformLocation(program, 'u_bias'), this.m_texBias);
634 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
635 * @param {Array<rrVertexPacket.VertexPacket>} packets
636 * @param {number} numPackets
638 es3fFboTestUtil.TextureCubeShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
639 /** @type {tcuMatrix.Matrix} */ var texCoordMat = tcuMatrix.matrixFromArray(3, 3, this.m_uniforms[0].value);
641 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
642 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
643 var x = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT)[0];
644 var y = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT)[1];
645 /** @type {Array<number>} */ var a_coord = [x, y];
646 /** @type {Array<number>} */ var v_coord = tcuMatrix.multiplyMatVec(texCoordMat, [a_coord[0], a_coord[1], 1.0]);
648 packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
649 packet.outputs[0] = [v_coord[0], v_coord[1], v_coord[2], 0.0];
654 * @param {Array<rrFragmentOperations.Fragment>} packet
655 * @param {rrShadingContext.FragmentShadingContext} context
657 es3fFboTestUtil.TextureCubeShader.prototype.shadeFragments = function(packet, context) {
658 var numPackets = packet.length;
659 /** @const {Array<number>} */ var texScale = this.m_uniforms[2].value;
660 /** @const {Array<number>} */ var texBias = this.m_uniforms[3].value;
665 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
666 var tex = this.m_uniforms[1].sampler;
667 var ratioX = tex.m_view.getSize() / context.getWidth();
668 var ratioY = tex.m_view.getSize() / context.getHeight();
669 var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
671 var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
672 texCoords = [coord[0], coord[1], coord[2]];
674 colors = tex.sample(texCoords, lod);
676 var color = deMath.add(deMath.multiply(colors, texScale), texBias);
677 var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
678 var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
680 if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
681 packet[packetNdx].value = color;
682 else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
683 packet[packetNdx].value = icolor;
684 else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
685 packet[packetNdx].value = uicolor;
690 * es3fFboTestUtil.Texture2DArrayShader inherits from sglrShaderProgram
692 * @extends {sglrShaderProgram.ShaderProgram}
693 * @param {gluShaderUtil.DataType} samplerType
694 * @param {gluShaderUtil.DataType} outputType
696 es3fFboTestUtil.Texture2DArrayShader = function(samplerType, outputType) {
697 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
698 var decl = new sglrShaderProgram.ShaderProgramDeclaration();
699 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
700 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
701 decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
702 decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
703 decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler0', samplerType));
704 decl.pushUniform(new sglrShaderProgram.Uniform('u_scale', gluShaderUtil.DataType.FLOAT_VEC4));
705 decl.pushUniform(new sglrShaderProgram.Uniform('u_bias', gluShaderUtil.DataType.FLOAT_VEC4));
706 decl.pushUniform(new sglrShaderProgram.Uniform('u_layer', gluShaderUtil.DataType.INT));
707 decl.pushVertexSource(new sglrShaderProgram.VertexSource(
708 '#version 300 es\n' +
709 'in highp vec4 a_position;\n' +
710 'in highp vec2 a_coord;\n' +
711 'out highp vec2 v_coord;\n' +
712 'void main (void)\n' +
714 ' gl_Position = a_position;\n' +
715 ' v_coord = a_coord;\n' +
717 decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
718 '#version 300 es\n' +
719 'uniform highp ' + gluShaderUtil.getDataTypeName(samplerType) + ' u_sampler0;\n' +
720 'uniform highp vec4 u_scale;\n' +
721 'uniform highp vec4 u_bias;\n' +
722 'uniform highp int u_layer;\n' +
723 'in highp vec2 v_coord;\n' +
724 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
725 'void main (void)\n' +
727 ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(vec4(texture(u_sampler0, vec3(v_coord, u_layer))) * u_scale + u_bias);\n' +
729 sglrShaderProgram.ShaderProgram.call(this, decl);
730 /** @type {Array<number>} */ this.m_texScale = [1.0, 1.0, 1.0, 1.0];
731 /** @type {Array<number>} */ this.m_texBias = [0.0, 0.0, 0.0, 0.0];
732 /** @type {number} */ this.m_layer = 0;
733 /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
736 es3fFboTestUtil.Texture2DArrayShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
737 es3fFboTestUtil.Texture2DArrayShader.prototype.constructor = es3fFboTestUtil.Texture2DArrayShader;
740 * @param {number} layer
742 es3fFboTestUtil.Texture2DArrayShader.prototype.setLayer = function(layer) {
743 this.m_layer = layer;
746 * @param {Array<number>} scale
747 * @param {Array<number>} bias
749 es3fFboTestUtil.Texture2DArrayShader.prototype.setTexScaleBias = function(scale, bias) {
750 this.m_texScale = scale;
751 this.m_texBias = bias;
754 * @param {es3fFboTestUtil.Context} ctx GL-like context
757 es3fFboTestUtil.Texture2DArrayShader.prototype.setUniforms = function(ctx, program) {
758 ctx.useProgram(program);
760 ctx.uniform1i(ctx.getUniformLocation(program, 'u_sampler0'), 0);
761 ctx.uniform1i(ctx.getUniformLocation(program, 'u_layer'), this.m_layer);
762 ctx.uniform4fv(ctx.getUniformLocation(program, 'u_scale'), this.m_texScale);
763 ctx.uniform4fv(ctx.getUniformLocation(program, 'u_bias'), this.m_texBias);
767 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
768 * @param {Array<rrVertexPacket.VertexPacket>} packets
769 * @param {number} numPackets
771 es3fFboTestUtil.Texture2DArrayShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
772 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
773 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
775 packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
776 packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
781 * @param {Array<rrFragmentOperations.Fragment>} packet
782 * @param {rrShadingContext.FragmentShadingContext} context
784 es3fFboTestUtil.Texture2DArrayShader.prototype.shadeFragments = function(packet, context) {
785 var numPackets = packet.length;
786 /** @const {Array<number>} */ var texScale = this.m_uniforms[1].value;
787 /** @const {Array<number>} */ var texBias = this.m_uniforms[2].value;
788 /** @const {number} */ var layer = this.m_uniforms[3].value[0];
793 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
794 var tex = this.m_uniforms[0].sampler;
795 var ratioX = tex.m_view.getWidth() / context.getWidth();
796 var ratioY = tex.m_view.getHeight() / context.getHeight();
797 var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
799 /** @const {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
800 texCoords = [coord[0], coord[1], layer];
802 colors = tex.sample(texCoords, lod);
804 /** @const {Array<number>} */ var color = deMath.add(deMath.multiply(colors, texScale), texBias);
805 /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
806 /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
808 if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
809 packet[packetNdx].value = color;
810 else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
811 packet[packetNdx].value = icolor;
812 else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
813 packet[packetNdx].value = uicolor;
818 * es3fFboTestUtil.Texture3DShader inherits from sglrShaderProgram
820 * @extends {sglrShaderProgram.ShaderProgram}
821 * @param {gluShaderUtil.DataType} samplerType
822 * @param {gluShaderUtil.DataType} outputType
824 es3fFboTestUtil.Texture3DShader = function(samplerType, outputType) {
825 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
826 var decl = new sglrShaderProgram.ShaderProgramDeclaration();
827 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
828 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
829 decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
830 decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
831 decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler0', samplerType));
832 decl.pushUniform(new sglrShaderProgram.Uniform('u_scale', gluShaderUtil.DataType.FLOAT_VEC4));
833 decl.pushUniform(new sglrShaderProgram.Uniform('u_bias', gluShaderUtil.DataType.FLOAT_VEC4));
834 decl.pushUniform(new sglrShaderProgram.Uniform('u_depth', gluShaderUtil.DataType.FLOAT));
835 decl.pushVertexSource(new sglrShaderProgram.VertexSource(
836 '#version 300 es\n' +
837 'in highp vec4 a_position;\n' +
838 'in highp vec2 a_coord;\n' +
839 'out highp vec2 v_coord;\n' +
840 'void main (void)\n' +
842 ' gl_Position = a_position;\n' +
843 ' v_coord = a_coord;\n' +
845 decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
846 '#version 300 es\n' +
847 'uniform highp ' + gluShaderUtil.getDataTypeName(samplerType) + ' u_sampler0;\n' +
848 'uniform highp vec4 u_scale;\n' +
849 'uniform highp vec4 u_bias;\n' +
850 'uniform highp float u_depth;\n' +
851 'in highp vec2 v_coord;\n' +
852 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
853 'void main (void)\n' +
855 ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(vec4(texture(u_sampler0, vec3(v_coord, u_depth))) * u_scale + u_bias);\n' +
857 sglrShaderProgram.ShaderProgram.call(this, decl);
858 /** @type {Array<number>} */ this.m_texScale = [1.0, 1.0, 1.0, 1.0];
859 /** @type {Array<number>} */ this.m_texBias = [0.0, 0.0, 0.0, 0.0];
860 /** @type {number} */ this.m_depth = 0.0;
861 /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
864 es3fFboTestUtil.Texture3DShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
865 es3fFboTestUtil.Texture3DShader.prototype.constructor = es3fFboTestUtil.Texture3DShader;
868 * @param {number} depth
870 es3fFboTestUtil.Texture3DShader.prototype.setDepth = function(depth) {
871 this.m_depth = depth;
875 * @param {Array<number>} scale
876 * @param {Array<number>} bias
878 es3fFboTestUtil.Texture3DShader.prototype.setTexScaleBias = function(scale, bias) {
879 this.m_texScale = scale;
880 this.m_texBias = bias;
884 * @param context GL-like context
887 es3fFboTestUtil.Texture3DShader.prototype.setUniforms = function(context, program) {
888 context.useProgram(program);
889 context.uniform1i(context.getUniformLocation(program, 'u_sampler0'), 0);
890 context.uniform1f(context.getUniformLocation(program, 'u_depth'), this.m_depth);
891 context.uniform4fv(context.getUniformLocation(program, 'u_scale'), this.m_texScale);
892 context.uniform4fv(context.getUniformLocation(program, 'u_bias'), this.m_texBias);
896 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
897 * @param {Array<rrVertexPacket.VertexPacket>} packets
898 * @param {number} numPackets
900 es3fFboTestUtil.Texture3DShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
901 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
902 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
904 packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
905 packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
910 * @param {Array<rrFragmentOperations.Fragment>} packet
911 * @param {rrShadingContext.FragmentShadingContext} context
913 es3fFboTestUtil.Texture3DShader.prototype.shadeFragments = function(packet, context) {
914 var numPackets = packet.length;
915 /** @const {Array<number>} */ var texScale = this.m_uniforms[1].value;
916 /** @const {Array<number>} */ var texBias = this.m_uniforms[2].value;
917 /** @const {number} */ var depth = this.m_uniforms[3].value[0];
922 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
923 var tex = this.m_uniforms[0].sampler;
924 var ratioX = tex.m_view.getWidth() / context.getWidth();
925 var ratioY = tex.m_view.getHeight() / context.getHeight();
926 // TODO: what to do with Z coordinate?
927 var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
929 var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
930 texCoords = [coord[0], coord[1], depth];
932 colors = tex.sample(texCoords, lod);
934 /** @const {Array<number>} */ var color = deMath.add(deMath.multiply(colors, texScale), texBias);
935 /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
936 /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
938 if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
939 packet[packetNdx].value = color;
940 else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
941 packet[packetNdx].value = icolor;
942 else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
943 packet[packetNdx].value = uicolor;
948 * es3fFboTestUtil.DepthGradientShader inherits from sglrShaderProgram
950 * @extends {sglrShaderProgram.ShaderProgram}
951 * @param {gluShaderUtil.DataType} outputType
953 es3fFboTestUtil.DepthGradientShader = function(outputType) {
954 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
955 var decl = new sglrShaderProgram.ShaderProgramDeclaration();
956 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
957 decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
958 decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
959 decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
960 decl.pushUniform(new sglrShaderProgram.Uniform('u_maxGradient', gluShaderUtil.DataType.FLOAT));
961 decl.pushUniform(new sglrShaderProgram.Uniform('u_minGradient', gluShaderUtil.DataType.FLOAT));
962 decl.pushUniform(new sglrShaderProgram.Uniform('u_color', gluShaderUtil.DataType.FLOAT_VEC4));
963 decl.pushVertexSource(new sglrShaderProgram.VertexSource(
964 '#version 300 es\n' +
965 'in highp vec4 a_position;\n' +
966 'in highp vec4 a_coord;\n' +
967 'out highp vec4 v_coord;\n' +
968 'void main (void)\n' +
970 ' gl_Position = a_position;\n' +
971 ' v_coord = a_coord;\n' +
973 decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
974 '#version 300 es\n' +
975 'in highp vec4 v_coord;\n' +
976 'uniform highp float u_minGradient;\n' +
977 'uniform highp float u_maxGradient;\n' +
978 'uniform highp vec4 u_color;\n' +
979 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
980 'void main (void)\n' +
982 ' highp float x = v_coord.x;\n' +
983 ' highp float y = v_coord.y;\n' +
984 ' highp float f0 = (x + y) * 0.5;\n' +
985 ' gl_FragDepth = u_minGradient + (u_maxGradient-u_minGradient)*f0;\n' +
986 ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(u_color);\n' +
988 this.m_outputType = outputType;
989 sglrShaderProgram.ShaderProgram.call(this, decl);
990 /** @const {sglrShaderProgram.Uniform} */ this.u_minGradient = this.getUniformByName('u_minGradient');
991 /** @const {sglrShaderProgram.Uniform} */ this.u_maxGradient = this.getUniformByName('u_maxGradient');
992 /** @const {sglrShaderProgram.Uniform} */ this.u_color = this.getUniformByName('u_color');
995 es3fFboTestUtil.DepthGradientShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
996 es3fFboTestUtil.DepthGradientShader.prototype.constructor = es3fFboTestUtil.DepthGradientShader;
999 * @param ctx GL-like context
1001 * @param {number} gradientMin
1002 * @param {number} gradientMax
1003 * @param {Array<number>} color
1005 es3fFboTestUtil.DepthGradientShader.prototype.setUniforms = function(ctx, program, gradientMin, gradientMax, color) {
1006 ctx.useProgram(program);
1007 ctx.uniform1fv(ctx.getUniformLocation(program, 'u_minGradient'), [gradientMin]);
1008 ctx.uniform1fv(ctx.getUniformLocation(program, 'u_maxGradient'), [gradientMax]);
1009 ctx.uniform4fv(ctx.getUniformLocation(program, 'u_color'), color);
1013 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
1014 * @param {Array<rrVertexPacket.VertexPacket>} packets
1015 * @param {number} numPackets
1017 es3fFboTestUtil.DepthGradientShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
1018 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
1019 /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
1021 packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
1022 packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
1027 * @param {Array<rrFragmentOperations.Fragment>} packet
1028 * @param {rrShadingContext.FragmentShadingContext} context
1030 es3fFboTestUtil.DepthGradientShader.prototype.shadeFragments = function(packet, context) {
1031 var numPackets = packet.length;
1032 /** @const {number} */ var gradientMin = this.u_minGradient.value[0];
1033 /** @const {number} */ var gradientMax = this.u_maxGradient.value[0];
1034 /** @type {Array<number>} */ var color = this.u_color.value;
1035 /** @type {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
1036 /** @type {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
1038 for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
1039 /** @type {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
1040 /** @const {number} */ var x = coord[0];
1041 /** @const {number} */ var y = coord[1];
1042 /** @const {number} */ var f0 = (x + y) * 0.5;
1044 packet[packetNdx].sampleDepths[0] = gradientMin + (gradientMax - gradientMin) * f0;
1046 if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
1047 packet[packetNdx].value = color;
1048 else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
1049 packet[packetNdx].value = icolor;
1050 else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
1051 packet[packetNdx].value = uicolor;
1055 es3fFboTestUtil.getFormatName = function(format) {
1057 case gl.RGB565: return 'rgb565';
1058 case gl.RGB5_A1: return 'rgb5_a1';
1059 case gl.RGBA4: return 'rgba4';
1060 case gl.DEPTH_COMPONENT16: return 'depth_component16';
1061 case gl.STENCIL_INDEX8: return 'stencil_index8';
1062 case gl.RGBA32F: return 'rgba32f';
1063 case gl.RGBA32I: return 'rgba32i';
1064 case gl.RGBA32UI: return 'rgba32ui';
1065 case gl.RGBA16F: return 'rgba16f';
1066 case gl.RGBA16I: return 'rgba16i';
1067 case gl.RGBA16UI: return 'rgba16ui';
1068 case gl.RGBA8: return 'rgba8';
1069 case gl.RGBA8I: return 'rgba8i';
1070 case gl.RGBA8UI: return 'rgba8ui';
1071 case gl.SRGB8_ALPHA8: return 'srgb8_alpha8';
1072 case gl.RGB10_A2: return 'rgb10_a2';
1073 case gl.RGB10_A2UI: return 'rgb10_a2ui';
1074 case gl.RGBA8_SNORM: return 'rgba8_snorm';
1075 case gl.RGB8: return 'rgb8';
1076 case gl.R11F_G11F_B10F: return 'r11f_g11f_b10f';
1077 case gl.RGB32F: return 'rgb32f';
1078 case gl.RGB32I: return 'rgb32i';
1079 case gl.RGB32UI: return 'rgb32ui';
1080 case gl.RGB16F: return 'rgb16f';
1081 case gl.RGB16I: return 'rgb16i';
1082 case gl.RGB16UI: return 'rgb16ui';
1083 case gl.RGB8_SNORM: return 'rgb8_snorm';
1084 case gl.RGB8I: return 'rgb8i';
1085 case gl.RGB8UI: return 'rgb8ui';
1086 case gl.SRGB8: return 'srgb8';
1087 case gl.RGB9_E5: return 'rgb9_e5';
1088 case gl.RG32F: return 'rg32f';
1089 case gl.RG32I: return 'rg32i';
1090 case gl.RG32UI: return 'rg32ui';
1091 case gl.RG16F: return 'rg16f';
1092 case gl.RG16I: return 'rg16i';
1093 case gl.RG16UI: return 'rg16ui';
1094 case gl.RG8: return 'rg8';
1095 case gl.RG8I: return 'rg8i';
1096 case gl.RG8UI: return 'rg8ui';
1097 case gl.RG8_SNORM: return 'rg8_snorm';
1098 case gl.R32F: return 'r32f';
1099 case gl.R32I: return 'r32i';
1100 case gl.R32UI: return 'r32ui';
1101 case gl.R16F: return 'r16f';
1102 case gl.R16I: return 'r16i';
1103 case gl.R16UI: return 'r16ui';
1104 case gl.R8: return 'r8';
1105 case gl.R8I: return 'r8i';
1106 case gl.R8UI: return 'r8ui';
1107 case gl.R8_SNORM: return 'r8_snorm';
1108 case gl.DEPTH_COMPONENT32F: return 'depth_component32f';
1109 case gl.DEPTH_COMPONENT24: return 'depth_component24';
1110 case gl.DEPTH32F_STENCIL8: return 'depth32f_stencil8';
1111 case gl.DEPTH24_STENCIL8: return 'depth24_stencil8';
1114 throw new Error('Unknown format in getFromatName()');
1119 * @param {tcuTexture.TextureFormat} format
1120 * @return {gluShaderUtil.DataType}
1122 es3fFboTestUtil.getFragmentOutputType = function(format) {
1123 switch (tcuTexture.getTextureChannelClass(format.type)) {
1124 case tcuTexture.TextureChannelClass.FLOATING_POINT:
1125 case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
1126 case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
1127 return gluShaderUtil.DataType.FLOAT_VEC4;
1129 case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
1130 return gluShaderUtil.DataType.UINT_VEC4;
1132 case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
1133 return gluShaderUtil.DataType.INT_VEC4;
1136 throw new Error('Unknown format');
1141 * @param {tcuTexture.TextureFormat} format
1142 * @return {tcuTexture.TextureFormat}
1144 es3fFboTestUtil.getFramebufferReadFormat = function(format) {
1145 switch (tcuTexture.getTextureChannelClass(format.type)) {
1146 case tcuTexture.TextureChannelClass.FLOATING_POINT:
1147 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.FLOAT);
1149 case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
1150 case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
1151 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8);
1153 case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
1154 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT32);
1156 case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
1157 return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT32);
1160 throw new Error('Unknown format in es3fFboTestUtil.getFramebufferReadFormat()');
1165 * @param {es3fFboTestUtil.Context} ctx GL-like context
1166 * @param {tcuTexture.TextureFormat} format
1167 * @param {Array<number>} value
1169 es3fFboTestUtil.clearColorBuffer = function(ctx, format, value) {
1170 /** @const @type {tcuTexture.TextureChannelClass} */
1171 var fmtClass = tcuTexture.getTextureChannelClass(format.type);
1174 case tcuTexture.TextureChannelClass.FLOATING_POINT:
1175 case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
1176 case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
1177 ctx.clearBufferfv(gl.COLOR, 0, value);
1180 case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
1181 ctx.clearBufferuiv(gl.COLOR, 0, value);
1184 case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
1185 ctx.clearBufferiv(gl.COLOR, 0, value);
1189 throw new Error('Invalid channel class: ' + fmtClass);
1194 * @param {tcuTexture.TextureFormat} format
1195 * @return {tcuRGBA.RGBA}
1197 es3fFboTestUtil.getThresholdFromTextureFormat = function(format) {
1198 /** @const @type {Array<number>} */ var bits = tcuTextureUtil.getTextureFormatMantissaBitDepth(format);
1199 return tcuRGBA.newRGBAComponents(
1200 es3fFboTestUtil.calculateU8ConversionError(bits[0]),
1201 es3fFboTestUtil.calculateU8ConversionError(bits[1]),
1202 es3fFboTestUtil.calculateU8ConversionError(bits[2]),
1203 es3fFboTestUtil.calculateU8ConversionError(bits[3])
1208 * @param {number} glFormat
1209 * @return {tcuRGBA.RGBA}
1211 es3fFboTestUtil.getFormatThreshold = function(glFormat) {
1212 /** @const @type {tcuTexture.TextureFormat} */ var format = gluTextureUtil.mapGLInternalFormat(glFormat);
1213 return es3fFboTestUtil.getThresholdFromTextureFormat(format);
1217 * @param {number} srcBits
1220 es3fFboTestUtil.getToSRGB8ConversionError = function(srcBits) {
1221 // \note These are pre-computed based on simulation results.
1222 /** @const @type {Array<number>} */ var errors = [
1223 1, // 0 bits - rounding
1239 DE_ASSERT(srcBits >= 0);
1240 if (srcBits < errors.length)
1241 return errors[srcBits];
1247 * @param {tcuTexture.TextureFormat} src
1248 * @param {tcuTexture.TextureFormat} dst
1249 * @return {tcuRGBA.RGBA}
1251 es3fFboTestUtil.getToSRGBConversionThreshold = function(src, dst) {
1252 // Only SRGB8 and SRGB8_ALPHA8 formats are supported.
1253 DE_ASSERT(dst.type == tcuTexture.ChannelType.UNORM_INT8);
1254 DE_ASSERT(dst.order == tcuTexture.ChannelOrder.sRGB || dst.order == tcuTexture.ChannelOrder.sRGBA);
1256 /** @const @type {Array<number>} */ var bits = tcuTextureUtil.getTextureFormatMantissaBitDepth(src);
1257 /** @const @type {boolean} */ var dstHasAlpha = dst.order == tcuTexture.ChannelOrder.sRGBA;
1259 return tcuRGBA.newRGBAComponents(
1260 es3fFboTestUtil.getToSRGB8ConversionError(bits[0]),
1261 es3fFboTestUtil.getToSRGB8ConversionError(bits[1]),
1262 es3fFboTestUtil.getToSRGB8ConversionError(bits[2]),
1263 dstHasAlpha ? es3fFboTestUtil.calculateU8ConversionError(bits[3]) : 0);
1267 * es3fFboTestUtil.readPixels()
1268 * @param {(WebGL2RenderingContext|sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext)} ctx
1269 * @param {tcuSurface.Surface} dst
1272 * @param {number} width
1273 * @param {number} height
1274 * @param {tcuTexture.TextureFormat} format
1275 * @param {Array<number>} scale
1276 * @param {Array<number>} bias
1278 es3fFboTestUtil.readPixels = function(ctx, dst, x, y, width, height, format, scale, bias) {
1279 /** @type {tcuTexture.TextureFormat} */ var readFormat = es3fFboTestUtil.getFramebufferReadFormat(format);
1280 /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(readFormat);
1281 /** @type {number} */ var alignment = 4; // \note gl.PACK_ALIGNMENT = 4 is assumed.
1282 /** @type {number} */ var rowSize = deMath.deAlign32(readFormat.getPixelSize() * width, alignment);
1283 var typedArrayType = tcuTexture.getTypedArray(readFormat.type);
1284 var data = new typedArrayType(rowSize * height);
1285 ctx.readPixels(x, y, width, height, transferFmt.format, transferFmt.dataType, data);
1287 // Convert to surface.
1288 var cpbaDescriptor = {
1298 /** @type {tcuTexture.ConstPixelBufferAccess} */
1299 var src = new tcuTexture.ConstPixelBufferAccess(cpbaDescriptor);
1301 dst.setSize(width, height);
1302 /** @type {tcuTexture.PixelBufferAccess} */ var dstAccess = dst.getAccess();
1304 for (var yo = 0; yo < height; yo++)
1305 for (var xo = 0; xo < width; xo++)
1306 dstAccess.setPixel(deMath.add(deMath.multiply(src.getPixel(xo, yo), scale), bias), xo, yo);
1310 * @param {number} srcBits
1313 es3fFboTestUtil.calculateU8ConversionError = function(srcBits) {
1315 /** @const @type {number} */ var clampedBits = deMath.clamp(srcBits, 0, 8);
1316 /** @const @type {number} */ var srcMaxValue = Math.max((1 << clampedBits) - 1, 1);
1317 /** @const @type {number} */ var error = Math.floor(Math.ceil(255.0 * 2.0 / srcMaxValue));
1319 return deMath.clamp(error, 0, 255);