summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-in-loop.html
blob: 1c4709dd1032f54276df18e33ea79d22d98c765c (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
<!--
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>Conditional discard in loop issue</title>
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script>
</head>

<body>
<canvas id="output" style="border: none;" width="256" height="256"></canvas>
<div id="description"></div>
<div id="console"></div>

<script id="shader-vs" type="x-shader/x-vertex">
// Inputs
attribute vec4 a_position;
attribute vec2 a_tex_coords;

// Output
varying vec2   v_tex_coords;

void main(void) {
    v_tex_coords = a_tex_coords;
    gl_Position  = a_position;
}
</script>

<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;

// Constants
const float TEXEL_COUNT_V = 256.0;
const float TEXEL_HEIGHT  = 1.0 / TEXEL_COUNT_V;
const float SEP_IX        = TEXEL_COUNT_V / 2.0;

const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0);
const vec4 BLUE  = vec4(0.0, 0.0, 1.0, 1.0);

// Input
varying vec2 v_tex_coords;

uniform sampler2D u_data;

// Without this function or directly returning the data, the issue does not occur
mediump vec4 UnpackData(in vec4 inData) {
     float s = inData.x;
     // Note s is always 0
     // mod(0, 1) = 0
     // So return value = (0, 0, -1, 0)
    return vec4(0.0, 0.0, mod(s, 1.0) - 1.0, 0.0);

    // Comment out the line above and uncomment the line below and the test succeeds on angle-dx11
    // return vec4(0.0, 0.0, -1.0, 0.0);
}

void main(void) {
     // Set initial color
    gl_FragColor = BLUE;

    if (gl_FragCoord.y <= SEP_IX) {
        mediump vec2 addr = vec2(v_tex_coords.x, TEXEL_HEIGHT);

        for (float e_ix = 0.0; e_ix < TEXEL_COUNT_V; ++e_ix) {
            vec4 entry = texture2D(u_data, addr);
            mediump vec4 unpack = UnpackData(entry);

            // Buffer is filled with 0, unpack is always (0, 0, -1, 0)
            // So discard is always triggered
            if (unpack.z == -1.0) {
                discard;
            }

            addr.y += unpack.z * TEXEL_HEIGHT;
        }
        // If discard is not triggered the output color is blue
    }
    else {
        gl_FragColor = GREEN;
    }
}
</script>


<script>
"use strict";

description();
debug("");
debug("If the code is executed correctly, the upper half of the viewport will be green, the lower half will be red.");
debug("This is a conformance suite test for the issue reported here : https://code.google.com/p/angleproject/issues/detail?id=706");

var wtu = WebGLTestUtils;
var canvas = document.getElementById("output");
var gl = wtu.create3DContext(canvas);
if (!gl) {
  testFailed("context does not exist");
} else {

  // Create texture filled with zero's
  var tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, 	 gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, 	 gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  wtu.fillTexture(gl, tex, 256, 256, [0, 0, 0, 0]);

  // Clear complete viewport to red
  gl.clearColor(1.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  var attribBuffers = wtu.setupUnitQuad(gl, 0, 1);
  var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], ["a_position", "a_tex_coords"], [0, 1], true);

  // Bind texture
  var uniformMap = wtu.getUniformMap(gl, program);
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.uniform1i(uniformMap.u_data.location, 0);

  // Draw
  wtu.drawUnitQuad(gl);

  // Verify output
  wtu.checkCanvasRect(gl, 0,   0, 256, 128, [ 255,   0,   0, 255 ], "should be red",    1);
  wtu.checkCanvasRect(gl, 0, 128, 256, 128, [   0, 255,   0, 255 ], "should be green",  1);
}

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