blend-integer.html (5173B)
1 <!-- 2 Copyright (c) 2021 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>WebGL 2 Blend Integer Conformance Tests</title> 12 <link rel="stylesheet" href="../../resources/js-test-style.css" /> 13 <script src="../../js/js-test-pre.js"></script> 14 <script src="../../js/webgl-test-utils.js"></script> 15 </head> 16 <body> 17 <div id="description"></div> 18 <div id="console"></div> 19 <script id="outputVertexShader" type="x-shader/x-vertex"> 20 #version 300 es 21 in vec4 vPosition; 22 void main() 23 { 24 gl_Position = vPosition; 25 } 26 </script> 27 <script id="outputFragmentShaderSigned" type="x-shader/x-fragment"> 28 #version 300 es 29 layout(location = 1) out highp vec4 o_drawBuffer1; 30 layout(location = 2) out highp ivec4 o_drawBuffer2; 31 layout(location = 3) out highp vec4 o_drawBuffer3; 32 void main(void) 33 { 34 o_drawBuffer1 = vec4(0, 0, 0, 0); 35 o_drawBuffer2 = ivec4(0, 0, 0, 0); 36 o_drawBuffer3 = vec4(0, 0, 0, 0); 37 } 38 </script> 39 <script id="outputFragmentShaderUnsigned" type="x-shader/x-fragment"> 40 #version 300 es 41 layout(location = 1) out highp vec4 o_drawBuffer1; 42 layout(location = 2) out highp uvec4 o_drawBuffer2; 43 layout(location = 3) out highp vec4 o_drawBuffer3; 44 void main(void) 45 { 46 o_drawBuffer1 = vec4(0, 0, 0, 0); 47 o_drawBuffer2 = uvec4(0, 0, 0, 0); 48 o_drawBuffer3 = vec4(0, 0, 0, 0); 49 } 50 </script> 51 52 <script> 53 "use strict"; 54 description("This test verifies correct behavior of min/max blending operations on integer attachments."); 55 56 debug(""); 57 58 const wtu = WebGLTestUtils; 59 const gl = wtu.create3DContext(null, undefined, 2); 60 61 if (!gl) { 62 testFailed("WebGL context does not exist"); 63 } else { 64 testPassed("WebGL context exists"); 65 66 debug("") 67 debug("GL_MIN"); 68 runTest(false, gl.MIN); 69 runTest(true, gl.MIN); 70 71 debug("") 72 debug("GL_MAX"); 73 runTest(false, gl.MAX); 74 runTest(true, gl.MAX); 75 } 76 77 function compareValue(value, attachment, isSigned) { 78 const pixel = isSigned ? new Int32Array(4) : new Uint32Array(4); 79 gl.readBuffer(attachment); 80 gl.readPixels(0, 0, 1, 1, gl.RGBA_INTEGER, isSigned ? gl.INT : gl.UNSIGNED_INT, pixel); 81 let pass = true; 82 for (let i = 0; i < 4; i++) { 83 if (value[i] != pixel[i]) { 84 testFailed(`Read value of channel ${i} should be ${pixel[i]}, was ${value[i]}.`); 85 pass = false; 86 } 87 } 88 return pass; 89 } 90 91 function runTest(isSigned, operation) { 92 gl.viewport(0, 0, 1, 1); 93 gl.disable(gl.BLEND); 94 95 const program = wtu.setupProgram(gl, 96 ["outputVertexShader", 97 isSigned ? "outputFragmentShaderSigned" : "outputFragmentShaderUnsigned"], 98 ['vPosition'], [0]); 99 const quadParameters = wtu.setupUnitQuad(gl, 0, 1); 100 101 // Setup render targets 102 const fb = gl.createFramebuffer(); 103 gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 104 105 const rb1 = gl.createRenderbuffer(); 106 gl.bindRenderbuffer(gl.RENDERBUFFER, rb1); 107 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50); 108 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1); 109 110 const rb2 = gl.createRenderbuffer(); 111 gl.bindRenderbuffer(gl.RENDERBUFFER, rb2); 112 gl.renderbufferStorage(gl.RENDERBUFFER, isSigned ? gl.RGBA32I : gl.RGBA32UI, 50, 50); 113 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.RENDERBUFFER, rb2); 114 115 const rb3 = gl.createRenderbuffer(); 116 gl.bindRenderbuffer(gl.RENDERBUFFER, rb3); 117 gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50); 118 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.RENDERBUFFER, rb3); 119 120 gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3]); 121 122 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Pipeline setup complete."); 123 124 if (isSigned) { 125 const clearValue = new Int32Array([-1, 2, -3, 4]); 126 gl.clearBufferiv(gl.COLOR, 2, clearValue); 127 if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) { 128 testPassed("Signed clear passed."); 129 } else { 130 testFailed("Signed clear failed."); 131 } 132 } else { 133 const clearValue = new Uint32Array([1, 2, 3, 4]); 134 gl.clearBufferuiv(gl.COLOR, 2, clearValue); 135 if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) { 136 testPassed("Unsigned clear passed."); 137 } else { 138 testFailed("Unsigned clear failed."); 139 } 140 } 141 142 gl.blendEquation(operation); 143 gl.enable(gl.BLEND); 144 145 wtu.drawUnitQuad(gl); 146 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw complete."); 147 148 if (isSigned) { 149 const drawValue = new Int32Array([0, 0, 0, 0]); 150 if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) { 151 testPassed("Signed draw passed."); 152 } else { 153 testFailed("Signed draw failed."); 154 } 155 } else { 156 const drawValue = new Uint32Array([0, 0, 0, 0]); 157 if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) { 158 testPassed("Unsigned draw passed."); 159 } else { 160 testFailed("Unsigned draw failed."); 161 } 162 } 163 gl.deleteRenderbuffer(rb1); 164 gl.deleteRenderbuffer(rb2); 165 gl.deleteRenderbuffer(rb3); 166 gl.deleteFramebuffer(fb); 167 gl.deleteProgram(program); 168 } 169 170 debug(""); 171 var successfullyParsed = true; 172 </script> 173 <script src="../../js/js-test-post.js"></script> 174 175 </body> 176 </html>