<!DOCTYPE html>
<html>
<meta charset=utf-8>
<title>Test the WHLSL test harness.</title>
<script src="whlsl/js/test-harness.js"></script>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
const epsilon = 0.0001;

const numericScalarTypes = ["int", "uchar", "uint", "float"];

const numericScalarFuncs = {
    "int": callIntFunction,
    "uchar": callUcharFunction,
    "uint": callUintFunction,
    "float": callFloatFunction
};

const scalarArgMakers = {
    "int": makeInt,
    "uchar": makeUchar,
    "uint": makeUint,
    "float": makeFloat
};

let mslTests = {};

mslTests.literals = () => {
    checkBools("Return a literal of type bool.", "return true;");
    checkFloat4s("return float4(0, 1, 2, 3);");
    checkNumericScalars("return 42;", [], 42);
};

mslTests.singleArgument = () => {
    checkBools("Upload and return a bool value.", "return in0;", [true]);
    checkFloat4s("return in0.wzyx;", [[3, 2, 1, 0]]);
    checkNumericScalars("return in0;", [42], 42);
};

mslTests.manyArguments = () => {
    checkBools("Upload many bool values and return a calculated result.",
        "return in0 & in1 & in2 & in3 & in4 & in5 & in6 & in7;",  
        [true, true, true, true, true, true, true, true]);

    const body = `return in0 + in1 + in2 + in3 + in4 + in5 + in6 + in7;`;
    let args = [];
    for (let i = 0; i < 8; ++i)
        args.push([0, 1, 2, 3]);
    checkFloat4s(body, args, [0, 8, 16, 24]);
    checkNumericScalars(body, [0, 1, 2, 3, 4, 5, 6, 7], 28);
};

mslTests.buffersWithOneValue = () => {
    const body = `return in0[0];`
    checkBools("Access and return a single bool through a bool*.", body, [[true]]);
    checkFloat4s(body, [[[0, 1, 2, 3]]]);
    checkNumericScalars(body, [[42]], 42);
};

mslTests.multipleBufferArguments = () => {
    checkBools("Access multiple bools through various buffers and return a bool.", 
        "return in0[0] & in0[1] & in0[2] & in1 & in2[0];", 
        [[true, true, true], true, [true]]);
    
    const body = `return in0[0] + in0[1] + in0[2] + in1 + in2[0];`;
    const vector = [0, 1, 2, 3];
    checkFloat4s(body, [[vector, vector, vector], vector, [vector]], [0, 5, 10, 15]);
    checkNumericScalars(body, [[0, 1, 2], 3, [4]], 10);
};

mslTests.multipleArgumentTypes = () => {
    const src = `float test(int i, uchar c, device uint* u, bool b, device bool* bs, float4 f4, device float* fs)
    {
        if (b && bs[0] && bs[1])
            return i + c + u[0] + f4.x + f4.y + f4.z + f4.w + fs[0] + fs[1];
        
        return 0;
    }`;
    const i = makeInt(1);
    const c = makeUchar(2);
    const u = makeUint([3]);
    const b = makeBool(true);
    const bs = makeBool([true, true]);
    const f4 = makeFloat4([4, 5, 6, 7]);
    const fs = makeFloat([8, 9]);
    webGPUPromiseTest(() => {
        return callFloatFunction(src, "test", [i, c, u, b, bs, f4, fs]).then(result => {
            assert_approx_equals(result, 45, epsilon, "Test returned expected value.");
        });
    }, "Upload and calculate a result from varied argument types.");
};

mslTests.bufferStores = () => {
    let src = `void test(device float4* out) {
        *out = float4(0, 1, 2, 3);
    }`;
    const float4Out = makeFloat4([[0, 0, 0, 0]]);
    callVoidFunction(src, "test", float4Out);

    webGPUPromiseTest(() => {
        return float4Out.getArrayBuffer().then(arrayBuffer => {
            const result = new Float32Array(arrayBuffer);
            for (let i; i < 4; ++i) {
                assert_approx_equals(result[i], i, "Test stored expected values.");
            }
        });
    }, "Store into a float4*.");

    src = `void test(device uchar* in, device uchar* out) {
        for (uint i = 0; i < 5; ++i)
            out[i] = in[i];
    }`;
    const array = [0, 1, 2, 3, 4];
    const input = makeUchar(array);
    const output = makeUchar([0, 0, 0, 0, 0]);
    callVoidFunction(src, "test", [input, output]);

    webGPUPromiseTest(() => {
        return output.getArrayBuffer().then(arrayBuffer => {
            const result = new Uint8Array(arrayBuffer);
            assert_array_equals(array, result, "Test stored expected values.");
        });
    }, "Upload a uchar* and store into a uchar*.");
};

window.addEventListener("load", () => {
    harness.isWHLSL = false;
    for (const name in mslTests) {
        mslTests[name]();
    }
});

/* Helper functions */

const checkNumericScalars = (body, argValues, expected) => {
    let functions = [];
    let src = "";
    for (let type of numericScalarTypes) {
        const name = `${type}Test`;

        let inputArgs = [];
        let values = [];
        for (let i = 0; i < argValues.length; ++i) {
            const isPointer = Array.isArray(argValues[i]);
            inputArgs.push(`${isPointer ? "device " : ""}${type}${isPointer ? "*" : ""} in${i}`);
            values.push(scalarArgMakers[type](argValues[i]));
        }
        
        src += `${type} ${name}(${inputArgs.join(", ")}) { ${body} }
        `;
        functions.push({ type: type, name: name, args: values, expected: expected });
    }

    for (const f of functions) {
        const callFunc = numericScalarFuncs[f.type];
        webGPUPromiseTest(async () => {
            return callFunc(src, f.name, f.args).then(result => {
                assert_approx_equals(result, f.expected, epsilon, "Test returned expected value.");
            });
        }, `Return an expected ${f.type} value.`);
    }
};

const checkBools = (msg = "Return an expected bool value.", body, argValues = [], expected = true) => {
    let src = "";
    let inputArgs = [];
    let values = [];
    for (let i = 0; i < argValues.length; ++i) {
        const isPointer = Array.isArray(argValues[i]);
        inputArgs.push(`${isPointer ? "device " : ""}bool${isPointer ? "*" : ""} in${i}`);
        values.push(makeBool(argValues[i]));
    }

    src += `bool boolTest(${inputArgs.join(", ")}) { ${body} }
    `;

    webGPUPromiseTest(async () => {
        return callBoolFunction(src, "boolTest", values).then(result => {
            assert_equals(result, expected, "Test returned expected value.");
        });
    }, msg);
};

const checkFloat4s = (body, argValues = [], expected = [0, 1, 2, 3]) => {
    let src = "";
    let inputArgs = [];
    let values = [];

    for (let i = 0; i < argValues.length; ++i) {
        // Support arrays of float4, including one with a single float4.
        const totalLength = argValues[i].flat().length;
        const isPointer = argValues[i].length === 1 || totalLength > 4;
        inputArgs.push(`${isPointer ? "device " : ""}float4${isPointer ? "*" : ""} in${i}`);
        values.push(makeFloat4(argValues[i]));
    }

    src += `float4 float4Test(${inputArgs.join(", ")}) { ${body} }
    `;

    webGPUPromiseTest(async () => {
        return callFloat4Function(src, "float4Test", values).then(result => {
            for (let i = 0; i < 4; ++i)
                assert_approx_equals(result[i], expected[i], epsilon, "Test returned expected value.");
        });
    }, "Return an expected float4 value.");
}
</script>
</html>
