summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-large-divisor.html
blob: 229649ee3c6b90bfbc516d383f9694727a221c92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<!--
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.
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL Instanced Arrays Conformance Tests - large vertex attrib divisors</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>
<canvas id="canvas"> </canvas>
<div id="console"></div>
<script id="outputVertexShader" type="x-shader/x-vertex">#version 300 es
layout(location = 0) in vec2 a_position;
layout(location = 1) in float a_positionOffset;
layout(location = 2) in vec4 a_color;
out vec4 v_color;
void main()
{
    gl_Position = vec4(a_position.x * 0.05 + a_positionOffset, a_position.y * 0.05, 0.0, 1.0);
    v_color = a_color;
}
</script>

<script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es
precision highp float;
in vec4 v_color;
out vec4 my_FragColor;
void main()
{
    my_FragColor = v_color;
}
</script>

<script>
"use strict";
description("Test switching vertex attrib divisor of one attribute between different large values");
// This is a regression test for http://anglebug.com/2832

debug("");

var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
canvas.width = 256;
canvas.height = 256;
var gl = wtu.create3DContext(canvas, null, 2);

var colorDivisor = 65536 * 2;

if (!gl) {
    testFailed("WebGL context does not exist");
} else {
    testPassed("WebGL context exists");

    runTest();
}

function runTest() {
    var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"]);

    gl.clearColor(0.0, 0.0, 1.0, 1.0);

    wtu.setupIndexedQuadWithOptions(gl, {positionLocation: 0});

    var offsetBuf = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuf);
    // Note that only the first two offsets below should be used for rendering.
    // We add some extra ones to the buffer since it can reveal if a too small divisor is used on the WebGL backend.
    var offsetData = [];
    for (var i = 0; i < 4; ++i) {
        offsetData.push(0.0 + i * 0.25);
    }
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(offsetData), gl.DYNAMIC_DRAW);

    gl.enableVertexAttribArray(1);
    gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);

    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up vertex buffer should succeed");

    var colorBuf = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
    // Red and green colors.
    var colorData = new Float32Array([1.0, 0.0, 0.0, 1.0,
                                      0.0, 1.0, 0.0, 1.0]);
    gl.bufferData(gl.ARRAY_BUFFER, colorData, gl.DYNAMIC_DRAW);

    gl.enableVertexAttribArray(2);
    gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0);
    gl.vertexAttribDivisor(2, colorDivisor);

    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up color buffer should succeed");

    var divisorsToTry = [
        256,
        65536,
        65536 * 2
    ];

    for (var i = 0; i < divisorsToTry.length; ++i) {
        runDrawElementsTest(divisorsToTry[i]);
    }
}

function runDrawElementsTest(divisor) {
    debug("Using divisor " + divisor);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.vertexAttribDivisor(1, divisor);

    var instanceCount = divisor + 1;
    var quadsRendered = Math.floor((instanceCount - 1) / divisor) + 1;

    gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);

    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Instanced draw should succeed");

    for (var quadIndex = 0; quadIndex < quadsRendered + 1; ++quadIndex) {
        var quadX = Math.floor((quadIndex / 8) * 256 + 128);
        var quadY = 128;
        if (quadIndex < quadsRendered) {
            var quadColorIndex = Math.floor((quadIndex * divisor) / colorDivisor);
            if (quadColorIndex == 0) {
                wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [255, 0, 0, 255]);
            } else {
                wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [0, 255, 0, 255]);
            }
        } else {
            wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [0, 0, 255, 255]);
        }
    }
}

debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>