<!--
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 CopyTexSubImage 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>
</head>
<body>
<div id="description"></div>
<canvas id="canvas" width="64px" height="32px"> </canvas>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">#version 300 es
in highp vec4 a_position;
in highp vec2 a_coord;
out highp vec2 v_coord;
void main(void) {
    gl_Position = a_position;
    v_coord = a_coord;
}
</script>
<script id="fshader_luminance_alpha" type="x-shader/x-fragment">#version 300 es
in highp vec2 v_coord;
uniform highp sampler3D u_sampler0;
out highp vec4 o_color0;
void main (void) {
    o_color0 = vec4(texture(u_sampler0,vec3(v_coord, 0)));
}
</script>
<script>
"use strict";
description("This test verifies the behavior of copTexSubImage3D with luminance textures.");
debug("");

var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas, null, 2);

function copytexsubimage3D_luma_format() {

    var testGroup = [
        {
            name: '3d_alpha',
            format: gl.ALPHA,
            width: 64,
            height: 32,
            depth: 2
        },
        {
            name: '3d_luminance',
            format: gl.LUMINANCE,
            width: 64,
            height: 32,
            depth: 2
        },
        {
            name: '3d_luminance_alpha',
            format: gl.LUMINANCE_ALPHA,
            width: 64,
            height: 32,
            depth: 2
        }
    ];

    testGroup.forEach(function(testcase) {
        debug("");
        debug("Testing copytexsubimage3d_luma_format_" + testcase.name);

        var texture = [];
        texture[0] = gl.createTexture();
        texture[1] = gl.createTexture();
        var layer = 0;
        var width = testcase.width;
        var height = testcase.height;
        var depth = testcase.depth;
        var msg;
        var uint1 = new Uint8Array(width * height * 4);
        for (var i = 0; i < uint1.length - 1; ++i) {
            uint1[i + 1] = (uint1[i] + 10) % 255;
        }

        gl.bindTexture(gl.TEXTURE_2D, texture[0]);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint1);
        var fbo = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);

        if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
            gl.bindTexture(gl.TEXTURE_3D, texture[1]);
            setUpTexStatus();
            gl.texImage3D(gl.TEXTURE_3D, 0, testcase.format, width, height, depth, 0, testcase.format, gl.UNSIGNED_BYTE, null);
            gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer, 0, 0,width, height);
            gl.bindFramebuffer(gl.FRAMEBUFFER, null);

            var program = wtu.setupProgram(gl, ["vshader", "fshader_luminance_alpha"], ["a_position", "a_coord"]);
            wtu.setupUnitQuad(gl, 0, 1);
            wtu.drawUnitQuad(gl);

            for (var y = 0; y < height; ++y) {
                for (var x = 0; x < width; ++x) {
                    var cur = y * width * 4 + x * 4;
                    if (testcase.format == gl.ALPHA) {
                        wtu.checkCanvasRect(gl, x, y, 1, 1, [ 0, 0,
                        0, uint1[cur + 3]], msg, [1, 1, 1, 1]);
                    } else if (testcase.format == gl.LUMINANCE) {
                        wtu.checkCanvasRect(gl, x, y, 1, 1, [uint1[cur], uint1[cur],
                        uint1[cur], 255], msg, [1, 1, 1, 1]);
                    } else { // gl.LUMINANCE_ALPHA
                        wtu.checkCanvasRect(gl, x, y, 1, 1, [uint1[cur], uint1[cur],
                        uint1[cur], uint1[cur + 3]], msg, [1, 1, 1, 1]);
                    }
                }
            }
        } else {
            testFailed("framebuffer not complete");
        }

        gl.bindTexture(gl.TEXTURE_3D, null);
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        gl.deleteFramebuffer(fbo);
        gl.deleteTexture(texture[0]);
        gl.deleteTexture(texture[1]);
        gl.deleteProgram(program);
    });
}

function setUpTexStatus() {
    gl.texParameteri(
        gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
    );
    gl.texParameteri(
        gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
    );
    gl.texParameteri(
        gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE
    );
    gl.texParameteri(
        gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE
    );
    gl.texParameteri(
        gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE
    );
}

if (!gl) {
    testFailed("WebGL context does not exist");
} else {
    testPassed("WebGL context exists");
    copytexsubimage3D_luma_format();
}

debug("");
var successfullyParsed = true;
</script>
<script src="../../../js/js-test-post.js"></script>

</body>
</html>
