Source code
Revision control
Copy as Markdown
Other Tools
<!--
Copyright (c) 2022 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">
<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="canvas" width="128" height="64" style="width: 32px; height: 32px;"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
const wtu = WebGLTestUtils;
description(' Test multisample with blitting between draws');
const gl = wtu.create3DContext("canvas", null, 2);
const w = 128;
const h = 64;
if (!gl) {
testFailed('canvas.getContext() failed');
} else {
gl.viewport(0, 0, w, h);
runTest(gl, 4);
}
function runTest(gl, sampleCount) {
const vs = `#version 300 es
layout(location = 0) in vec4 position;
uniform mat4 mat;
void main() {
gl_Position = mat * position;
}
`;
const fs = `#version 300 es
precision mediump float;
uniform vec4 color;
out vec4 outColor;
void main() {
outColor = color;
}
`;
const texVS = `#version 300 es
layout(location = 0) in vec4 position;
out vec2 texcoord;
uniform mat4 mat;
void main() {
gl_Position = mat * position;
texcoord = position.xy;
}
`;
const texFS = `#version 300 es
precision mediump float;
in vec2 texcoord;
uniform sampler2D tex;
out vec4 outColor;
void main() {
outColor = texture(tex, texcoord);
}
`;
const msRB = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, msRB);
gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, w, h);
const msFB = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, msFB);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msRB);
const dTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, dTex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
const dFB = gl.createFramebuffer();
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dFB);
gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, dTex, 0);
const positionLoc = 0; // hard coded in shaders so they match
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(positionLoc);
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
const program = wtu.setupProgram(gl, [vs, fs]);
const texProgram = wtu.setupProgram(gl, [texVS, texFS]);
const colorLoc = gl.getUniformLocation(program, 'color');
const matLoc = gl.getUniformLocation(program, 'mat');
const texMatLoc = gl.getUniformLocation(texProgram, 'mat');
gl.useProgram(program);
const drawAndResolve = (color, mat) => {
gl.bindFramebuffer(gl.FRAMEBUFFER, msFB);
gl.uniform4fv(colorLoc, color);
gl.uniformMatrix4fv(matLoc, false, mat);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dFB);
gl.blitFramebuffer(0, 0, w, h, 0, 0, w, h, gl.COLOR_BUFFER_BIT, gl.NEAREST);
};
const check = (x, y, w, h, expected, msg) => {
gl.bindFramebuffer(gl.FRAMEBUFFER, dFB);
const tolerance = 2; // For multisampling resolution differences between GPUs
wtu.checkCanvasRect(gl, x, y, w, h, expected, msg, tolerance);
};
const f32Red = [1, 0, 0, 1];
const f32Green = [0, 1, 0, 1];
const f32Gray = [0.5, 0.5, 0.5, 1];
const u8Red = [255, 0, 0, 255];
const u8Green = [ 0, 255, 0, 255];
const u8LightRed = [255, 128, 128, 255];
const u8LightGreen = [128, 255, 128, 255];
debug('fill with red');
drawAndResolve(f32Red, [
2, 0, 0, 0,
0, 2, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1,
]);
check(0, 0, w, h, u8Red, 'whole thing');
debug('draw right in green');
drawAndResolve(f32Green, [
1, 0, 0, 0,
0, 2, 0, 0,
0, 0, 1, 0,
0, -1, 0, 1,
]);
check(0, 0, w / 2, h, u8Red, 'left');
check(w / 2, 0, w / 2, h, u8Green, 'right');
debug('draw middle in gray with blending');
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE);
drawAndResolve(f32Gray, [
1, 0, 0, 0,
0, 2, 0, 0,
0, 0, 1, 0,
-0.5, -1, 0, 1,
]);
gl.disable(gl.BLEND);
/*
expected
+-----+-------+---------+--------+
| red | ltRed | ltGreen | green |
+-----+-------+---------+--------+
0,0
*/
check(0, 0, w / 4, h , u8Red, 'left edge')
check(w * 3 / 4, 0, w / 4, h, u8Green, 'right edge');
check(w / 4, 0, w / 4, h, u8LightRed, 'left of center');
check(w / 2, 0, w / 4, h, u8LightGreen, 'right of center');
// show it
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.useProgram(texProgram);
gl.uniformMatrix4fv(texMatLoc, false, [
2, 0, 0, 0,
0, 2, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1,
]);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.deleteRenderbuffer(msRB);
gl.deleteTexture(dTex);
gl.deleteFramebuffer(msFB);
gl.deleteFramebuffer(dFB);
}
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>