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.es3fIndexedStateQueryTests');
23 goog.require('framework.common.tcuTestCase');
24 goog.require('functional.gles3.es3fApiCase');
26 goog.scope(function() {
27 var es3fIndexedStateQueryTests = functional.gles3.es3fIndexedStateQueryTests;
28 var tcuTestCase = framework.common.tcuTestCase;
29 var es3fApiCase = functional.gles3.es3fApiCase;
33 * @extends {es3fApiCase.ApiCase}
34 * @param {string} name
35 * @param {string} description
37 es3fIndexedStateQueryTests.TransformFeedbackCase = function(name, description) {
38 es3fApiCase.ApiCase.call(this, name, description, gl);
41 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
42 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackCase;
44 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.testTransformFeedback = function() {
45 throw new Error('This method should be overriden.');
48 es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.test = function() {
49 /** @type {string} */ var transformFeedbackTestVertSource = '' +
51 'out highp vec4 anotherOutput;\n' +
52 'void main (void)\n' +
54 ' gl_Position = vec4(0.0);\n' +
55 ' anotherOutput = vec4(0.0);\n' +
57 /** @type {string} */ var transformFeedbackTestFragSource = '' +
59 'layout(location = 0) out mediump vec4 fragColor;' +
60 'void main (void)\n' +
62 ' fragColor = vec4(0.0);\n' +
65 /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
66 /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
68 gl.shaderSource(shaderVert, transformFeedbackTestVertSource);
69 gl.shaderSource(shaderFrag, transformFeedbackTestFragSource);
71 gl.compileShader(shaderVert);
72 gl.compileShader(shaderFrag);
74 /** @type {WebGLProgram} */ var shaderProg = gl.createProgram();
75 gl.attachShader(shaderProg, shaderVert);
76 gl.attachShader(shaderProg, shaderFrag);
78 /** @type {Array<string>} */ var transformFeedbackOutputs = ['gl_Position', 'anotherOutput'];
80 gl.transformFeedbackVaryings(shaderProg, transformFeedbackOutputs, gl.INTERLEAVED_ATTRIBS);
81 gl.linkProgram(shaderProg);
83 /** @type {WebGLTransformFeedback} */ var transformFeedbackId = gl.createTransformFeedback();
84 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackId);
86 this.testTransformFeedback();
90 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
92 gl.deleteTransformFeedback(transformFeedbackId);
93 gl.deleteShader(shaderVert);
94 gl.deleteShader(shaderFrag);
95 gl.deleteProgram(shaderProg);
100 * @extends {es3fIndexedStateQueryTests.TransformFeedbackCase}
101 * @param {string} name
102 * @param {string} description
104 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase = function(name, description) {
105 es3fIndexedStateQueryTests.TransformFeedbackCase.call(this, name, description);
108 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype = Object.create(es3fIndexedStateQueryTests.TransformFeedbackCase.prototype);
109 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase;
111 es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype.testTransformFeedback = function() {
112 /** @type {number} */ var feedbackPositionIndex = 0;
113 /** @type {number} */ var feedbackOutputIndex = 1;
114 /** @type {Array<number>} */ var feedbackIndex = [feedbackPositionIndex, feedbackOutputIndex];
118 /** @type {Array<WebGLBuffer>} */ var feedbackBuffers = [];
119 for (var ndx = 0; ndx < 2; ndx++)
120 feedbackBuffers[ndx] = gl.createBuffer();
122 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) {
123 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[ndx]);
124 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ);
125 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackIndex[ndx], feedbackBuffers[ndx]);
128 // test TRANSFORM_FEEDBACK_BUFFER_BINDING
129 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) {
130 var boundBuffer = /** @type {WebGLBuffer} */ (gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, ndx));
131 this.check(boundBuffer === feedbackBuffers[ndx], 'buffers do not match');
135 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++)
136 gl.deleteBuffer(feedbackBuffers[ndx]);
141 * @extends {es3fIndexedStateQueryTests.TransformFeedbackCase}
142 * @param {string} name
143 * @param {string} description
145 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase = function(name, description) {
146 es3fIndexedStateQueryTests.TransformFeedbackCase.call(this, name, description);
149 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype = Object.create(es3fIndexedStateQueryTests.TransformFeedbackCase.prototype);
150 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase;
152 es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype.testTransformFeedback = function() {
153 /** @type {number} */ var feedbackPositionIndex = 0;
154 /** @type {number} */ var feedbackOutputIndex = 1;
156 /** @type {number} */ var rangeBufferOffset = 4;
157 /** @type {number} */ var rangeBufferSize = 8;
161 /** @type {Array<WebGLBuffer>} */ var feedbackBuffers = [];
162 for (var ndx = 0; ndx < 2; ndx++)
163 feedbackBuffers[ndx] = gl.createBuffer();
165 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[0]);
166 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ);
167 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackPositionIndex, feedbackBuffers[0]);
169 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[1]);
170 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ);
171 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackOutputIndex, feedbackBuffers[1], rangeBufferOffset, rangeBufferSize);
173 /** @type {Array<{index: number, pname: number, value: number}>} */ var requirements = [
174 {index: feedbackPositionIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_START, value: 0},
175 {index: feedbackPositionIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, value: 0},
176 {index: feedbackOutputIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_START, value: rangeBufferOffset},
177 {index: feedbackOutputIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, value: rangeBufferSize}
180 for (var ndx = 0; ndx < requirements.length; ndx++) {
181 var state = /** @type {number} */ (gl.getIndexedParameter(requirements[ndx].pname, requirements[ndx].index));
182 this.check(state === requirements[ndx].value, 'got ' + state + '; expected ' + requirements[ndx].value);
186 for (var ndx = 0; ndx < feedbackBuffers.length; ndx++)
187 gl.deleteBuffer(feedbackBuffers[ndx]);
192 * @extends {es3fApiCase.ApiCase}
193 * @param {string} name
194 * @param {string} description
196 es3fIndexedStateQueryTests.UniformBufferCase = function(name, description) {
197 es3fApiCase.ApiCase.call(this, name, description, gl);
198 /** @type {?WebGLProgram} */ this.m_program = null;
201 es3fIndexedStateQueryTests.UniformBufferCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
202 es3fIndexedStateQueryTests.UniformBufferCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferCase;
204 es3fIndexedStateQueryTests.UniformBufferCase.prototype.testUniformBuffers = function() {
205 throw new Error('This method should be overriden.');
208 es3fIndexedStateQueryTests.UniformBufferCase.prototype.test = function() {
210 /** @type {string} */ var testVertSource = '' +
211 '#version 300 es\n' +
212 'uniform highp vec4 input1;\n' +
213 'uniform highp vec4 input2;\n' +
214 'void main (void)\n' +
216 ' gl_Position = input1 + input2;\n' +
218 /** @type {string} */ var testFragSource = '' +
219 '#version 300 es\n' +
220 'layout(location = 0) out mediump vec4 fragColor;' +
221 'void main (void)\n' +
223 ' fragColor = vec4(0.0);\n' +
226 /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
227 /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
229 gl.shaderSource(shaderVert, testVertSource);
230 gl.shaderSource(shaderFrag, testFragSource);
232 gl.compileShader(shaderVert);
233 gl.compileShader(shaderFrag);
235 this.m_program = gl.createProgram();
236 gl.attachShader(this.m_program, shaderVert);
237 gl.attachShader(this.m_program, shaderFrag);
238 gl.linkProgram(this.m_program);
239 gl.useProgram(this.m_program);
241 this.testUniformBuffers();
244 gl.deleteShader(shaderVert);
245 gl.deleteShader(shaderFrag);
246 gl.deleteProgram(this.m_program);
251 * @extends {es3fIndexedStateQueryTests.UniformBufferCase}
252 * @param {string} name
253 * @param {string} description
255 es3fIndexedStateQueryTests.UniformBufferBindingCase = function(name, description) {
256 es3fIndexedStateQueryTests.UniformBufferCase.call(this, name, description);
257 /** @type {?WebGLProgram} */ this.m_program = null;
260 es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype = Object.create(es3fIndexedStateQueryTests.UniformBufferCase.prototype);
261 es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferBindingCase;
263 es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype.testUniformBuffers = function() {
264 /** @type {Array<string>} */ var uniformNames = ['input1', 'input2'];
266 /** @type {Array<number>} */ var uniformIndices = gl.getUniformIndices(this.m_program, uniformNames);
268 /** @type {Array<WebGLBuffer>} */ var buffers = [];
269 for (var ndx = 0; ndx < 2; ndx++)
270 buffers[ndx] = gl.createBuffer();
272 for (var ndx = 0; ndx < buffers.length; ++ndx) {
273 gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[ndx]);
274 gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW);
275 gl.bindBufferBase(gl.UNIFORM_BUFFER, uniformIndices[ndx], buffers[ndx]);
278 /** @type {Array<WebGLBuffer>} */ var boundBuffer = [];
279 for (var ndx = 0; ndx < buffers.length; ndx++) {
280 boundBuffer[ndx] = /** @type {WebGLBuffer} */ (gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, uniformIndices[ndx]));
281 this.check(boundBuffer[ndx] === buffers[ndx], 'buffers do not match');
284 for (var ndx = 0; ndx < buffers.length; ndx++)
285 gl.deleteBuffer(buffers[ndx]);
290 * @extends {es3fIndexedStateQueryTests.UniformBufferCase}
291 * @param {string} name
292 * @param {string} description
294 es3fIndexedStateQueryTests.UniformBufferBufferCase = function(name, description) {
295 es3fIndexedStateQueryTests.UniformBufferCase.call(this, name, description);
296 /** @type {?WebGLProgram} */ this.m_program = null;
299 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype = Object.create(es3fIndexedStateQueryTests.UniformBufferCase.prototype);
300 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferBufferCase;
302 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.testUniformBuffers = function() {
303 /** @type {Array<string>} */ var uniformNames = ['input1', 'input2'];
305 /** @type {Array<number>} */ var uniformIndices = gl.getUniformIndices(this.m_program, uniformNames);
307 /** @type {number} */ var alignment = this.getAlignment();
308 if (alignment === -1) // cannot continue without this
311 bufferedLogToConsole('Alignment is ' + alignment);
313 /** @type {number} */ var rangeBufferOffset = alignment;
314 /** @type {number} */ var rangeBufferSize = alignment * 2;
315 /** @type {number} */ var rangeBufferTotalSize = rangeBufferOffset + rangeBufferSize + 8; // + 8 has no special meaning, just to make it != with the size of the range
317 /** @type {Array<WebGLBuffer>} */ var buffers = [];
318 for (var ndx = 0; ndx < 2; ndx++)
319 buffers[ndx] = gl.createBuffer();
321 gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[0]);
322 gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW);
323 gl.bindBufferBase(gl.UNIFORM_BUFFER, uniformIndices[0], buffers[0]);
325 gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[1]);
326 gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW);
327 gl.bindBufferRange(gl.UNIFORM_BUFFER, uniformIndices[1], buffers[1], rangeBufferOffset, rangeBufferSize);
329 // test UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE
331 /** @type {Array<{index: number, pname: number, value: number}>} */ var requirements = [
332 {index: uniformIndices[0], pname: gl.UNIFORM_BUFFER_START, value: 0},
333 {index: uniformIndices[0], pname: gl.UNIFORM_BUFFER_SIZE, value: 0},
334 {index: uniformIndices[1], pname: gl.UNIFORM_BUFFER_START, value: rangeBufferOffset},
335 {index: uniformIndices[1], pname: gl.UNIFORM_BUFFER_SIZE, value: rangeBufferSize}
338 for (var ndx = 0; ndx < requirements.length; ndx++) {
339 var state = /** @type {number} */ (gl.getIndexedParameter(requirements[ndx].pname, requirements[ndx].index));
341 this.check(state === requirements[ndx].value, 'got ' + state + '; expected ' + requirements[ndx].value);
344 for (var ndx = 0; ndx < buffers.length; ndx++)
345 gl.deleteBuffer(buffers[ndx]);
352 es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.getAlignment = function() {
353 var state = /** @type {number} */ (gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT));
358 bufferedLogToConsole('ERROR: UNIFORM_BUFFER_OFFSET_ALIGNMENT has a maximum value of 256.');
359 testFailedOptions('invalid UNIFORM_BUFFER_OFFSET_ALIGNMENT value', false);
366 * @extends {tcuTestCase.DeqpTest}
368 es3fIndexedStateQueryTests.IndexedStateQueryTests = function() {
369 tcuTestCase.DeqpTest.call(this, 'indexed', 'Indexed Integer Values');
372 es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
373 es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype.constructor = es3fIndexedStateQueryTests.IndexedStateQueryTests;
375 es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype.init = function() {
376 // transform feedback
377 this.addChild(new es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase('transform_feedback_buffer_binding', 'TRANSFORM_FEEDBACK_BUFFER_BINDING'));
378 this.addChild(new es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase('transform_feedback_buffer_start_size', 'TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE'));
381 this.addChild(new es3fIndexedStateQueryTests.UniformBufferBindingCase('uniform_buffer_binding', 'UNIFORM_BUFFER_BINDING'));
382 this.addChild(new es3fIndexedStateQueryTests.UniformBufferBufferCase('uniform_buffer_start_size', 'UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE'));
387 * @param {WebGL2RenderingContext} context
389 es3fIndexedStateQueryTests.run = function(context) {
391 //Set up Test Root parameters
392 var state = tcuTestCase.runner;
393 state.setRoot(new es3fIndexedStateQueryTests.IndexedStateQueryTests());
395 //Set up name and description of this test series.
396 setCurrentTestName(state.testCases.fullName());
397 description(state.testCases.getDescription());
401 tcuTestCase.runTestCases();
404 testFailedOptions('Failed to es3fIndexedStateQueryTests.run tests', false);
405 tcuTestCase.runner.terminate();