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.es3fShaderBuiltinVarTests');
23 goog
.require('framework.delibs.debase.deMath');
24 goog
.require('framework.delibs.debase.deRandom');
25 goog
.require('framework.delibs.debase.deString');
26 goog
.require('framework.common.tcuImageCompare');
27 goog
.require('framework.common.tcuLogImage');
28 goog
.require('framework.common.tcuPixelFormat');
29 goog
.require('framework.common.tcuRGBA');
30 goog
.require('framework.common.tcuSurface');
31 goog
.require('framework.common.tcuTestCase');
32 goog
.require('framework.common.tcuTexture');
33 goog
.require('framework.opengl.gluDrawUtil');
34 goog
.require('framework.opengl.gluShaderProgram');
35 goog
.require('framework.opengl.gluShaderUtil');
36 goog
.require('framework.opengl.gluVarType');
37 goog
.require('framework.opengl.simplereference.sglrReferenceContext');
38 goog
.require('framework.opengl.simplereference.sglrShaderProgram');
39 goog
.require('framework.referencerenderer.rrFragmentOperations');
40 goog
.require('framework.referencerenderer.rrGenericVector');
41 goog
.require('framework.referencerenderer.rrMultisamplePixelBufferAccess');
42 goog
.require('framework.referencerenderer.rrRenderer');
43 goog
.require('framework.referencerenderer.rrRenderState');
44 goog
.require('framework.referencerenderer.rrShadingContext');
45 goog
.require('framework.referencerenderer.rrVertexAttrib');
46 goog
.require('framework.referencerenderer.rrVertexPacket');
47 goog
.require('modules.shared.glsShaderRenderCase');
48 goog
.require('modules.shared.glsShaderExecUtil');
50 goog
.scope(function() {
51 var es3fShaderBuiltinVarTests
= functional
.gles3
.es3fShaderBuiltinVarTests
;
52 var deMath
= framework
.delibs
.debase
.deMath
;
53 var deString
= framework
.delibs
.debase
.deString
;
54 var deRandom
= framework
.delibs
.debase
.deRandom
;
55 var glsShaderExecUtil
= modules
.shared
.glsShaderExecUtil
;
56 var glsShaderRenderCase
= modules
.shared
.glsShaderRenderCase
;
57 var gluShaderProgram
= framework
.opengl
.gluShaderProgram
;
58 var gluShaderUtil
= framework
.opengl
.gluShaderUtil
;
59 var gluDrawUtil
= framework
.opengl
.gluDrawUtil
;
60 var gluVarType
= framework
.opengl
.gluVarType
;
61 var tcuPixelFormat
= framework
.common
.tcuPixelFormat
;
62 var tcuSurface
= framework
.common
.tcuSurface
;
63 var tcuTexture
= framework
.common
.tcuTexture
;
64 var tcuLogImage
= framework
.common
.tcuLogImage
;
65 var tcuTestCase
= framework
.common
.tcuTestCase
;
66 var tcuImageCompare
= framework
.common
.tcuImageCompare
;
67 var tcuRGBA
= framework
.common
.tcuRGBA
;
68 var rrGenericVector
= framework
.referencerenderer
.rrGenericVector
;
69 var rrFragmentOperations
= framework
.referencerenderer
.rrFragmentOperations
;
70 var rrMultisamplePixelBufferAccess
= framework
.referencerenderer
.rrMultisamplePixelBufferAccess
;
71 var rrRenderer
= framework
.referencerenderer
.rrRenderer
;
72 var rrRenderState
= framework
.referencerenderer
.rrRenderState
;
73 var rrShadingContext
= framework
.referencerenderer
.rrShadingContext
;
74 var rrVertexAttrib
= framework
.referencerenderer
.rrVertexAttrib
;
75 var rrVertexPacket
= framework
.referencerenderer
.rrVertexPacket
;
76 var sglrShaderProgram
= framework
.opengl
.simplereference
.sglrShaderProgram
;
77 var sglrReferenceContext
= framework
.opengl
.simplereference
.sglrReferenceContext
;
79 /** @typedef {function():number} */ es3fShaderBuiltinVarTests
.GetConstantValueFunc
;
82 * @param {number} pname
83 * @return {number} getParameter returns values of any kind
85 es3fShaderBuiltinVarTests
.getInteger = function(pname
) {
86 return /** @type {number} */ (gl
.getParameter(pname
));
90 * @param {number} pname
91 * @return {number} forcing number
93 es3fShaderBuiltinVarTests
.getVectorsFromComps = function(pname
) {
94 var value
= /** @type {number} */ (gl
.getParameter(pname
));
95 assertMsgOptions(value
%4 === 0, 'Expected value to be divisible by 4.', false, true);
101 * @extends {tcuTestCase.DeqpTest}
102 * @param {string} name
103 * @param {string} desc
104 * @param {string} varName
105 * @param {es3fShaderBuiltinVarTests.GetConstantValueFunc} getValue
106 * @param {gluShaderProgram.shaderType} shaderType
108 es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase = function(name
, desc
, varName
, getValue
, shaderType
) {
109 tcuTestCase
.DeqpTest
.call(this, name
, desc
);
110 /** @type {string} */ this.m_varName
= varName
;
111 /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ this.m_getValue
= getValue
;
112 /** @type {gluShaderProgram.shaderType} */ this.m_shaderType
= shaderType
;
115 es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
116 es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase
.prototype.constructor = es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase
;
118 es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase
.prototype.deinit = function() {
119 // an attempt to cleanup the GL state when the test fails
120 bufferedLogToConsole('ShaderBuildInConstantCase.deinit()');
122 gl
.bindBuffer(gl
.ARRAY_BUFFER
, null);
123 gl
.bindBuffer(gl
.ELEMENT_ARRAY_BUFFER
, null);
124 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
125 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, null);
129 * @param {gluShaderProgram.shaderType} shaderType
130 * @param {string} varName
131 * @return {glsShaderExecUtil.ShaderExecutor}
133 es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase
.prototype.createGetConstantExecutor = function(shaderType
, varName
) {
134 /** @type {glsShaderExecUtil.ShaderSpec} */ var shaderSpec
= new glsShaderExecUtil
.ShaderSpec();
135 shaderSpec
.version
= gluShaderUtil
.GLSLVersion
.V300_ES
;
136 shaderSpec
.source
= 'result = ' + varName
+ ';\n';
137 shaderSpec
.outputs
.push(new glsShaderExecUtil
.Symbol('result',
138 gluVarType
.newTypeBasic(gluShaderUtil
.DataType
.INT
, gluShaderUtil
.precision
.PRECISION_HIGHP
)));
139 return glsShaderExecUtil
.createExecutor(shaderType
, shaderSpec
);
144 * @return {tcuTestCase.IterateResult}
146 es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase
.prototype.iterate = function() {
147 /** @type {glsShaderExecUtil.ShaderExecutor} */
148 var shaderExecutor
= this.createGetConstantExecutor(this.m_shaderType
, this.m_varName
);
149 /** @type {number} */ var reference
= this.m_getValue();
150 /** @type {goog.NumberArray} */ var shaderExecutorResult
;
151 /** @type {number} */ var result
;
153 if (!shaderExecutor
.isOk())
154 assertMsgOptions(false, 'Compile failed', false, true);
156 shaderExecutor
.useProgram();
158 shaderExecutorResult
= shaderExecutor
.execute(1, null);
159 result
= new Int32Array(shaderExecutorResult
[0].buffer
)[0];
161 bufferedLogToConsole(this.m_varName
+ ' = ' + result
);
163 if (result
!= reference
) {
164 bufferedLogToConsole('ERROR: Expected ' + this.m_varName
+ ' = ' + reference
+ '\n' +
165 'Test shader:' + shaderExecutor
.m_program
.getProgramInfo().infoLog
);
166 testFailedOptions('Invalid builtin constant value', false);
168 testPassedOptions('Pass', true);
170 return tcuTestCase
.IterateResult
.STOP
;
176 * @param {number=} near
177 * @param {number=} far
179 es3fShaderBuiltinVarTests
.DepthRangeParams = function(near
, far
) {
180 /** @type {number} */ this.zNear
= near
=== undefined ? 0.0 : near
;
181 /** @type {number} */ this.zFar
= far
=== undefined ? 1.0 : far
;
186 * @extends {glsShaderRenderCase.ShaderEvaluator}
187 * @param {es3fShaderBuiltinVarTests.DepthRangeParams} params
189 es3fShaderBuiltinVarTests
.DepthRangeEvaluator = function(params
) {
190 /** @type {es3fShaderBuiltinVarTests.DepthRangeParams} */ this.m_params
= params
;
193 es3fShaderBuiltinVarTests
.DepthRangeEvaluator
.prototype = Object
.create(glsShaderRenderCase
.ShaderEvaluator
.prototype);
194 es3fShaderBuiltinVarTests
.DepthRangeEvaluator
.prototype.constructor = es3fShaderBuiltinVarTests
.DepthRangeEvaluator
;
197 * @param {glsShaderRenderCase.ShaderEvalContext} c
199 es3fShaderBuiltinVarTests
.DepthRangeEvaluator
.prototype.evaluate = function(c
) {
200 /** @type {number} */ var zNear
= deMath
.clamp(this.m_params
.zNear
, 0.0, 1.0);
201 /** @type {number} */ var zFar
= deMath
.clamp(this.m_params
.zFar
, 0.0, 1.0);
202 /** @type {number} */ var diff
= zFar
- zNear
;
205 c
.color
[2] = diff
* 0.5 + 0.5;
210 * @extends {glsShaderRenderCase.ShaderRenderCase}
211 * @param {string} name
212 * @param {string} desc
213 * @param {boolean} isVertexCase
215 es3fShaderBuiltinVarTests
.ShaderDepthRangeTest = function(name
, desc
, isVertexCase
) {
216 glsShaderRenderCase
.ShaderRenderCase
.call(this, name
, desc
, isVertexCase
);
217 /** @type {es3fShaderBuiltinVarTests.DepthRangeParams} */ this.m_depthRange
= new es3fShaderBuiltinVarTests
.DepthRangeParams();
218 /** @type {es3fShaderBuiltinVarTests.DepthRangeEvaluator} */ this.m_evaluator
= new es3fShaderBuiltinVarTests
.DepthRangeEvaluator(this.m_depthRange
);
219 /** @type {number} */ this.m_iterNdx
= 0;
222 es3fShaderBuiltinVarTests
.ShaderDepthRangeTest
.prototype = Object
.create(glsShaderRenderCase
.ShaderRenderCase
.prototype);
223 es3fShaderBuiltinVarTests
.ShaderDepthRangeTest
.prototype.constructor = es3fShaderBuiltinVarTests
.ShaderDepthRangeTest
;
225 es3fShaderBuiltinVarTests
.ShaderDepthRangeTest
.prototype.init = function() {
226 /** @type {string} */ var defaultVertSrc
= '' +
227 '#version 300 es\n' +
228 'in highp vec4 a_position;\n' +
229 'void main (void)\n' +
231 ' gl_Position = a_position;\n' +
233 /** @type {string} */ var defaultFragSrc
= '' +
234 '#version 300 es\n' +
235 'in mediump vec4 v_color;\n' +
236 'layout(location = 0) out mediump vec4 o_color;\n\n' +
237 'void main (void)\n' +
239 ' o_color = v_color;\n' +
243 /** @type {string} */ var src
= '#version 300 es\n';
244 if (this.m_isVertexCase
)
245 src
+= 'in highp vec4 a_position;\n' +
246 'out mediump vec4 v_color;\n';
248 src
+= 'layout(location = 0) out mediump vec4 o_color;\n';
250 src
+= 'void main (void)\n{\n' +
251 '\t' + (this.m_isVertexCase
? 'v_color' : 'o_color') + ' = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff*0.5 + 0.5, 1.0);\n';
253 if (this.m_isVertexCase
)
254 src
+= '\tgl_Position = a_position;\n';
258 this.m_vertShaderSource
= this.m_isVertexCase
? src
: defaultVertSrc
;
259 this.m_fragShaderSource
= this.m_isVertexCase
? defaultFragSrc
: src
;
265 * @return {tcuTestCase.IterateResult}
267 es3fShaderBuiltinVarTests
.ShaderDepthRangeTest
.prototype.iterate = function() {
268 /** @type {Array<es3fShaderBuiltinVarTests.DepthRangeParams>} */ var cases
= [
269 new es3fShaderBuiltinVarTests
.DepthRangeParams(0.0, 1.0)
272 this.m_depthRange
= cases
[this.m_iterNdx
];
273 bufferedLogToConsole('gl.depthRange(' + this.m_depthRange
.zNear
+ ', ' + this.m_depthRange
.zFar
+ ')');
274 gl
.depthRange(this.m_depthRange
.zNear
, this.m_depthRange
.zFar
);
279 if (this.m_iterNdx
== cases
.length
)
280 return tcuTestCase
.IterateResult
.STOP
;
282 return tcuTestCase
.IterateResult
.CONTINUE
;
287 * @extends {tcuTestCase.DeqpTest}
289 es3fShaderBuiltinVarTests
.FragCoordXYZCase = function() {
290 tcuTestCase
.DeqpTest
.call(this, 'fragcoord_xyz', 'gl_FragCoord.xyz Test');
293 es3fShaderBuiltinVarTests
.FragCoordXYZCase
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
294 es3fShaderBuiltinVarTests
.FragCoordXYZCase
.prototype.constructor = es3fShaderBuiltinVarTests
.FragCoordXYZCase
;
296 es3fShaderBuiltinVarTests
.FragCoordXYZCase
.prototype.iterate = function() {
297 /** @type {number} */ var width
= gl
.drawingBufferWidth
;
298 /** @type {number} */ var height
= gl
.drawingBufferHeight
;
299 /** @type {Array<number>} */ var threshold
= deMath
.add([1, 1, 1, 1], tcuPixelFormat
.PixelFormatFromContext(gl
).getColorThreshold());
300 /** @type {Array<number>} */ var scale
= [1. / width
, 1. / height
, 1.0];
302 /** @type {tcuSurface.Surface} */ var testImg
= new tcuSurface
.Surface(width
, height
);
303 /** @type {tcuSurface.Surface} */ var refImg
= new tcuSurface
.Surface(width
, height
);
305 /** @type {string} */ var vtxSource
= '' +
306 '#version 300 es\n' +
307 'in highp vec4 a_position;\n' +
308 'void main (void)\n' +
310 ' gl_Position = a_position;\n' +
312 /** @type {string} */ var fragSource
= '' +
313 '#version 300 es\n' +
314 'uniform highp vec3 u_scale;\n' +
315 'layout(location = 0) out mediump vec4 o_color;\n' +
316 'void main (void)\n' +
318 ' o_color = vec4(gl_FragCoord.xyz*u_scale, 1.0);\n' +
320 /** @type {gluShaderProgram.ShaderProgram} */ var program
= new gluShaderProgram
.ShaderProgram(gl
, gluShaderProgram
.makeVtxFragSources(vtxSource
, fragSource
));
322 bufferedLogToConsole(program
.getProgramInfo().infoLog
);
325 throw new Error('Compile failed');
328 /** @type {Array<number>} */ var positions
= [
329 -1.0, 1.0, -1.0, 1.0,
330 -1.0, -1.0, 0.0, 1.0,
334 /** @type {Array<number>} */ var indices
= [0, 1, 2, 2, 1, 3];
336 /** @type {WebGLUniformLocation} */ var scaleLoc
= gl
.getUniformLocation(program
.getProgram(), 'u_scale');
337 /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding
= gluDrawUtil
.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions
);
339 gl
.useProgram(program
.getProgram());
340 gl
.uniform3fv(scaleLoc
, scale
);
342 gl
.viewport(0, 0, width
, height
);
343 gluDrawUtil
.draw(gl
, program
.getProgram(), [posBinding
], gluDrawUtil
.triangles(indices
));
345 testImg
.readViewport(gl
, [0, 0, width
, height
]);
348 for (var y
= 0; y
< refImg
.getHeight(); y
++) {
349 for (var x
= 0; x
< refImg
.getWidth(); x
++) {
350 /** @type {number} */ var xf
= (x
+ .5) / refImg
.getWidth();
351 /** @type {number} */ var yf
= (refImg
.getHeight() - y
- 1 + .5) / refImg
.getHeight();
352 /** @type {number} */ var z
= (xf
+ yf
) / 2.0;
353 /** @type {Array<number>} */ var fragCoord
= [x
+ .5, y
+ .5, z
];
354 /** @type {Array<number>} */ var scaledFC
= deMath
.multiply(fragCoord
, scale
);
355 /** @type {Array<number>} */
357 deMath
.clamp(Math
.floor(scaledFC
[0] * 255 + 0.5), 0, 255),
358 deMath
.clamp(Math
.floor(scaledFC
[1] * 255 + 0.5), 0, 255),
359 deMath
.clamp(Math
.floor(scaledFC
[2] * 255 + 0.5), 0, 255),
361 refImg
.setPixel(x
, y
, color
);
366 /** @type {boolean} */ var isOk
= tcuImageCompare
.pixelThresholdCompare('Result', 'Image comparison result', refImg
, testImg
, threshold
);
369 testFailedOptions('Image comparison failed', false);
371 testPassedOptions('Pass', true);
373 return tcuTestCase
.IterateResult
.STOP
;
377 * @param {Array<number>} s
378 * @param {Array<number>} w
383 es3fShaderBuiltinVarTests
.projectedTriInterpolate = function(s
, w
, nx
, ny
) {
384 return (s
[0] * (1.0 - nx
- ny
)/w[0] + s[1] * ny / w
[1] + s
[2] * nx
/ w
[2]) / ((1.0 - nx
- ny
) / w
[0] + ny
/ w
[1] + nx
/ w
[2]);
389 * @extends {tcuTestCase.DeqpTest}
391 es3fShaderBuiltinVarTests
.FragCoordWCase = function() {
392 tcuTestCase
.DeqpTest
.call(this, 'fragcoord_w', 'gl_FragCoord.w Test');
395 es3fShaderBuiltinVarTests
.FragCoordWCase
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
396 es3fShaderBuiltinVarTests
.FragCoordWCase
.prototype.constructor = es3fShaderBuiltinVarTests
.FragCoordWCase
;
399 * @return {tcuTestCase.IterateResult}
401 es3fShaderBuiltinVarTests
.FragCoordWCase
.prototype.iterate = function() {
402 /** @type {number} */ var width
= gl
.drawingBufferWidth
;
403 /** @type {number} */ var height
= gl
.drawingBufferHeight
;
404 /** @type {Array<number>} */ var threshold
= deMath
.add([1, 1, 1, 1], tcuPixelFormat
.PixelFormatFromContext(gl
).getColorThreshold());
406 /** @type {tcuSurface.Surface} */ var testImg
= new tcuSurface
.Surface(width
, height
);
407 /** @type {tcuSurface.Surface} */ var refImg
= new tcuSurface
.Surface(width
, height
);
409 /** @type {Array<number>} */ var w
= [1.7, 2.0, 1.2, 1.0];
411 /** @type {string} */ var vtxSource
= '#version 300 es\n' +
412 'in highp vec4 a_position;\n' +
413 'void main (void)\n' +
415 ' gl_Position = a_position;\n' +
418 /** @type {string} */ var fragSource
= '#version 300 es\n' +
419 'layout(location = 0) out mediump vec4 o_color;\n' +
420 'void main (void)\n' +
422 ' o_color = vec4(0.0, 1.0/gl_FragCoord.w - 1.0, 0.0, 1.0);\n' +
425 /** @type {gluShaderProgram.ShaderProgram} */ var program
= new gluShaderProgram
.ShaderProgram(gl
, gluShaderProgram
.makeVtxFragSources(vtxSource
, fragSource
));
426 bufferedLogToConsole(program
.getProgramInfo().infoLog
);
429 throw new Error('Compile failed');
432 /** @type {Array<number>} */ var positions
= [
433 -w
[0], w
[0], 0.0, w
[0],
434 -w
[1], -w
[1], 0.0, w
[1],
435 w
[2], w
[2], 0.0, w
[2],
436 w
[3], -w
[3], 0.0, w
[3]
438 /** @type {Array<number>} */ var indices
= [0, 1, 2, 2, 1, 3];
440 /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding
= gluDrawUtil
.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions
);
441 gl
.useProgram(program
.getProgram());
443 gluDrawUtil
.draw(gl
, program
.getProgram(), [posBinding
], gluDrawUtil
.triangles(indices
));
444 testImg
.readViewport(gl
, [0, 0, width
, height
]);
447 for (var y
= 0; y
< refImg
.getHeight(); y
++) {
448 for (var x
= 0; x
< refImg
.getWidth(); x
++) {
449 /** @type {number} */ var xf
= (x
+ 0.5) / refImg
.getWidth();
450 /** @type {number} */ var yf
= (refImg
.getHeight() - y
- 1 + 0.5) / refImg
.getHeight();
451 /** @type {number} */ var oow
= ((xf
+ yf
) < 1.0) ?
452 es3fShaderBuiltinVarTests
.projectedTriInterpolate([w
[0], w
[1], w
[2]], [w
[0], w
[1], w
[2]], xf
, yf
) :
453 es3fShaderBuiltinVarTests
.projectedTriInterpolate([w
[3], w
[2], w
[1]], [w
[3], w
[2], w
[1]], 1.0 - xf
, 1.0 - yf
);
454 /** @type {Array<number>} */
457 deMath
.clamp(Math
.floor((oow
- 1.0) * 255 + 0.5), 0, 255),
460 refImg
.setPixel(x
, y
, color
);
465 /** @type {boolean} */ var isOk
= tcuImageCompare
.pixelThresholdCompare('Result', 'Image comparison result', refImg
, testImg
, threshold
);
468 testFailedOptions('Image comparison failed', false);
470 testPassedOptions('Pass', true);
472 return tcuTestCase
.IterateResult
.STOP
;
477 * @extends {tcuTestCase.DeqpTest}
479 es3fShaderBuiltinVarTests
.PointCoordCase = function() {
480 tcuTestCase
.DeqpTest
.call(this, 'pointcoord', 'gl_PointCoord Test');
483 es3fShaderBuiltinVarTests
.PointCoordCase
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
484 es3fShaderBuiltinVarTests
.PointCoordCase
.prototype.constructor = es3fShaderBuiltinVarTests
.PointCoordCase
;
487 * @return {tcuTestCase.IterateResult}
489 es3fShaderBuiltinVarTests
.PointCoordCase
.prototype.iterate = function() {
490 /** @type {number} */ var width
= Math
.min(256, gl
.drawingBufferWidth
);
491 /** @type {number} */ var height
= Math
.min(256, gl
.drawingBufferHeight
);
492 /** @type {number} */ var threshold
= 0.02;
494 /** @type {number} */ var numPoints
= 8;
496 /** @type {Array<number>} */ var coords
= [];
497 /** @type {Array<number>} */ var pointSizeRange
= [0.0, 0.0];
498 /** @type {deRandom.Random} */ var rnd
= new deRandom
.Random(0x145fa);
499 /** @type {tcuSurface.Surface} */ var testImg
= new tcuSurface
.Surface(width
, height
);
500 /** @type {tcuSurface.Surface} */ var refImg
= new tcuSurface
.Surface(width
, height
);
502 pointSizeRange
= /** @type {Array<number>} */ (gl
.getParameter(gl
.ALIASED_POINT_SIZE_RANGE
));
504 if (pointSizeRange
[0] <= 0.0 || pointSizeRange
[1] <= 0.0 || pointSizeRange
[1] < pointSizeRange
[0])
505 throw new Error('Invalid gl.ALIASED_POINT_SIZE_RANGE');
507 // Compute coordinates.
508 for (var i
= 0; i
< numPoints
; i
++)
510 rnd
.getFloat(-0.9, 0.9),
511 rnd
.getFloat(-0.9, 0.9),
512 rnd
.getFloat(pointSizeRange
[0], pointSizeRange
[1])
515 /** @type {string} */ var vtxSource
= '#version 300 es\n' +
516 'in highp vec3 a_positionSize;\n' +
517 'void main (void)\n' +
519 ' gl_Position = vec4(a_positionSize.xy, 0.0, 1.0);\n' +
520 ' gl_PointSize = a_positionSize.z;\n' +
523 /** @type {string} */ var fragSource
= '#version 300 es\n' +
524 'layout(location = 0) out mediump vec4 o_color;\n' +
525 'void main (void)\n' +
527 ' o_color = vec4(gl_PointCoord, 0.0, 1.0);\n' +
530 /** @type {gluShaderProgram.ShaderProgram} */ var program
= new gluShaderProgram
.ShaderProgram(gl
, gluShaderProgram
.makeVtxFragSources(vtxSource
, fragSource
));
531 bufferedLogToConsole(program
.getProgramInfo().infoLog
);
534 throw new Error('Compile failed');
537 var newCoords
= [].concat
.apply([], coords
);
539 // /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_positionSize', 3, coords.length, 0, coords);
540 /** @type {gluDrawUtil.VertexArrayBinding} */
541 var posBinding
= gluDrawUtil
.newFloatVertexArrayBinding('a_positionSize', 3, coords
.length
, 12, newCoords
);
542 /** @type {number} */ var viewportX
= rnd
.getInt(0, gl
.drawingBufferWidth
- width
);
543 /** @type {number} */ var viewportY
= rnd
.getInt(0, gl
.drawingBufferHeight
- height
);
545 gl
.viewport(viewportX
, viewportY
, width
, height
);
546 gl
.clearColor(0.0, 0.0, 0.0, 1.0);
547 gl
.clear(gl
.COLOR_BUFFER_BIT
);
549 gl
.useProgram(program
.getProgram());
551 gluDrawUtil
.draw(gl
, program
.getProgram(), [posBinding
], gluDrawUtil
.pointsFromElements(coords
.length
));
552 testImg
.readViewport(gl
, [viewportX
, viewportY
, width
, height
]);
555 refImg
.getAccess().clear([0.0, 0.0, 0.0, 1.0]);
556 for (var i
= 0; i
< coords
.length
; i
++) {
557 /** @type {number} */ var x0
= Math
.round(width
* (coords
[i
][0] * 0.5 + 0.5) - coords
[i
][2] * 0.5);
558 /** @type {number} */ var y0
= Math
.round(height
* (coords
[i
][1] * 0.5 + 0.5) - coords
[i
][2] * 0.5);
559 /** @type {number} */ var x1
= Math
.round(width
* (coords
[i
][0] * 0.5 + 0.5) + coords
[i
][2] * 0.5);
560 /** @type {number} */ var y1
= Math
.round(height
* (coords
[i
][1] * 0.5 + 0.5) + coords
[i
][2] * 0.5);
561 /** @type {number} */ var w
= x1
- x0
;
562 /** @type {number} */ var h
= y1
- y0
;
564 for (var yo
= 0; yo
< h
; yo
++) {
565 for (var xo
= 0; xo
< w
; xo
++) {
566 /** @type {number} */ var xf
= (xo
+ 0.5) / w
;
567 /** @type {number} */ var yf
= ((h
- yo
- 1) + 0.5) / h
;
568 /** @type {number} */ var dx
= x0
+ xo
;
569 /** @type {number} */ var dy
= y0
+ yo
;
570 /** @type {Array<number>} */
572 deMath
.clamp(Math
.floor(xf
* 255 + 0.5), 0, 255),
573 deMath
.clamp(Math
.floor(yf
* 255 + 0.5), 0, 255),
576 if (deMath
.deInBounds32(dx
, 0, refImg
.getWidth()) && deMath
.deInBounds32(dy
, 0, refImg
.getHeight()))
577 refImg
.setPixel(dx
, dy
, color
);
583 /** @type {boolean} */ var isOk
= tcuImageCompare
.fuzzyCompare('Result', 'Image comparison result', refImg
.getAccess(), testImg
.getAccess(), threshold
);
586 testFailedOptions('Image comparison failed', false);
588 testPassedOptions('Pass', true);
590 return tcuTestCase
.IterateResult
.STOP
;
595 * @extends {tcuTestCase.DeqpTest}
597 es3fShaderBuiltinVarTests
.FrontFacingCase = function() {
598 tcuTestCase
.DeqpTest
.call(this, 'frontfacing', 'gl_FrontFacing Test');
601 es3fShaderBuiltinVarTests
.FrontFacingCase
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
602 es3fShaderBuiltinVarTests
.FrontFacingCase
.prototype.constructor = es3fShaderBuiltinVarTests
.FrontFacingCase
;
605 * @return {tcuTestCase.IterateResult}
607 es3fShaderBuiltinVarTests
.FrontFacingCase
.prototype.iterate = function() {
608 // Test case renders two adjecent quads, where left is has front-facing
609 // triagles and right back-facing. Color is selected based on gl_FrontFacing
611 /** @type {deRandom.Random} */ var rnd
= new deRandom
.Random(0x89f2c);
612 /** @type {number} */ var width
= Math
.min(64, gl
.drawingBufferWidth
);
613 /** @type {number} */ var height
= Math
.min(64, gl
.drawingBufferHeight
);
614 /** @type {number} */ var viewportX
= rnd
.getInt(0, gl
.drawingBufferWidth
- width
);
615 /** @type {number} */ var viewportY
= rnd
.getInt(0, gl
.drawingBufferHeight
- height
);
616 /** @type {Array<number>} */ var threshold
= deMath
.add([1, 1, 1, 1], tcuPixelFormat
.PixelFormatFromContext(gl
).getColorThreshold());
618 /** @type {tcuSurface.Surface} */ var testImg
= new tcuSurface
.Surface(width
, height
);
619 /** @type {tcuSurface.Surface} */ var refImg
= new tcuSurface
.Surface(width
, height
);
621 /** @type {string} */ var vtxSource
= '#version 300 es\n' +
622 'in highp vec4 a_position;\n' +
623 'void main (void)\n' +
625 ' gl_Position = a_position;\n' +
628 /** @type {string} */ var fragSource
= '#version 300 es\n' +
629 'layout(location = 0) out mediump vec4 o_color;\n' +
630 'void main (void)\n' +
632 ' if (gl_FrontFacing)\n' +
633 ' o_color = vec4(0.0, 1.0, 0.0, 1.0);\n' +
635 ' o_color = vec4(0.0, 0.0, 1.0, 1.0);\n' +
638 /** @type {gluShaderProgram.ShaderProgram} */ var program
= new gluShaderProgram
.ShaderProgram(gl
, gluShaderProgram
.makeVtxFragSources(vtxSource
, fragSource
));
640 bufferedLogToConsole(program
.getProgramInfo().infoLog
);
643 throw new Error('Compile failed');
646 /** @type {Array<number>} */ var positions
= [
648 -1.0, -1.0, 0.0, 1.0,
653 /** @type {Array<number>} */ var indicesCCW
= [0, 1, 2, 2, 1, 3];
654 /** @type {Array<number>} */ var indicesCW
= [2, 1, 0, 3, 1, 2];
656 /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding
= gluDrawUtil
.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions
);
658 gl
.useProgram(program
.getProgram());
660 gl
.viewport(viewportX
, viewportY
, Math
.floor(width
/ 2), height
);
662 gluDrawUtil
.draw(gl
, program
.getProgram(), [posBinding
], gluDrawUtil
.triangles(indicesCCW
));
664 gl
.viewport(viewportX
+ Math
.floor(width
/ 2), viewportY
, width
- Math
.floor(width
/ 2), height
);
665 gluDrawUtil
.draw(gl
, program
.getProgram(), [posBinding
], gluDrawUtil
.triangles(indicesCW
));
666 testImg
.readViewport(gl
, [viewportX
, viewportY
, width
, height
]);
668 for (var y
= 0; y
< refImg
.getHeight(); y
++) {
669 for (var x
= 0; x
< Math
.floor(refImg
.getWidth() / 2); x
++)
670 refImg
.setPixel(x
, y
, tcuRGBA
.RGBA
.green
.toIVec());
672 for (var x
= Math
.floor(refImg
.getWidth() / 2); x
< refImg
.getWidth(); x
++)
673 refImg
.setPixel(x
, y
, tcuRGBA
.RGBA
.blue
.toIVec());
677 /** @type {boolean} */ var isOk
= tcuImageCompare
.pixelThresholdCompare('Result', 'Image comparison result', refImg
, testImg
, threshold
);
680 testFailedOptions('Image comparison failed', false);
682 testPassedOptions('Pass', true);
684 return tcuTestCase
.IterateResult
.STOP
;
689 * @extends {tcuTestCase.DeqpTest}
691 es3fShaderBuiltinVarTests
.VertexIDCase = function() {
692 tcuTestCase
.DeqpTest
.call(this, 'vertex_id', 'gl_VertexID Test');
693 /** @type {?gluShaderProgram.ShaderProgram} */ this.m_program
= null;
694 /** @type {WebGLBuffer} */ this.m_positionBuffer
= null;
695 /** @type {WebGLBuffer} */ this.m_elementBuffer
= null;
696 /** @type {number} */ this.m_viewportW
= 0;
697 /** @type {number} */ this.m_viewportH
= 0;
698 /** @type {number} */ this.m_iterNdx
= 0;
699 /** @type {Array<Array<number>>} */ this.m_positions
= [];
700 /** @type {Array<Array<number>>} */ this.m_colors
= [];
703 es3fShaderBuiltinVarTests
.VertexIDCase
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
704 es3fShaderBuiltinVarTests
.VertexIDCase
.prototype.constructor = es3fShaderBuiltinVarTests
.VertexIDCase
;
706 es3fShaderBuiltinVarTests
.VertexIDCase
.MAX_VERTICES
= 24; //!< 8 triangles, totals 24 vertices
708 es3fShaderBuiltinVarTests
.VertexIDCase
.prototype.init = function() {
709 /** @type {number} */ var width
= gl
.drawingBufferWidth
;
710 /** @type {number} */ var height
= gl
.drawingBufferHeight
;
712 /** @type {number} */ var quadWidth
= 32;
713 /** @type {number} */ var quadHeight
= 32;
715 if (width
< quadWidth
)
716 throw new Error('Too small render target');
718 /** @type {number} */ var maxQuadsX
= Math
.floor(width
/ quadWidth
);
719 /** @type {number} */ var numVertices
= es3fShaderBuiltinVarTests
.VertexIDCase
.MAX_VERTICES
;
721 /** @type {number} */ var numQuads
= Math
.floor(numVertices
/ 6) + (numVertices
% 6 != 0 ? 1 : 0);
722 /** @type {number} */ var viewportW
= Math
.min(numQuads
, maxQuadsX
)*quadWidth
;
723 /** @type {number} */ var viewportH
= (Math
.floor(numQuads
/maxQuadsX
) + (numQuads
% maxQuadsX
!= 0 ? 1 : 0)) * quadHeight
;
725 if (viewportH
> height
)
726 throw new Error('Too small render target');
728 assertMsgOptions(viewportW
<= width
&& viewportH
<= height
, 'Unexpected viewport dimensions.', false, true);
730 assertMsgOptions(!this.m_program
, 'Program should not be defined at this point.', false, true);
732 /** @type {string} */ var vtxSource
= '#version 300 es\n' +
733 'in highp vec4 a_position;\n' +
734 'out mediump vec4 v_color;\n' +
735 'uniform highp vec4 u_colors[24];\n' +
736 'void main (void)\n' +
738 ' gl_Position = a_position;\n' +
739 ' v_color = u_colors[gl_VertexID];\n' +
742 /** @type {string} */ var fragSource
= '#version 300 es\n' +
743 'in mediump vec4 v_color;\n' +
744 'layout(location = 0) out mediump vec4 o_color;\n' +
745 'void main (void)\n' +
747 ' o_color = v_color;\n' +
750 this.m_program
= new gluShaderProgram
.ShaderProgram(gl
, gluShaderProgram
.makeVtxFragSources(vtxSource
, fragSource
));
751 bufferedLogToConsole(this.m_program
.getProgramInfo().infoLog
);
753 if (!this.m_program
.isOk()) {
754 this.m_program
= null;
755 throw new Error('Compile failed');
758 this.m_positionBuffer
= gl
.createBuffer();
759 this.m_elementBuffer
= gl
.createBuffer();
761 // Set colors (in dynamic memory to save static data space).
762 this.m_colors
[0] = [0.0, 0.0, 0.0, 1.0];
763 this.m_colors
[1] = [0.5, 1.0, 0.5, 1.0];
764 this.m_colors
[2] = [0.0, 0.5, 1.0, 1.0];
765 this.m_colors
[3] = [0.0, 1.0, 0.0, 1.0];
766 this.m_colors
[4] = [0.0, 1.0, 1.0, 1.0];
767 this.m_colors
[5] = [0.5, 0.0, 0.0, 1.0];
768 this.m_colors
[6] = [0.5, 0.0, 1.0, 1.0];
769 this.m_colors
[7] = [0.5, 0.0, 0.5, 1.0];
770 this.m_colors
[8] = [1.0, 0.0, 0.0, 1.0];
771 this.m_colors
[9] = [0.5, 1.0, 0.0, 1.0];
772 this.m_colors
[10] = [0.0, 0.5, 0.0, 1.0];
773 this.m_colors
[11] = [0.5, 1.0, 1.0, 1.0];
774 this.m_colors
[12] = [0.0, 0.0, 1.0, 1.0];
775 this.m_colors
[13] = [1.0, 0.0, 0.5, 1.0];
776 this.m_colors
[14] = [0.0, 0.5, 0.5, 1.0];
777 this.m_colors
[15] = [1.0, 1.0, 0.5, 1.0];
778 this.m_colors
[16] = [1.0, 0.0, 1.0, 1.0];
779 this.m_colors
[17] = [1.0, 0.5, 0.0, 1.0];
780 this.m_colors
[18] = [0.0, 1.0, 0.5, 1.0];
781 this.m_colors
[19] = [1.0, 0.5, 1.0, 1.0];
782 this.m_colors
[20] = [1.0, 1.0, 0.0, 1.0];
783 this.m_colors
[21] = [1.0, 0.5, 0.5, 1.0];
784 this.m_colors
[22] = [0.0, 0.0, 0.5, 1.0];
785 this.m_colors
[23] = [1.0, 1.0, 1.0, 1.0];
787 // Compute positions.
788 assertMsgOptions(numVertices
% 3 == 0, 'Number of vertices should be multiple of 3.', false, true);
790 for (var vtxNdx
= 0; vtxNdx
< numVertices
; vtxNdx
+= 3) {
791 /** @type {number} */ var h
= 2.0 * quadHeight
/ viewportH
;
792 /** @type {number} */ var w
= 2.0 * quadWidth
/ viewportW
;
794 /** @type {number} */ var triNdx
= Math
.floor(vtxNdx
/ 3);
795 /** @type {number} */ var quadNdx
= Math
.floor(triNdx
/ 2);
796 /** @type {number} */ var quadY
= Math
.floor(quadNdx
/ maxQuadsX
);
797 /** @type {number} */ var quadX
= quadNdx
% maxQuadsX
;
799 /** @type {number} */ var x0
= -1.0 + quadX
* w
;
800 /** @type {number} */ var y0
= -1.0 + quadY
* h
;
802 if (triNdx
% 2 === 0) {
803 this.m_positions
[vtxNdx
+ 0] = [x0
, y0
, 0.0, 1.0];
804 this.m_positions
[vtxNdx
+ 1] = [x0
+w
, y0
+h
, 0.0, 1.0];
805 this.m_positions
[vtxNdx
+ 2] = [x0
, y0
+h
, 0.0, 1.0];
807 this.m_positions
[vtxNdx
+ 0] = [x0
+ w
, y0
+ h
, 0.0, 1.0];
808 this.m_positions
[vtxNdx
+ 1] = [x0
, y0
, 0.0, 1.0];
809 this.m_positions
[vtxNdx
+ 2] = [x0
+w
, y0
, 0.0, 1.0];
813 this.m_viewportW
= viewportW
;
814 this.m_viewportH
= viewportH
;
819 es3fShaderBuiltinVarTests
.VertexIDCase
.prototype.deinit = function() {
820 this.m_program
= null;
822 if (this.m_positionBuffer
) {
823 gl
.deleteBuffer(this.m_positionBuffer
);
824 this.m_positionBuffer
= null;
827 if (this.m_elementBuffer
) {
828 gl
.deleteBuffer(this.m_elementBuffer
);
829 this.m_elementBuffer
= null;
832 this.m_positions
= [];
838 * @extends {sglrShaderProgram.ShaderProgram}
840 es3fShaderBuiltinVarTests
.VertexIDReferenceShader = function() {
841 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var declaration
= new sglrShaderProgram
.ShaderProgramDeclaration();
842 declaration
.pushVertexAttribute(new sglrShaderProgram
.VertexAttribute('', rrGenericVector
.GenericVecType
.FLOAT
));
843 declaration
.pushVertexAttribute(new sglrShaderProgram
.VertexAttribute('', rrGenericVector
.GenericVecType
.FLOAT
));
844 declaration
.pushVertexToFragmentVarying(new sglrShaderProgram
.VertexToFragmentVarying(rrGenericVector
.GenericVecType
.FLOAT
, new sglrShaderProgram
.VaryingFlags()));
845 declaration
.pushFragmentOutput(new sglrShaderProgram
.FragmentOutput(rrGenericVector
.GenericVecType
.FLOAT
));
846 declaration
.pushVertexSource(new sglrShaderProgram
.VertexSource('')); // ShaderProgram fails if we don't push a source, even though GLSL source is not used
847 declaration
.pushFragmentSource(new sglrShaderProgram
.FragmentSource(''));
848 sglrShaderProgram
.ShaderProgram
.call(this, declaration
);
851 es3fShaderBuiltinVarTests
.VertexIDReferenceShader
.prototype = Object
.create(sglrShaderProgram
.ShaderProgram
.prototype);
852 es3fShaderBuiltinVarTests
.VertexIDReferenceShader
.prototype.constructor = es3fShaderBuiltinVarTests
.VertexIDReferenceShader
;
854 /** @const {number} */ es3fShaderBuiltinVarTests
.VertexIDReferenceShader
.VARYINGLOC_COLOR
= 0;
857 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
858 * @param {Array<rrVertexPacket.VertexPacket>} packets
860 es3fShaderBuiltinVarTests
.VertexIDReferenceShader
.prototype.shadeVertices = function(inputs
, packets
) {
861 for (var packetNdx
= 0; packetNdx
< packets
.length
; ++packetNdx
) {
862 /** @type {number} */ var positionAttrLoc
= 0;
863 /** @type {number} */ var colorAttrLoc
= 1;
865 /** @type {rrVertexPacket.VertexPacket} */ var packet
= packets
[packetNdx
];
867 // Transform to position
868 packet
.position
= rrVertexAttrib
.readVertexAttrib(inputs
[positionAttrLoc
], packet
.instanceNdx
, packet
.vertexNdx
, rrGenericVector
.GenericVecType
.FLOAT
);
871 packet
.outputs
[es3fShaderBuiltinVarTests
.VertexIDReferenceShader
.VARYINGLOC_COLOR
] = rrVertexAttrib
.readVertexAttrib(inputs
[colorAttrLoc
], packet
.instanceNdx
, packet
.vertexNdx
, rrGenericVector
.GenericVecType
.FLOAT
);
876 * @param {Array<rrFragmentOperations.Fragment>} packets
877 * @param {rrShadingContext.FragmentShadingContext} context
879 es3fShaderBuiltinVarTests
.VertexIDReferenceShader
.prototype.shadeFragments = function(packets
, context
) {
880 for (var packetNdx
= 0; packetNdx
< packets
.length
; ++packetNdx
) {
881 /** @type {rrFragmentOperations.Fragment} */ var packet
= packets
[packetNdx
];
882 packet
.value
= rrShadingContext
.readVarying(packet
, context
, es3fShaderBuiltinVarTests
.VertexIDReferenceShader
.VARYINGLOC_COLOR
);
887 * @param {tcuTexture.PixelBufferAccess} dst
888 * @param {Array<number>} indices
889 * @param {goog.NumberArray} positions
890 * @param {goog.NumberArray} colors
892 es3fShaderBuiltinVarTests
.VertexIDCase
.prototype.renderReference = function(dst
, indices
, positions
, colors
) {
893 /** @type {rrRenderState.RenderState} */
894 var referenceState
= new rrRenderState
.RenderState(
895 new rrRenderState
.ViewportState(rrMultisamplePixelBufferAccess
.MultisamplePixelBufferAccess
.fromSinglesampleAccess(dst
))
898 /** @type {rrRenderer.RenderTarget} */
899 var referenceTarget
= new rrRenderer
.RenderTarget(
900 rrMultisamplePixelBufferAccess
.MultisamplePixelBufferAccess
.fromSinglesampleAccess(dst
)
903 /** @type {es3fShaderBuiltinVarTests.VertexIDReferenceShader} */
904 var referenceShaderProgram
= new es3fShaderBuiltinVarTests
.VertexIDReferenceShader();
906 /** @type {Array<rrVertexAttrib.VertexAttrib>} */ var attribs
= [];
907 attribs
[0] = new rrVertexAttrib
.VertexAttrib();
908 attribs
[0].type
= rrVertexAttrib
.VertexAttribType
.FLOAT
;
910 attribs
[0].stride
= 0;
911 attribs
[0].instanceDivisor
= 0;
912 attribs
[0].pointer
= positions
.buffer
;
914 attribs
[1] = new rrVertexAttrib
.VertexAttrib();
915 attribs
[1].type
= rrVertexAttrib
.VertexAttribType
.FLOAT
;
917 attribs
[1].stride
= 0;
918 attribs
[1].instanceDivisor
= 0;
919 attribs
[1].pointer
= colors
.buffer
;
920 rrRenderer
.drawTriangles(referenceState
, referenceTarget
, referenceShaderProgram
,
921 attribs
, rrRenderer
.PrimitiveType
.TRIANGLES
, 0, indices
.length
, /*instanceID = */ 0);
925 * @return {tcuTestCase.IterateResult}
927 es3fShaderBuiltinVarTests
.VertexIDCase
.prototype.iterate = function() {
928 /** @type {number} */ var width
= gl
.drawingBufferWidth
;
929 /** @type {number} */ var height
= gl
.drawingBufferHeight
;
930 /** @type {number} */ var viewportW
= this.m_viewportW
;
931 /** @type {number} */ var viewportH
= this.m_viewportH
;
933 /** @type {number} */ var threshold
= 0.02;
935 /** @type {deRandom.Random} */ var rnd
= new deRandom
.Random(0xcf23ab1 ^ deString
.deStringHash(this.m_iterNdx
.toString()));
936 /** @type {tcuSurface.Surface} */ var refImg
= new tcuSurface
.Surface(viewportW
, viewportH
);
937 /** @type {tcuSurface.Surface} */ var testImg
= new tcuSurface
.Surface(viewportW
, viewportH
);
939 /** @type {number} */ var viewportX
= rnd
.getInt(0, width
- viewportW
);
940 /** @type {number} */ var viewportY
= rnd
.getInt(0, height
- viewportH
);
942 /** @type {number} */ var posLoc
= gl
.getAttribLocation(this.m_program
.getProgram(), 'a_position');
943 /** @type {WebGLUniformLocation} */ var colorsLoc
= gl
.getUniformLocation(this.m_program
.getProgram(), 'u_colors[0]');
944 /** @type {Array<number>} */ var clearColor
= [0.0, 0.0, 0.0, 1.0];
945 /** @type {Array<number>} */ var indices
= [];
946 /** @type {Array<Array<number>>} */ var mappedPos
= [];
947 /** @type {goog.NumberArray} */ var flatColorArray
;
948 /** @type {goog.NumberArray} */ var flatPosArray
;
949 // Setup common state.
950 gl
.viewport(viewportX
, viewportY
, viewportW
, viewportH
);
951 gl
.useProgram(this.m_program
.getProgram());
952 gl
.bindBuffer(gl
.ARRAY_BUFFER
, this.m_positionBuffer
);
953 gl
.enableVertexAttribArray(posLoc
);
954 gl
.vertexAttribPointer(posLoc
, 4, gl
.FLOAT
, false, 0, 0);
955 gl
.uniform4fv(colorsLoc
, [].concat
.apply([], this.m_colors
));
957 // Clear render target to black.
958 gl
.clearColor(clearColor
[0], clearColor
[1], clearColor
[2], clearColor
[3]);
959 gl
.clear(gl
.COLOR_BUFFER_BIT
);
961 refImg
.getAccess().clear(clearColor
);
963 if (this.m_iterNdx
=== 0) {
964 bufferedLogToConsole('Iter0: glDrawArrays()');
966 flatPosArray
= new Float32Array([].concat
.apply([], this.m_positions
));
967 flatColorArray
= new Float32Array([].concat
.apply([], this.m_colors
));
968 gl
.bufferData(gl
.ARRAY_BUFFER
, flatPosArray
.buffer
, gl
.DYNAMIC_DRAW
);
969 gl
.drawArrays(gl
.TRIANGLES
, 0, Math
.floor(flatPosArray
.length
/ 4));
971 //glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
972 testImg
.readViewport(gl
, [viewportX
, viewportY
, viewportW
, viewportH
]);
974 for (var ndx
= 0; ndx
< this.m_positions
.length
; ndx
++)
977 this.renderReference(refImg
.getAccess(), indices
, flatPosArray
, flatColorArray
);
978 } else if (this.m_iterNdx
=== 1) {
979 bufferedLogToConsole('Iter1: glDrawElements(), indices in buffer');
981 // Compute initial indices and suffle
982 for (var ndx
= 0; ndx
< this.m_positions
.length
; ndx
++)
984 // deRandom.shuffle(rnd, indices);
985 // \note [2015-08-05 dag] The original test shuffles the indices array but the reference renderer cannot handle triangles with sides not parallel to the axes.
987 // Use indices to re-map positions.
988 for (var ndx
= 0; ndx
< indices
.length
; ndx
++)
989 mappedPos
[indices
[ndx
]] = this.m_positions
[ndx
];
991 gl
.bindBuffer(gl
.ELEMENT_ARRAY_BUFFER
, this.m_elementBuffer
);
992 gl
.bufferData(gl
.ELEMENT_ARRAY_BUFFER
, (new Uint16Array(indices
)).buffer
, gl
.DYNAMIC_DRAW
);
994 flatPosArray
= new Float32Array([].concat
.apply([], mappedPos
));
995 flatColorArray
= new Float32Array([].concat
.apply([], this.m_colors
));
996 gl
.bufferData(gl
.ARRAY_BUFFER
, flatPosArray
.buffer
, gl
.DYNAMIC_DRAW
);
997 gl
.drawElements(gl
.TRIANGLES
, indices
.length
, gl
.UNSIGNED_SHORT
, 0);
999 //glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
1000 testImg
.readViewport(gl
, [viewportX
, viewportY
, viewportW
, viewportH
]);
1001 refImg
.getAccess().clear(clearColor
);
1002 this.renderReference(refImg
.getAccess(), indices
, flatPosArray
, flatColorArray
);
1004 throw new Error('Iteration count exceeded.');
1006 if (!tcuImageCompare
.fuzzyCompare('Result', 'Image comparison result', refImg
.getAccess(), testImg
.getAccess(), threshold
))
1007 testFailedOptions('Image comparison failed', false);
1009 testPassedOptions('Pass', true);
1011 this.m_iterNdx
+= 1;
1012 return (this.m_iterNdx
< 2) ? tcuTestCase
.IterateResult
.CONTINUE
: tcuTestCase
.IterateResult
.STOP
;
1017 * @extends {tcuTestCase.DeqpTest}
1019 es3fShaderBuiltinVarTests
.ShaderBuiltinVarTests = function() {
1020 tcuTestCase
.DeqpTest
.call(this, 'builtin_variable', 'Built-in Variable Tests');
1023 es3fShaderBuiltinVarTests
.ShaderBuiltinVarTests
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
1024 es3fShaderBuiltinVarTests
.ShaderBuiltinVarTests
.prototype.constructor = es3fShaderBuiltinVarTests
.ShaderBuiltinVarTests
;
1026 es3fShaderBuiltinVarTests
.ShaderBuiltinVarTests
.prototype.init = function() {
1027 var testGroup
= tcuTestCase
.runner
.testCases
;
1028 // Builtin constants.
1032 * @param {string} caseName
1033 * @param {string} varName
1034 * @param {es3fShaderBuiltinVarTests.GetConstantValueFunc} getValue
1036 var BuiltinConstant = function(caseName
, varName
, getValue
) {
1037 /** @type {string} */ this.caseName
= caseName
;
1038 /** @type {string} */ this.varName
= varName
;
1039 /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ this.getValue
= getValue
;
1043 /** @type {Array<BuiltinConstant>} */ var builtinConstants
= [
1046 new BuiltinConstant('max_vertex_attribs', 'gl_MaxVertexAttribs', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_VERTEX_ATTRIBS
); }),
1047 new BuiltinConstant('max_vertex_uniform_vectors', 'gl_MaxVertexUniformVectors', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_VERTEX_UNIFORM_VECTORS
); }),
1048 new BuiltinConstant('max_fragment_uniform_vectors', 'gl_MaxFragmentUniformVectors', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_FRAGMENT_UNIFORM_VECTORS
); }),
1049 new BuiltinConstant('max_texture_image_units', 'gl_MaxTextureImageUnits', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_TEXTURE_IMAGE_UNITS
); }),
1050 new BuiltinConstant('max_vertex_texture_image_units', 'gl_MaxVertexTextureImageUnits', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_VERTEX_TEXTURE_IMAGE_UNITS
); }),
1051 new BuiltinConstant('max_combined_texture_image_units', 'gl_MaxCombinedTextureImageUnits', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_COMBINED_TEXTURE_IMAGE_UNITS
); }),
1052 new BuiltinConstant('max_draw_buffers', 'gl_MaxDrawBuffers', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_DRAW_BUFFERS
); }),
1056 new BuiltinConstant('max_vertex_output_vectors', 'gl_MaxVertexOutputVectors', function() { return es3fShaderBuiltinVarTests
.getVectorsFromComps(gl
.MAX_VERTEX_OUTPUT_COMPONENTS
); }),
1057 new BuiltinConstant('max_fragment_input_vectors', 'gl_MaxFragmentInputVectors', function() { return es3fShaderBuiltinVarTests
.getVectorsFromComps(gl
.MAX_FRAGMENT_INPUT_COMPONENTS
); }),
1058 new BuiltinConstant('min_program_texel_offset', 'gl_MinProgramTexelOffset', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MIN_PROGRAM_TEXEL_OFFSET
); }),
1059 new BuiltinConstant('max_program_texel_offset', 'gl_MaxProgramTexelOffset', function() { return es3fShaderBuiltinVarTests
.getInteger(gl
.MAX_PROGRAM_TEXEL_OFFSET
); })
1062 for (var ndx
= 0; ndx
< builtinConstants
.length
; ndx
++) {
1063 /** @type {string} */ var caseName
= builtinConstants
[ndx
].caseName
;
1064 /** @type {string} */ var varName
= builtinConstants
[ndx
].varName
;
1065 /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ var getValue
= builtinConstants
[ndx
].getValue
;
1067 testGroup
.addChild(new es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase(caseName
+ '_vertex', varName
, varName
, getValue
, gluShaderProgram
.shaderType
.VERTEX
));
1068 testGroup
.addChild(new es3fShaderBuiltinVarTests
.ShaderBuiltinConstantCase(caseName
+ '_fragment', varName
, varName
, getValue
, gluShaderProgram
.shaderType
.FRAGMENT
));
1071 testGroup
.addChild(new es3fShaderBuiltinVarTests
.ShaderDepthRangeTest('depth_range_vertex', 'gl_DepthRange', true));
1072 testGroup
.addChild(new es3fShaderBuiltinVarTests
.ShaderDepthRangeTest('depth_range_fragment', 'gl_DepthRange', false));
1074 // Vertex shader builtin variables.
1075 testGroup
.addChild(new es3fShaderBuiltinVarTests
.VertexIDCase());
1076 // \todo [2013-03-20 pyry] gl_InstanceID -- tested in instancing tests quite thoroughly.
1078 // Fragment shader builtin variables.
1079 testGroup
.addChild(new es3fShaderBuiltinVarTests
.FragCoordXYZCase());
1080 testGroup
.addChild(new es3fShaderBuiltinVarTests
.FragCoordWCase());
1081 testGroup
.addChild(new es3fShaderBuiltinVarTests
.PointCoordCase());
1082 testGroup
.addChild(new es3fShaderBuiltinVarTests
.FrontFacingCase());
1087 * @param {WebGL2RenderingContext} context
1089 es3fShaderBuiltinVarTests
.run = function(context
) {
1091 //Set up Test Root parameters
1092 var state
= tcuTestCase
.runner
;
1093 state
.setRoot(new es3fShaderBuiltinVarTests
.ShaderBuiltinVarTests());
1095 //Set up name and description of this test series.
1096 setCurrentTestName(state
.testCases
.fullName());
1097 description(state
.testCases
.getDescription());
1101 tcuTestCase
.runTestCases();
1104 testFailedOptions('Failed to es3fShaderBuiltinVarTests.run tests', false);
1105 tcuTestCase
.runner
.terminate();