summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html
blob: 40ccfd0d860ceb329e8d4adb4e97e9612d148b39 (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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<!--
Copyright (c) 2021 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 2 Blend Integer Conformance Tests</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>
<div id="description"></div>
<div id="console"></div>
<script id="outputVertexShader" type="x-shader/x-vertex">
#version 300 es
in vec4 vPosition;
void main()
{
  gl_Position = vPosition;
}
</script>
<script id="outputFragmentShaderSigned" type="x-shader/x-fragment">
#version 300 es
layout(location = 1) out highp vec4 o_drawBuffer1;
layout(location = 2) out highp ivec4 o_drawBuffer2;
layout(location = 3) out highp vec4 o_drawBuffer3;
void main(void)
{
  o_drawBuffer1 = vec4(0, 0, 0, 0);
  o_drawBuffer2 = ivec4(0, 0, 0, 0);
  o_drawBuffer3 = vec4(0, 0, 0, 0);
}
</script>
<script id="outputFragmentShaderUnsigned" type="x-shader/x-fragment">
  #version 300 es
  layout(location = 1) out highp vec4 o_drawBuffer1;
  layout(location = 2) out highp uvec4 o_drawBuffer2;
  layout(location = 3) out highp vec4 o_drawBuffer3;
  void main(void)
  {
    o_drawBuffer1 = vec4(0, 0, 0, 0);
    o_drawBuffer2 = uvec4(0, 0, 0, 0);
    o_drawBuffer3 = vec4(0, 0, 0, 0);
  }
  </script>

<script>
"use strict";
description("This test verifies correct behavior of min/max blending operations on integer attachments.");

debug("");

const wtu = WebGLTestUtils;
const gl = wtu.create3DContext(null, undefined, 2);

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

  debug("")
  debug("GL_MIN");
  runTest(false, gl.MIN);
  runTest(true, gl.MIN);

  debug("")
  debug("GL_MAX");
  runTest(false, gl.MAX);
  runTest(true, gl.MAX);
}

function compareValue(value, attachment, isSigned) {
  const pixel = isSigned ? new Int32Array(4) : new Uint32Array(4);
  gl.readBuffer(attachment);
  gl.readPixels(0, 0, 1, 1, gl.RGBA_INTEGER, isSigned ? gl.INT : gl.UNSIGNED_INT, pixel);
  let pass = true;
  for (let i = 0; i < 4; i++) {
    if (value[i] != pixel[i]) {
      testFailed(`Read value of channel ${i} should be ${pixel[i]}, was ${value[i]}.`);
      pass = false;
    }
  }
  return pass;
}

function runTest(isSigned, operation) {
  gl.viewport(0, 0, 1, 1);
  gl.disable(gl.BLEND);

  const program = wtu.setupProgram(gl,
    ["outputVertexShader",
      isSigned ? "outputFragmentShaderSigned" : "outputFragmentShaderUnsigned"],
    ['vPosition'], [0]);
  const quadParameters = wtu.setupUnitQuad(gl, 0, 1);

  // Setup render targets
  const fb = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);

  const rb1 = gl.createRenderbuffer();
  gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
  gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50);
  gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1);

  const rb2 = gl.createRenderbuffer();
  gl.bindRenderbuffer(gl.RENDERBUFFER, rb2);
  gl.renderbufferStorage(gl.RENDERBUFFER, isSigned ? gl.RGBA32I : gl.RGBA32UI, 50, 50);
  gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.RENDERBUFFER, rb2);

  const rb3 = gl.createRenderbuffer();
  gl.bindRenderbuffer(gl.RENDERBUFFER, rb3);
  gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50);
  gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.RENDERBUFFER, rb3);

  gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3]);

  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Pipeline setup complete.");

  if (isSigned) {
    const clearValue = new Int32Array([-1, 2, -3, 4]);
    gl.clearBufferiv(gl.COLOR, 2, clearValue);
    if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) {
      testPassed("Signed clear passed.");
    } else {
      testFailed("Signed clear failed.");
    }
  } else {
    const clearValue = new Uint32Array([1, 2, 3, 4]);
    gl.clearBufferuiv(gl.COLOR, 2, clearValue);
    if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) {
      testPassed("Unsigned clear passed.");
    } else {
      testFailed("Unsigned clear failed.");
    }
  }

  gl.blendEquation(operation);
  gl.enable(gl.BLEND);

  wtu.drawUnitQuad(gl);
  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw complete.");

  if (isSigned) {
    const drawValue = new Int32Array([0, 0, 0, 0]);
    if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) {
      testPassed("Signed draw passed.");
    } else {
      testFailed("Signed draw failed.");
    }
  } else {
    const drawValue = new Uint32Array([0, 0, 0, 0]);
    if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) {
      testPassed("Unsigned draw passed.");
    } else {
      testFailed("Unsigned draw failed.");
    }
  }
  gl.deleteRenderbuffer(rb1);
  gl.deleteRenderbuffer(rb2);
  gl.deleteRenderbuffer(rb3);
  gl.deleteFramebuffer(fb);
  gl.deleteProgram(program);
}

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

</body>
</html>