Source code

Revision control

Copy as Markdown

Other Tools

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL 2 gl_VertexID Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/desktop-gl-constants.js"></script>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<!-- Shaders for testing instanced draws -->
<script id="vs" type="text/plain">
#version 300 es
flat out highp int vVertexID;
void main() {
vVertexID = gl_VertexID;
gl_PointSize = 1.0;
gl_Position = vec4(0,0,0,1);
}
</script>
<script id="fs" type="text/plain">
#version 300 es
flat in highp int vVertexID;
out highp int oVertexID;
void main() {
oVertexID = vVertexID;
}
</script>
<script>
"use strict";
description("Test gl_VertexID");
debug("");
const wtu = WebGLTestUtils;
const canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
const gl = wtu.create3DContext(canvas, null, 2);
(function() {
if (!gl) {
testFailed("WebGL context does not exist");
return;
}
testPassed("WebGL context exists");
const vs = document.getElementById("vs").innerHTML.trim();
const fs = document.getElementById("fs").innerHTML.trim();
const prog = wtu.loadProgram(gl, vs, fs);
gl.useProgram(prog);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32I, 1, 1);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after setup");
function shouldBeVal(prefix, expected, was) {
let text = prefix + "Should be " + expected;
let func = testPassed;
if (was != expected) {
text = text + ", was " + was;
func = testFailed;
}
func(text);
};
const readValData = new Int32Array(10000);
function ensureVal(prefix, expected) {
gl.readPixels(0, 0, 1, 1, gl.RGBA_INTEGER, gl.INT, readValData);
const was = readValData[0];
shouldBeVal(prefix, expected, was);
};
gl.clearBufferiv(gl.COLOR, 0, new Int32Array([42, 0, 0, 0]));
ensureVal("After clear", 42);
// -
debug("");
debug("----------------");
debug("drawArrays");
let test = function(first, count) {
debug("");
debug(`drawArrays(first: ${first}, count: ${count})`);
gl.drawArrays(gl.POINTS, first, count);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
ensureVal("", first+count-1);
};
test(0, 1);
test(1, 1);
test(10000, 1);
test(100000, 1);
test(1000000, 1);
test(0, 2);
test(1, 2);
test(10000, 2);
test(100000, 2);
test(1000000, 2);
const INT32_MAX = 0x7fffffff;
test = function(first, count) {
debug("");
debug(`drawArrays(first: ${first}, count: ${count})`);
gl.drawArrays(gl.POINTS, first, count);
if (!wtu.glErrorShouldBe(gl, [gl.NO_ERROR, gl.OUT_OF_MEMORY])) {
ensureVal("", first+count-1);
}
};
test(INT32_MAX-2, 1);
test(INT32_MAX-1, 1);
test(INT32_MAX, 1);
// -
debug("");
debug("----------------");
debug("drawElements");
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
const indexData = new Uint16Array([1, 2, 5, 3, 10000]);
debug("indexData: " + indexData);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
test = function(first, count) {
debug("");
debug(`drawElements(first: ${first}, count: ${count})`);
gl.drawElements(gl.POINTS, count, gl.UNSIGNED_SHORT, first*2);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
ensureVal("", indexData[first+count-1]);
};
for (let f = 0; f < indexData.length; ++f) {
for (let c = 1; f + c <= indexData.length; ++c) {
test(f, c);
}
}
// -
debug("");
debug("----------------");
debug("Via transform feedback");
gl.transformFeedbackVaryings(prog, ["vVertexID"], gl.INTERLEAVED_ATTRIBS);
wtu.linkProgram(gl, prog);
gl.useProgram(prog);
const tfBuffer = gl.createBuffer();
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*10000, gl.DYNAMIC_READ);
test = function(offset, count) {
debug("");
debug("drawArrays(" + offset + ", " + count + ")");
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, offset, count);
gl.endTransformFeedback();
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, readValData);
let ok = true;
for (let i = 0; i < readValData.length; i++) {
if (i >= count)
break;
const expected = offset + i;
const was = readValData[i];
if (was != expected) {
testFailed("[" + i + "] expected " + expected + ", was " + was);
ok = false;
break;
}
}
if (ok) {
testPassed("ok");
}
};
test(0, 1);
test(1, 1);
test(10000, 1);
test(0, 2);
test(1, 2);
test(10000, 2);
test(10000, 10000);
// -
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "There should be no remaining errors");
})();
debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>
<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->