tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

es3fFragDepthTests.js (21548B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES Utilities
      3 * ------------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the "License");
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *      http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an "AS IS" BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 */
     20 
     21 'use strict';
     22 goog.provide('functional.gles3.es3fFragDepthTests');
     23 goog.require('framework.common.tcuImageCompare');
     24 goog.require('framework.common.tcuRGBA');
     25 goog.require('framework.common.tcuSurface');
     26 goog.require('framework.common.tcuTestCase');
     27 goog.require('framework.delibs.debase.deMath');
     28 goog.require('framework.delibs.debase.deRandom');
     29 goog.require('framework.delibs.debase.deString');
     30 goog.require('framework.opengl.gluShaderProgram');
     31 goog.require('framework.opengl.gluDrawUtil');
     32 goog.require('modules.shared.glsShaderRenderCase');
     33 
     34 goog.scope(function() {
     35 var es3fFragDepthTests = functional.gles3.es3fFragDepthTests;
     36 var deMath = framework.delibs.debase.deMath;
     37 var deRandom = framework.delibs.debase.deRandom;
     38 var deString = framework.delibs.debase.deString;
     39 var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
     40 var gluShaderProgram = framework.opengl.gluShaderProgram;
     41 var gluDrawUtil = framework.opengl.gluDrawUtil;
     42 var tcuImageCompare = framework.common.tcuImageCompare;
     43 var tcuRGBA = framework.common.tcuRGBA;
     44 var tcuSurface = framework.common.tcuSurface;
     45 var tcuTestCase = framework.common.tcuTestCase;
     46 /** @typedef {function(Array<number>):number} */ es3fFragDepthTests.EvalFragDepthFunc;
     47 
     48 /** @const {string} */ es3fFragDepthTests.s_vertexShaderSrc = '' +
     49 	'#version 300 es\n' +
     50 	'in highp vec4 a_position;\n' +
     51 	'in highp vec2 a_coord;\n' +
     52 	'out highp vec2 v_coord;\n' +
     53 	'void main (void)\n' +
     54 	'{\n' +
     55 	'	gl_Position = a_position;\n' +
     56 	'	v_coord = a_coord;\n' +
     57 	'}\n';
     58 
     59 /** @const {string} */ es3fFragDepthTests.s_defaultFragmentShaderSrc = '' +
     60 	'#version 300 es\n' +
     61 	'uniform highp vec4 u_color;\n' +
     62 	'layout(location = 0) out mediump vec4 o_color;\n' +
     63 	'void main (void)\n' +
     64 	'{\n' +
     65 	'	o_color = u_color;\n' +
     66 	'}\n';
     67 
     68 /**
     69  * @param {number} func
     70  * @param {*} a
     71  * @param {*} b
     72  * @return {boolean}
     73  */
     74 es3fFragDepthTests.compare = function(func, a, b)	{
     75 	switch (func) {
     76 		case gl.NEVER: return false;
     77 		case gl.ALWAYS: return true;
     78 		case gl.LESS: return a < b;
     79 		case gl.LEQUAL: return a <= b;
     80 		case gl.EQUAL: return a === b;
     81 		case gl.NOTEQUAL: return a !== b;
     82 		case gl.GEQUAL: return a >= b;
     83 		case gl.GREATER: return a > b;
     84 	}
     85 	bufferedLogToConsole('Compare function not supported.');
     86 	return false;
     87 };
     88 
     89 /**
     90  * @constructor
     91  * @extends {tcuTestCase.DeqpTest}
     92  * @param {string} name
     93  * @param {string} desc
     94  * @param {string} fragSrc
     95  * @param {?es3fFragDepthTests.EvalFragDepthFunc} evalFunc
     96  * @param {number} compareFunc
     97  */
     98 es3fFragDepthTests.FragDepthCompareCase = function(name, desc, fragSrc, evalFunc, compareFunc) {
     99 	tcuTestCase.DeqpTest.call(this, name, desc);
    100 	/** @type {string} */ this.m_fragSrc = fragSrc;
    101 	/** @type {?es3fFragDepthTests.EvalFragDepthFunc} */ this.m_evalFunc = evalFunc;
    102 	/** @type {number} */ this.m_compareFunc = compareFunc;
    103 };
    104 
    105 es3fFragDepthTests.FragDepthCompareCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    106 es3fFragDepthTests.FragDepthCompareCase.prototype.constructor = es3fFragDepthTests.FragDepthCompareCase;
    107 
    108 /**
    109  * @return {tcuTestCase.IterateResult}
    110  */
    111 es3fFragDepthTests.FragDepthCompareCase.prototype.iterate = function() {
    112 	/** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
    113 	/** @type {number} */ var viewportW = Math.min(128, gl.drawingBufferWidth);
    114 	/** @type {number} */ var viewportH = Math.min(128, gl.drawingBufferHeight);
    115 	/** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - viewportW);
    116 	/** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - viewportH);
    117 	/** @type {tcuSurface.Surface} */ var renderedFrame = new tcuSurface.Surface(viewportW, viewportH);
    118 	/** @type {tcuSurface.Surface} */ var referenceFrame = new tcuSurface.Surface(viewportW, viewportH);
    119 	/** @type {number} */ var constDepth = 0.1;
    120 	var depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
    121 
    122 	/** @type {number} */ var xf;
    123 	/** @type {number} */ var d;
    124 	/** @type {boolean} */ var dpass;
    125 
    126 	if (depthBits == 0)
    127 		throw new Error('Depth buffer is required');
    128 
    129 	gl.depthMask(true);
    130 	gl.viewport(viewportX, viewportY, viewportW, viewportH);
    131 	gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    132 	gl.enable(gl.DEPTH_TEST);
    133 
    134 	/** @type {Array<number>} */ var quadIndices = [0, 1, 2, 2, 1, 3];
    135 
    136 	// Fill viewport with 2 quads - one with constant depth and another with d = [-1..1]
    137 	/** @type {gluShaderProgram.ShaderProgram} */
    138 	var basicQuadProgram = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, es3fFragDepthTests.s_defaultFragmentShaderSrc));
    139 
    140 	if (!basicQuadProgram.isOk()) {
    141 		bufferedLogToConsole(basicQuadProgram.getProgramInfo().infoLog);
    142 		throw new Error('Compile failed');
    143 	}
    144 
    145 	/** @type {Array<number>} */ var constDepthCoord = [
    146 		 -1.0, -1.0, constDepth, 1.0,
    147 		 -1.0, 1.0, constDepth, 1.0,
    148 		 0.0, -1.0, constDepth, 1.0,
    149 		 0.0, 1.0, constDepth, 1.0
    150 	];
    151 
    152 	/** @type {Array<number>} */ var varyingDepthCoord = [
    153 		 0.0, -1.0, 1.0, 1.0,
    154 		 0.0, 1.0, 0.0, 1.0,
    155 		 1.0, -1.0, 0.0, 1.0,
    156 		 1.0, 1.0, -1.0, 1.0
    157 	];
    158 
    159 	gl.useProgram(basicQuadProgram.getProgram());
    160 	gl.uniform4f(gl.getUniformLocation(basicQuadProgram.getProgram(), 'u_color'), 0.0, 0.0, 1.0, 1.0);
    161 	gl.depthFunc(gl.ALWAYS);
    162 
    163 	/** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, constDepthCoord);
    164 	gluDrawUtil.draw(gl, basicQuadProgram.getProgram(), [posBinding], gluDrawUtil.triangles(quadIndices));
    165 
    166 	posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, varyingDepthCoord);
    167 	gluDrawUtil.draw(gl, basicQuadProgram.getProgram(), [posBinding], gluDrawUtil.triangles(quadIndices));
    168 
    169 	// Render with depth test.
    170 	/** @type {gluShaderProgram.ShaderProgram} */
    171 	var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, this.m_fragSrc));
    172 	bufferedLogToConsole(program.getProgramInfo().infoLog);
    173 
    174 	if (!program.isOk())
    175 		throw new Error('Compile failed');
    176 
    177 	/** @type {Array<number>} */ var coord = [
    178 		0.0, 0.0,
    179 		0.0, 1.0,
    180 		1.0, 0.0,
    181 		1.0, 1.0
    182 	];
    183 
    184 	/** @type {Array<number>} */ var position = [
    185 		-1.0, -1.0, 1.0, 1.0,
    186 		-1.0, 1.0, 0.0, 1.0,
    187 		1.0, -1.0, 0.0, 1.0,
    188 		1.0, 1.0, -1.0, 1.0
    189 	];
    190 
    191 	gl.useProgram(program.getProgram());
    192 	gl.depthFunc(this.m_compareFunc);
    193 	gl.uniform4f(gl.getUniformLocation(program.getProgram(), 'u_color'), 0.0, 1.0, 0.0, 1.0);
    194 
    195 	// Setup default helper uniforms.
    196 	glsShaderRenderCase.setupDefaultUniforms(program.getProgram());
    197 
    198 	/** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var  vertexArrays = [
    199 		gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, position),
    200 		gluDrawUtil.newFloatVertexArrayBinding('a_coord', 2, 4, 0, coord)
    201 	];
    202 
    203 	gluDrawUtil.draw(gl, program.getProgram(), vertexArrays, gluDrawUtil.triangles(quadIndices));
    204 
    205 	renderedFrame.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
    206 
    207 	// Render reference.
    208 	for (var y = 0; y < referenceFrame.getHeight(); y++) {
    209 		/** @type {number} */ var yf = (y + 0.5) / referenceFrame.getHeight();
    210 		/** @type {number} */ var half = deMath.clamp(Math.floor(referenceFrame.getWidth() * 0.5 + 0.5), 0, referenceFrame.getWidth());
    211 
    212 		// Fill left half - comparison to constant 0.5
    213 		for (var x = 0; x < half; x++) {
    214 			xf = (x + 0.5) / referenceFrame.getWidth();
    215 			d = this.m_evalFunc([xf, yf]);
    216 			dpass = es3fFragDepthTests.compare(this.m_compareFunc, d, constDepth * 0.5 + 0.5);
    217 
    218 			referenceFrame.setPixel(x, y, dpass ? tcuRGBA.RGBA.green.toIVec() : tcuRGBA.RGBA.blue.toIVec());
    219 		}
    220 
    221 		// Fill right half - comparison to interpolated depth
    222 		for (var x = half; x < referenceFrame.getWidth(); x++) {
    223 			xf = (x + 0.5) / referenceFrame.getWidth();
    224 			/** @type {number} */ var xh = (x - half + 0.5) / (referenceFrame.getWidth() - half);
    225 			/** @type {number} */ var rd = 1.0 - (xh + yf) * 0.5;
    226 			d = this.m_evalFunc([xf, yf]);
    227 			dpass = es3fFragDepthTests.compare(this.m_compareFunc, d, rd);
    228 
    229 			referenceFrame.setPixel(x, y, dpass ? tcuRGBA.RGBA.green.toIVec() : tcuRGBA.RGBA.blue.toIVec());
    230 		}
    231 	}
    232 
    233 	/** @type {boolean} */ var isOk = tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', referenceFrame.getAccess(), renderedFrame.getAccess(), 0.05);
    234 
    235 	if (!isOk)
    236 		testFailedOptions('Fail', false);
    237 	else
    238 		testPassedOptions('Pass', true);
    239 
    240 	return tcuTestCase.IterateResult.STOP;
    241 };
    242 
    243 /**
    244  * @constructor
    245  * @extends {tcuTestCase.DeqpTest}
    246  * @param {string} name
    247  * @param {string} desc
    248  * @param {string} fragSrc
    249  * @param {es3fFragDepthTests.EvalFragDepthFunc} evalFunc
    250  */
    251 es3fFragDepthTests.FragDepthWriteCase = function(name, desc, fragSrc, evalFunc) {
    252 	tcuTestCase.DeqpTest.call(this, name, desc);
    253 	/** @type {string} */ this.m_fragSrc = fragSrc;
    254 	/** @type {es3fFragDepthTests.EvalFragDepthFunc} */ this.m_evalFunc = evalFunc;
    255 };
    256 
    257 es3fFragDepthTests.FragDepthWriteCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    258 es3fFragDepthTests.FragDepthWriteCase.prototype.constructor = es3fFragDepthTests.FragDepthWriteCase;
    259 
    260 /**
    261  * @return {tcuTestCase.IterateResult}
    262  */
    263 es3fFragDepthTests.FragDepthWriteCase.prototype.iterate = function() {
    264 	/** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
    265 	/** @type {number} */ var viewportW = Math.min(128, gl.drawingBufferWidth);
    266 	/** @type {number} */ var viewportH = Math.min(128, gl.drawingBufferHeight);
    267 	/** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - viewportW);
    268 	/** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - viewportH);
    269 	/** @type {tcuSurface.Surface} */ var renderedFrame = new tcuSurface.Surface(viewportW, viewportH);
    270 	/** @type {tcuSurface.Surface} */ var referenceFrame = new tcuSurface.Surface(viewportW, viewportH);
    271 	/** @type {number} */ var numDepthSteps = 16;
    272 	/** @type {number} */ var depthStep = 1.0 / (numDepthSteps - 1);
    273 	var depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
    274 
    275 	if (depthBits === 0)
    276 		throw new Error('Depth buffer is required');
    277 
    278 	gl.depthMask(true);
    279 	gl.viewport(viewportX, viewportY, viewportW, viewportH);
    280 	gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
    281 	gl.enable(gl.DEPTH_TEST);
    282 	gl.depthFunc(gl.LESS);
    283 
    284 	/** @type {Array<number>} */ var quadIndices = [0, 1, 2, 2, 1, 3];
    285 
    286 	// Render with given shader.
    287 	/** @type {gluShaderProgram.ShaderProgram} */
    288 	var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, this.m_fragSrc));
    289 	bufferedLogToConsole(program.getProgramInfo().infoLog);
    290 
    291 	if (!program.isOk())
    292 		throw new Error('Compile failed');
    293 
    294 	/** @type {Array<number>} */ var coord = [
    295 		0.0, 0.0,
    296 		0.0, 1.0,
    297 		1.0, 0.0,
    298 		1.0, 1.0
    299 	];
    300 
    301 	/** @type {Array<number>} */ var position = [
    302 		-1.0, -1.0, +1.0, 1.0,
    303 		-1.0, 1.0, 0.0, 1.0,
    304 		1.0, -1.0, 0.0, 1.0,
    305 		1.0, 1.0, -1.0, 1.0
    306 	];
    307 
    308 	gl.useProgram(program.getProgram());
    309 	gl.uniform4f(gl.getUniformLocation(program.getProgram(), 'u_color'), 0.0, 1.0, 0.0, 1.0);
    310 
    311 	// Setup default helper uniforms.
    312 	glsShaderRenderCase.setupDefaultUniforms(program.getProgram());
    313 
    314 	/** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var  vertexArrays = [
    315 		gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, position),
    316 		gluDrawUtil.newFloatVertexArrayBinding('a_coord', 2, 4, 0, coord)
    317 	];
    318 	gluDrawUtil.draw(gl, program.getProgram(), vertexArrays, gluDrawUtil.triangles(quadIndices));
    319 
    320 	// Visualize by rendering full-screen quads with increasing depth and color.
    321 	program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, es3fFragDepthTests.s_defaultFragmentShaderSrc));
    322 
    323 	if (!program.isOk()) {
    324 		bufferedLogToConsole(program.getProgramInfo().infoLog);
    325 		throw new Error('Compile failed');
    326 	}
    327 
    328 	/** @type {WebGLUniformLocation} */ var colorLoc = gl.getUniformLocation(program.getProgram(), 'u_color');
    329 
    330 	gl.useProgram(program.getProgram());
    331 	gl.depthMask(false);
    332 
    333 	for (var stepNdx = 0; stepNdx < numDepthSteps; stepNdx++) {
    334 		/** @type {number} */ var f = stepNdx * depthStep;
    335 		/** @type {number} */ var depth = f * 2.0 - 1.0;
    336 		/** @type {Array<number>} */ var color = [f, f, f, 1.0];
    337 
    338 		position = [
    339 			-1.0, -1.0, depth, 1.0,
    340 			-1.0, 1.0, depth, 1.0,
    341 			1.0, -1.0, depth, 1.0,
    342 			1.0, 1.0, depth, 1.0
    343 		];
    344 
    345 		/** @type {gluDrawUtil.VertexArrayBinding} */
    346 		var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, position);
    347 
    348 		gl.uniform4fv(colorLoc, color);
    349 		gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(quadIndices));
    350 	}
    351 
    352 	renderedFrame.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
    353 
    354 	// Render reference.
    355 	for (var y = 0; y < referenceFrame.getHeight(); y++)
    356 	for (var x = 0; x < referenceFrame.getWidth(); x++) {
    357 		/** @type {number} */ var xf = (x + 0.5) / referenceFrame.getWidth();
    358 		/** @type {number} */ var yf = (y + 0.5) / referenceFrame.getHeight();
    359 		/** @type {number} */ var d = this.m_evalFunc([xf, yf]);
    360 		/** @type {number} */ var step = Math.floor(d / depthStep);
    361 		/** @type {number} */ var col = deMath.clamp(Math.floor(step * depthStep * 255.0), 0, 255);
    362 
    363 		referenceFrame.setPixel(x, y, [col, col, col, 0xff]);
    364 	}
    365 
    366 	/** @type {boolean} */ var isOk = tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', referenceFrame.getAccess(), renderedFrame.getAccess(), 0.05);
    367 
    368 	if (!isOk)
    369 		testFailedOptions('Fail', false);
    370 	else
    371 		testPassedOptions('Pass', true);
    372 
    373 	return tcuTestCase.IterateResult.STOP;
    374 };
    375 
    376 
    377 /**
    378  * @constructor
    379  * @extends {tcuTestCase.DeqpTest}
    380  */
    381 es3fFragDepthTests.FragDepthTests = function() {
    382 	tcuTestCase.DeqpTest.call(this, 'fragdepth', 'gl_FragDepth tests');
    383 };
    384 
    385 es3fFragDepthTests.FragDepthTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
    386 es3fFragDepthTests.FragDepthTests.prototype.constructor = es3fFragDepthTests.FragDepthTests;
    387 
    388 /**
    389  * @param {Array<number>} coord
    390  * @return {number}
    391  */
    392 es3fFragDepthTests.evalConstDepth = function(coord) {
    393 	return 0.5;
    394 };
    395 
    396 /**
    397  * @param {Array<number>} coord
    398  * @return {number}
    399  */
    400 es3fFragDepthTests.evalDynamicDepth = function(coord) {
    401 	return (coord[0] + coord[1]) * 0.5;
    402 };
    403 
    404 /**
    405  * @param {Array<number>} coord
    406  * @return {number}
    407  */
    408 es3fFragDepthTests.evalNoWrite = function(coord) {
    409 	return 1.0 - (coord[0] + coord[1]) * 0.5;
    410 };
    411 
    412 /**
    413  * @param {Array<number>} coord
    414  * @return {number}
    415  */
    416 es3fFragDepthTests.evalDynamicConditionalDepth = function(coord) {
    417 	/** @type {number} */ var d = (coord[0] + coord[1]) * 0.5;
    418 	if (coord[1] < 0.5)
    419 		return d;
    420 	else
    421 		return 1.0 - d;
    422 };
    423 
    424 es3fFragDepthTests.FragDepthTests.prototype.init = function() {
    425 	/**
    426 	 * @struct
    427 	 * @constructor
    428 	 * @param {string} name
    429 	 * @param {string} desc
    430 	 * @param {es3fFragDepthTests.EvalFragDepthFunc} evalFunc
    431 	 * @param {string} fragSrc
    432 	 */
    433 	var Case = function(name, desc, evalFunc, fragSrc) {
    434 		/** @type {string} */ this.name = name;
    435 		/** @type {string} */ this.desc = desc;
    436 		/** @type {es3fFragDepthTests.EvalFragDepthFunc} */ this.evalFunc = evalFunc;
    437 		/** @type {string} */ this.fragSrc = fragSrc;
    438 	};
    439 
    440 	/** @type {Array<Case>} */ var cases = [
    441 		new Case('no_write', 'No gl_FragDepth write', es3fFragDepthTests.evalNoWrite,
    442 			'#version 300 es\n' +
    443 			'uniform highp vec4 u_color;\n' +
    444 			'layout(location = 0) out mediump vec4 o_color;\n' +
    445 			'void main (void)\n' +
    446 			'{\n' +
    447 			'	o_color = u_color;\n' +
    448 			'}\n'
    449 		),
    450 		new Case('const', 'Const depth write', es3fFragDepthTests.evalConstDepth,
    451 			'#version 300 es\n' +
    452 			'uniform highp vec4 u_color;\n' +
    453 			'layout(location = 0) out mediump vec4 o_color;\n' +
    454 			'void main (void)\n' +
    455 			'{\n' +
    456 			'	o_color = u_color;\n' +
    457 			'	gl_FragDepth = 0.5;\n' +
    458 			'}\n'
    459 		),
    460 		new Case('uniform', 'Uniform depth write', es3fFragDepthTests.evalConstDepth,
    461 			'#version 300 es\n' +
    462 			'uniform highp vec4 u_color;\n' +
    463 			'uniform highp float uf_half;\n' +
    464 			'layout(location = 0) out mediump vec4 o_color;\n' +
    465 			'void main (void)\n' +
    466 			'{\n' +
    467 			'	o_color = u_color;\n' +
    468 			'	gl_FragDepth = uf_half;\n' +
    469 			'}\n'
    470 		),
    471 		new Case('dynamic', 'Dynamic depth write', es3fFragDepthTests.evalDynamicDepth,
    472 			'#version 300 es\n' +
    473 			'uniform highp vec4 u_color;\n' +
    474 			'in highp vec2 v_coord;\n' +
    475 			'layout(location = 0) out mediump vec4 o_color;\n' +
    476 			'void main (void)\n' +
    477 			'{\n' +
    478 			'	o_color = u_color;\n' +
    479 			'	gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n' +
    480 			'}\n'
    481 		),
    482 		new Case('fragcoord_z', 'gl_FragDepth write from gl_FragCoord.z', es3fFragDepthTests.evalNoWrite,
    483 			'#version 300 es\n' +
    484 			'uniform highp vec4 u_color;\n' +
    485 			'layout(location = 0) out mediump vec4 o_color;\n' +
    486 			'void main (void)\n' +
    487 			'{\n' +
    488 			'	o_color = u_color;\n' +
    489 			'	gl_FragDepth = gl_FragCoord.z;\n' +
    490 			'}\n'
    491 		),
    492 		new Case('uniform_conditional_write', 'Uniform conditional write', es3fFragDepthTests.evalDynamicDepth,
    493 			'#version 300 es\n' +
    494 			'uniform highp vec4 u_color;\n' +
    495 			'uniform bool ub_true;\n' +
    496 			'in highp vec2 v_coord;\n' +
    497 			'layout(location = 0) out mediump vec4 o_color;\n' +
    498 			'void main (void)\n' +
    499 			'{\n' +
    500 			'	o_color = u_color;\n' +
    501 			'	if (ub_true)\n' +
    502 			'		gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n' +
    503 			'}\n'
    504 		),
    505 		new Case('dynamic_conditional_write', 'Uniform conditional write', es3fFragDepthTests.evalDynamicConditionalDepth,
    506 			'#version 300 es\n' +
    507 			'uniform highp vec4 u_color;\n' +
    508 			'uniform bool ub_true;\n' +
    509 			'in highp vec2 v_coord;\n' +
    510 			'layout(location = 0) out mediump vec4 o_color;\n' +
    511 			'void main (void)\n' +
    512 			'{\n' +
    513 			'	o_color = u_color;\n' +
    514 			'	mediump float d = (v_coord.x+v_coord.y)*0.5f;\n' +
    515 			'	if (v_coord.y < 0.5)\n' +
    516 			'		gl_FragDepth = d;\n' +
    517 			'	else\n' +
    518 			'		gl_FragDepth = 1.0 - d;\n' +
    519 			'}\n'
    520 		),
    521 		new Case('uniform_loop_write', 'Uniform loop write', es3fFragDepthTests.evalConstDepth,
    522 			'#version 300 es\n' +
    523 			'uniform highp vec4 u_color;\n' +
    524 			'uniform int ui_two;\n' +
    525 			'uniform highp float uf_fourth;\n' +
    526 			'in highp vec2 v_coord;\n' +
    527 			'layout(location = 0) out mediump vec4 o_color;\n' +
    528 			'void main (void)\n' +
    529 			'{\n' +
    530 			'	o_color = u_color;\n' +
    531 			'	gl_FragDepth = 0.0;\n' +
    532 			'	for (int i = 0; i < ui_two; i++)\n' +
    533 			'		gl_FragDepth += uf_fourth;\n' +
    534 			'}\n'
    535 		),
    536 		new Case('write_in_function', 'Uniform loop write', es3fFragDepthTests.evalDynamicDepth,
    537 			'#version 300 es\n' +
    538 			'uniform highp vec4 u_color;\n' +
    539 			'uniform highp float uf_half;\n' +
    540 			'in highp vec2 v_coord;\n' +
    541 			'layout(location = 0) out mediump vec4 o_color;\n' +
    542 			'void myfunc (highp vec2 coord)\n' +
    543 			'{\n' +
    544 			'	gl_FragDepth = (coord.x+coord.y)*0.5;\n' +
    545 			'}\n' +
    546 			'void main (void)\n' +
    547 			'{\n' +
    548 			'	o_color = u_color;\n' +
    549 			'	myfunc(v_coord);\n' +
    550 			'}\n'
    551 		)
    552 	];
    553 
    554 	var testGroup = tcuTestCase.runner.testCases;
    555 
    556 	// .write
    557 	/** @type {tcuTestCase.DeqpTest} */ var writeGroup = tcuTestCase.newTest('write', 'gl_FragDepth write tests');
    558 	testGroup.addChild(writeGroup);
    559 	for (var ndx = 0; ndx < cases.length; ndx++)
    560 		writeGroup.addChild(new es3fFragDepthTests.FragDepthWriteCase(cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc));
    561 
    562 	// .compare
    563 	/** @type {tcuTestCase.DeqpTest} */ var compareGroup = tcuTestCase.newTest('compare', 'gl_FragDepth used with depth comparison');
    564 	testGroup.addChild(compareGroup);
    565 	for (var ndx = 0; ndx < cases.length; ndx++)
    566 		compareGroup.addChild(new es3fFragDepthTests.FragDepthCompareCase(cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc, gl.LESS));
    567 };
    568 
    569    /**
    570    * Run test
    571    * @param {WebGL2RenderingContext} context
    572    */
    573    es3fFragDepthTests.run = function(context) {
    574    	gl = context;
    575    	//Set up Test Root parameters
    576    	var state = tcuTestCase.runner;
    577    	state.setRoot(new es3fFragDepthTests.FragDepthTests());
    578 
    579    	//Set up name and description of this test series.
    580    	setCurrentTestName(state.testCases.fullName());
    581    	description(state.testCases.getDescription());
    582 
    583    	try {
    584    		//Run test cases
    585    		tcuTestCase.runTestCases();
    586    	}
    587    	catch (err) {
    588    		testFailedOptions('Failed to es3fFragDepthTests.run tests', false);
    589    		tcuTestCase.runner.terminate();
    590    	}
    591    };
    592 
    593 });