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.
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>
16 <canvas id=
"canvas" width=
"128" height=
"64" style=
"width: 32px; height: 32px;"></canvas>
17 <div id=
"description"></div>
18 <div id=
"console"></div>
22 const wtu
= WebGLTestUtils
;
23 description(' Test multisample with blitting between draws');
25 const gl
= wtu
.create3DContext("canvas", null, 2);
30 testFailed('canvas.getContext() failed');
32 gl
.viewport(0, 0, w
, h
);
36 function runTest(gl
, sampleCount
) {
37 const vs
= `#version 300 es
39 layout(location = 0) in vec4 position;
43 gl_Position = mat * position;
47 const fs
= `#version 300 es
48 precision mediump float;
56 const texVS
= `#version 300 es
58 layout(location = 0) in vec4 position;
63 gl_Position = mat * position;
64 texcoord = position.xy;
68 const texFS
= `#version 300 es
69 precision mediump float;
71 uniform sampler2D tex;
74 outColor = texture(tex, texcoord);
78 const msRB
= gl
.createRenderbuffer();
79 gl
.bindRenderbuffer(gl
.RENDERBUFFER
, msRB
);
80 gl
.renderbufferStorageMultisample(gl
.RENDERBUFFER
, 4, gl
.RGBA8
, w
, h
);
82 const msFB
= gl
.createFramebuffer();
83 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, msFB
);
84 gl
.framebufferRenderbuffer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.RENDERBUFFER
, msRB
);
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
);
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);
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([
106 gl
.enableVertexAttribArray(positionLoc
);
107 gl
.vertexAttribPointer(positionLoc
, 2, gl
.FLOAT
, false, 0, 0);
109 const program
= wtu
.setupProgram(gl
, [vs
, fs
]);
110 const texProgram
= wtu
.setupProgram(gl
, [texVS
, texFS
]);
112 const colorLoc
= gl
.getUniformLocation(program
, 'color');
113 const matLoc
= gl
.getUniformLocation(program
, 'mat');
114 const texMatLoc
= gl
.getUniformLocation(texProgram
, 'mat');
116 gl
.useProgram(program
);
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);
124 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, dFB
);
125 gl
.blitFramebuffer(0, 0, w
, h
, 0, 0, w
, h
, gl
.COLOR_BUFFER_BIT
, gl
.NEAREST
);
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
);
134 const f32Red
= [1, 0, 0, 1];
135 const f32Green
= [0, 1, 0, 1];
136 const f32Gray
= [0.5, 0.5, 0.5, 1];
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];
143 debug('fill with red');
144 drawAndResolve(f32Red
, [
150 check(0, 0, w
, h
, u8Red
, 'whole thing');
152 debug('draw right in green');
153 drawAndResolve(f32Green
, [
159 check(0, 0, w
/ 2, h
, u8Red
, 'left');
160 check(w
/ 2, 0, w
/ 2, h
, u8Green
, 'right');
162 debug('draw middle in gray with blending');
164 gl
.blendFunc(gl
.ONE
, gl
.ONE
);
165 drawAndResolve(f32Gray
, [
171 gl
.disable(gl
.BLEND
);
175 +-----+-------+---------+--------+
176 | red | ltRed | ltGreen | green |
177 +-----+-------+---------+--------+
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');
187 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
188 gl
.useProgram(texProgram
);
189 gl
.uniformMatrix4fv(texMatLoc
, false, [
195 gl
.drawArrays(gl
.TRIANGLES
, 0, 6);
197 gl
.deleteRenderbuffer(msRB
);
198 gl
.deleteTexture(dTex
);
199 gl
.deleteFramebuffer(msFB
);
200 gl
.deleteFramebuffer(dFB
);
203 var successfullyParsed
= true;
205 <script src=
"../../js/js-test-post.js"></script>