| <!-- |
| Copyright (c) 2019 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 BlitFramebuffer Stencil-only 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> |
| |
| <script id="vs" type="x-shader/x-vertex">#version 300 es |
| in vec4 position; |
| void main() { |
| gl_Position = position; |
| } |
| </script> |
| <script id="fs" type="x-shader/x-fragment">#version 300 es |
| out mediump vec4 colorOut; |
| uniform mediump vec3 color; |
| void main() { |
| colorOut = vec4(color, 1.0); |
| } |
| </script> |
| |
| </head> |
| <body> |
| <canvas id="example" width="8" height="8"></canvas> |
| <div id="description"></div> |
| <div id="console"></div> |
| |
| <script> |
| "use strict"; |
| |
| var wtu = WebGLTestUtils; |
| description("This test covers some edge cases of blitFramebuffer with stencil."); |
| |
| var gl = wtu.create3DContext("example", undefined, 2); |
| |
| var program, colorLoc; |
| |
| function init_buffer(format) { |
| var buf = gl.createFramebuffer(); |
| gl.bindFramebuffer(gl.FRAMEBUFFER, buf) |
| var tex = gl.createTexture(); |
| gl.bindTexture(gl.TEXTURE_2D, tex); |
| gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 16, 16); |
| gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); |
| var rbo = gl.createRenderbuffer(); |
| gl.bindRenderbuffer(gl.RENDERBUFFER, rbo); |
| gl.renderbufferStorage(gl.RENDERBUFFER, format, 16, 16); |
| gl.framebufferRenderbuffer(gl.FRAMEBUFFER, |
| gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo); |
| |
| gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0); |
| |
| wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after buffer init"); |
| shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); |
| |
| return { fbo: buf, color: tex, depthStencil: rbo }; |
| } |
| |
| var quadVB; |
| |
| function drawQuad(depth) { |
| if (!quadVB) { |
| quadVB = gl.createBuffer() |
| } |
| |
| var quadVerts = new Float32Array(3 * 6); |
| quadVerts[0] = -1.0; quadVerts[1] = 1.0; quadVerts[2] = depth; |
| quadVerts[3] = -1.0; quadVerts[4] = -1.0; quadVerts[5] = depth; |
| quadVerts[6] = 1.0; quadVerts[7] = -1.0; quadVerts[8] = depth; |
| quadVerts[9] = -1.0; quadVerts[10] = 1.0; quadVerts[11] = depth; |
| quadVerts[12] = 1.0; quadVerts[13] = -1.0; quadVerts[14] = depth; |
| quadVerts[15] = 1.0; quadVerts[16] = 1.0; quadVerts[17] = depth; |
| |
| gl.bindBuffer(gl.ARRAY_BUFFER, quadVB); |
| gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW); |
| gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, 0); |
| gl.enableVertexAttribArray(0); |
| gl.drawArrays(gl.TRIANGLES, 0, 6); |
| |
| wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawQuad"); |
| } |
| |
| // Test based on dEQP-GLES3.functional.blit.depth_stencil.depth_24_stencil8_stencil_only |
| function test_stencil_only_blit(format) { |
| debug("testing format: " + wtu.glEnumToString(gl, format)) |
| |
| var src = init_buffer(format); |
| var dest = init_buffer(format); |
| |
| gl.bindFramebuffer(gl.FRAMEBUFFER, src.fbo); |
| gl.viewport(0, 0, 16, 16); |
| |
| // Fill source with red, depth = 0.5, stencil = 7 |
| gl.enable(gl.DEPTH_TEST); |
| gl.enable(gl.STENCIL_TEST); |
| gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); |
| gl.stencilFunc(gl.ALWAYS, 7, 0xFF); |
| gl.uniform3f(colorLoc, 1.0, 0.0, 0.0); |
| drawQuad(0.5); |
| |
| // Fill dest with yellow, depth = 0.0, stencil = 1 |
| gl.bindFramebuffer(gl.FRAMEBUFFER, dest.fbo); |
| gl.stencilFunc(gl.ALWAYS, 1, 0xff); |
| gl.uniform3f(colorLoc, 1.0, 1.0, 0.0); |
| drawQuad(0.0); |
| |
| // Perform copy. |
| gl.bindFramebuffer(gl.READ_FRAMEBUFFER, src.fbo); |
| gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dest.fbo); |
| gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.STENCIL_BUFFER_BIT, gl.NEAREST); |
| |
| // Render blue where depth < 0, decrement on depth failure. |
| gl.bindFramebuffer(gl.FRAMEBUFFER, dest.fbo); |
| gl.stencilOp(gl.KEEP, gl.DECR, gl.KEEP); |
| gl.stencilFunc(gl.ALWAYS, 0, 0xff); |
| |
| gl.uniform3f(colorLoc, 0.0, 0.0, 1.0); |
| drawQuad(0.0); |
| |
| // Render green where stencil == 6. |
| gl.disable(gl.DEPTH_TEST); |
| gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); |
| gl.stencilFunc(gl.EQUAL, 6, 0xff); |
| |
| gl.uniform3f(colorLoc, 0.0, 1.0, 0.0); |
| drawQuad(0.0); |
| |
| wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after test"); |
| wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0, 255, 0, 255], |
| "stencil test should be green"); |
| |
| gl.deleteFramebuffer(src.fbo); |
| gl.deleteFramebuffer(dest.fbo); |
| gl.deleteTexture(src.color); |
| gl.deleteTexture(dest.color); |
| gl.deleteRenderbuffer(src.depthStencil); |
| gl.deleteRenderbuffer(dest.depthStencil); |
| } |
| |
| if (!gl) { |
| testFailed("WebGL context does not exist"); |
| } else { |
| testPassed("WebGL context exists"); |
| |
| program = wtu.setupProgram(gl, ["vs", "fs"], ["position"]); |
| wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after program initialization"); |
| shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true'); |
| |
| colorLoc = gl.getUniformLocation(program, "color") |
| wtu.glErrorShouldBe(gl, gl.NO_ERROR, "query uniform location"); |
| shouldBeNonNull('colorLoc') |
| |
| test_stencil_only_blit(gl.DEPTH24_STENCIL8); |
| test_stencil_only_blit(gl.DEPTH32F_STENCIL8); |
| } |
| |
| var successfullyParsed = true; |
| </script> |
| <script src="../../js/js-test-post.js"></script> |
| |
| </body> |
| </html> |