#version 460
#extension GL_ARB_separate_shader_objects   : enable
#extension GL_NV_mesh_shader                : require

layout(local_size_x=30) in;

layout(triangles) out;
layout(max_vertices=30, max_primitives=10) out;

layout( push_constant ) uniform constants{
    mat4 mvp;
};

layout(location = 0) out vec3 passNormal[];
layout(location = 1) out uint passTaskIndex[];

struct Vertex
{
    vec3 position;  float padding0;
    vec3 normal;    float padding1;
};

layout(std430, binding = 0) readonly buffer vertexBuffer
{
    Vertex vertices[];
};

layout(std430, binding = 1) readonly buffer indexBuffer
{
    uint indices[]; // breaks for 16 bit indices
};

taskNV in Task {
  uint baseID;
} IN;

void main()	{
    
    uint workIndex                      = gl_LocalInvocationID.x;      
    gl_PrimitiveIndicesNV[workIndex]    = workIndex;
    
    const uint verticesPerMeshTask  = 30;
    uint previousMeshGroupCount     = IN.baseID;
    uint indexBufferIndex           = previousMeshGroupCount * verticesPerMeshTask + workIndex;
    uint index                      = indices[indexBufferIndex];
    
    vec3 inPos      = vertices[index].position;
    vec3 inNormal   = vertices[index].normal;
    
    gl_MeshVerticesNV[workIndex].gl_Position    = mvp * vec4(inPos, 1);
    passNormal[workIndex]                       = inNormal;
    passTaskIndex[workIndex]                    = previousMeshGroupCount;
    
    if(gl_LocalInvocationID.x == 0){
        gl_PrimitiveCountNV = 10;
    }
}