//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ConvertIndex.comp: Convert UINT_8 indices into UINT_16 using a compute shader.
//
// The following defines tweak the functionality, and a different shader is built based on these.
//
//  - Flags:
//    * IsPrimitiveRestartEnabled: enables conversion from 0xFF to 0xFFFF,
//                                 the restart indices for 8-bit and 16-bit indices.
//    * IsIndirect: Use indirect buffer for index info
//

#version 450 core

layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;

layout (set = 0, binding = 0) buffer dst
{
    // Shader invocations output one packed 32-bit value with up to two 16-bit indices.
    uint dstData[];
};

layout (set = 0, binding = 1) readonly buffer src
{
    // Shader invocations read at most 16 bits of one packed 32-bit value. (Two 8-bit indices.)
    uint srcData[];
};

#if IsIndirect
layout (set = 0, binding = 2) readonly buffer cmd
{
    // Shader invocations read from the cmdData buffer to determine what indices to convert
    // The command data starts at offset cmdOffsetDiv4 of the cmdData buffer.
    uint cmdData[];
};

layout (push_constant) uniform PushConstants
{
    // Read offset in bytes into the cmdData array, divided by four.
    uint cmdOffsetDiv4;
    // Write offset in bytes into the dstData array, divided by four.
    uint dstOffsetDiv4;
    // Maximum size of the read buffer. The highest index value we will convert.
    uint maxIndex;
    // Not used in the shader. Kept to pad "PushConstants" to the size of a vec4.
    uint _padding;
};

#else

layout (push_constant) uniform PushConstants
{
    // Read offset in bytes into the srcData array.
    uint srcOffset;
    // Write offset in bytes into the dstData array, divided by four.
    uint dstOffsetDiv4;
    // Maximum size of the read buffer. The highest index value we will convert.
    uint maxIndex;
    // Not used in the shader. Kept to pad "PushConstants" to the size of a vec4.
    uint _padding;
};
#endif

uint PullIndex(uint index)
{
#if IsIndirect
    uint srcIndex = index;
#else
    uint srcIndex = index + srcOffset;
#endif
    uint srcBlock = srcData[srcIndex >> 2];
    uint srcComponent = (srcIndex & 3);

    uint value = (srcBlock >> (srcComponent << 3)) & 0xFF;
#if IsPrimitiveRestartEnabled
    // convert 0xFF (restart value for 8-bit indices)
    // to 0xFFFF (restart value for 16-bit indices).
    if (value == 0xFF)
        value = 0xFFFF;
#endif
    return value;
}

void PackIndexValue(uint srcValue, uint indexIndex, inout uint dstValue)
{
    // Pack 16-byte index into the 32-byte destination.
    dstValue |= srcValue << (indexIndex << 4);
}

void main()
{
#if IsIndirect
    uint indexCount = cmdData[cmdOffsetDiv4];
    uint firstIndex = cmdData[cmdOffsetDiv4 + 2];
    uint endIndex = firstIndex + indexCount;
#else
    uint firstIndex = 0;
    uint endIndex = firstIndex + maxIndex;
#endif

    // The element index is invocation ID times two plus
    // the firstIndex / 2.
    // This way the first indexCount/2 invocations will transform
    // the data and any additional invocations will be a no-op
    uint index = ((gl_GlobalInvocationID.x + (firstIndex >> 1)) << 1);

    // Don't write anything to dest if we're entirely past the end of the buffer.
    // We assume buffer size is uint-aligned.
    if (index >= endIndex)
        return;

    uint dstValue = 0;

    // Skip packing the first index if we're before the first element.
    if (index >= firstIndex)
    {
        uint srcValue = PullIndex(index);
        PackIndexValue(srcValue, 0, dstValue);
    }

    // Skip packing the second index if we're after the last element.
    if (index + 1 < endIndex)
    {
        uint srcValue = PullIndex(index + 1);
        PackIndexValue(srcValue, 1, dstValue);
    }

    dstData[dstOffsetDiv4 + gl_GlobalInvocationID.x] = dstValue;
}
