multisample-draws-between-blits.html (5611B)
1 <!-- 2 Copyright (c) 2022 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 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 12 <script src="../../js/js-test-pre.js"></script> 13 <script src="../../js/webgl-test-utils.js"></script> 14 </head> 15 <body> 16 <canvas id="canvas" width="128" height="64" style="width: 32px; height: 32px;"></canvas> 17 <div id="description"></div> 18 <div id="console"></div> 19 <script> 20 "use strict"; 21 22 const wtu = WebGLTestUtils; 23 description(' Test multisample with blitting between draws'); 24 25 const gl = wtu.create3DContext("canvas", null, 2); 26 const w = 128; 27 const h = 64; 28 29 if (!gl) { 30 testFailed('canvas.getContext() failed'); 31 } else { 32 gl.viewport(0, 0, w, h); 33 runTest(gl, 4); 34 } 35 36 function runTest(gl, sampleCount) { 37 const vs = `#version 300 es 38 39 layout(location = 0) in vec4 position; 40 uniform mat4 mat; 41 42 void main() { 43 gl_Position = mat * position; 44 } 45 `; 46 47 const fs = `#version 300 es 48 precision mediump float; 49 uniform vec4 color; 50 out vec4 outColor; 51 void main() { 52 outColor = color; 53 } 54 `; 55 56 const texVS = `#version 300 es 57 58 layout(location = 0) in vec4 position; 59 out vec2 texcoord; 60 uniform mat4 mat; 61 62 void main() { 63 gl_Position = mat * position; 64 texcoord = position.xy; 65 } 66 `; 67 68 const texFS = `#version 300 es 69 precision mediump float; 70 in vec2 texcoord; 71 uniform sampler2D tex; 72 out vec4 outColor; 73 void main() { 74 outColor = texture(tex, texcoord); 75 } 76 `; 77 78 const msRB = gl.createRenderbuffer(); 79 gl.bindRenderbuffer(gl.RENDERBUFFER, msRB); 80 gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, w, h); 81 82 const msFB = gl.createFramebuffer(); 83 gl.bindFramebuffer(gl.FRAMEBUFFER, msFB); 84 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msRB); 85 86 const dTex = gl.createTexture(); 87 gl.bindTexture(gl.TEXTURE_2D, dTex); 88 gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h); 89 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 90 91 const dFB = gl.createFramebuffer(); 92 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dFB); 93 gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, dTex, 0); 94 95 const positionLoc = 0; // hard coded in shaders so they match 96 const buf = gl.createBuffer(); 97 gl.bindBuffer(gl.ARRAY_BUFFER, buf); 98 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 99 0, 0, 100 1, 0, 101 0, 1, 102 0, 1, 103 1, 0, 104 1, 1, 105 ]), gl.STATIC_DRAW); 106 gl.enableVertexAttribArray(positionLoc); 107 gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0); 108 109 const program = wtu.setupProgram(gl, [vs, fs]); 110 const texProgram = wtu.setupProgram(gl, [texVS, texFS]); 111 112 const colorLoc = gl.getUniformLocation(program, 'color'); 113 const matLoc = gl.getUniformLocation(program, 'mat'); 114 const texMatLoc = gl.getUniformLocation(texProgram, 'mat'); 115 116 gl.useProgram(program); 117 118 const drawAndResolve = (color, mat) => { 119 gl.bindFramebuffer(gl.FRAMEBUFFER, msFB); 120 gl.uniform4fv(colorLoc, color); 121 gl.uniformMatrix4fv(matLoc, false, mat); 122 gl.drawArrays(gl.TRIANGLES, 0, 6); 123 124 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dFB); 125 gl.blitFramebuffer(0, 0, w, h, 0, 0, w, h, gl.COLOR_BUFFER_BIT, gl.NEAREST); 126 }; 127 128 const check = (x, y, w, h, expected, msg) => { 129 gl.bindFramebuffer(gl.FRAMEBUFFER, dFB); 130 const tolerance = 2; // For multisampling resolution differences between GPUs 131 wtu.checkCanvasRect(gl, x, y, w, h, expected, msg, tolerance); 132 }; 133 134 const f32Red = [1, 0, 0, 1]; 135 const f32Green = [0, 1, 0, 1]; 136 const f32Gray = [0.5, 0.5, 0.5, 1]; 137 138 const u8Red = [255, 0, 0, 255]; 139 const u8Green = [ 0, 255, 0, 255]; 140 const u8LightRed = [255, 128, 128, 255]; 141 const u8LightGreen = [128, 255, 128, 255]; 142 143 debug('fill with red'); 144 drawAndResolve(f32Red, [ 145 2, 0, 0, 0, 146 0, 2, 0, 0, 147 0, 0, 1, 0, 148 -1, -1, 0, 1, 149 ]); 150 check(0, 0, w, h, u8Red, 'whole thing'); 151 152 debug('draw right in green'); 153 drawAndResolve(f32Green, [ 154 1, 0, 0, 0, 155 0, 2, 0, 0, 156 0, 0, 1, 0, 157 0, -1, 0, 1, 158 ]); 159 check(0, 0, w / 2, h, u8Red, 'left'); 160 check(w / 2, 0, w / 2, h, u8Green, 'right'); 161 162 debug('draw middle in gray with blending'); 163 gl.enable(gl.BLEND); 164 gl.blendFunc(gl.ONE, gl.ONE); 165 drawAndResolve(f32Gray, [ 166 1, 0, 0, 0, 167 0, 2, 0, 0, 168 0, 0, 1, 0, 169 -0.5, -1, 0, 1, 170 ]); 171 gl.disable(gl.BLEND); 172 173 /* 174 expected 175 +-----+-------+---------+--------+ 176 | red | ltRed | ltGreen | green | 177 +-----+-------+---------+--------+ 178 0,0 179 */ 180 181 check(0, 0, w / 4, h , u8Red, 'left edge') 182 check(w * 3 / 4, 0, w / 4, h, u8Green, 'right edge'); 183 check(w / 4, 0, w / 4, h, u8LightRed, 'left of center'); 184 check(w / 2, 0, w / 4, h, u8LightGreen, 'right of center'); 185 186 // show it 187 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 188 gl.useProgram(texProgram); 189 gl.uniformMatrix4fv(texMatLoc, false, [ 190 2, 0, 0, 0, 191 0, 2, 0, 0, 192 0, 0, 1, 0, 193 -1, -1, 0, 1, 194 ]); 195 gl.drawArrays(gl.TRIANGLES, 0, 6); 196 197 gl.deleteRenderbuffer(msRB); 198 gl.deleteTexture(dTex); 199 gl.deleteFramebuffer(msFB); 200 gl.deleteFramebuffer(dFB); 201 } 202 203 var successfullyParsed = true; 204 </script> 205 <script src="../../js/js-test-post.js"></script> 206 </body> 207 </html>