Skip to content

Commit

Permalink
GLSL: Implement GL_EXT_mesh_shader.
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKristian-Work committed Sep 2, 2022
1 parent ec7b9b0 commit aa14c36
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 21 deletions.
63 changes: 63 additions & 0 deletions shaders/mesh/mesh-shader-basic-triangle.mesh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#version 450
#extension GL_EXT_mesh_shader : require
layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;
layout(triangles, max_vertices = 24, max_primitives = 22) out;

out gl_MeshPerVertexEXT
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[1];
float gl_CullDistance[2];
} gl_MeshVerticesEXT[];

layout(location = 0) out vec4 vOut[];
layout(location = 1) perprimitiveEXT out vec4 vPrim[];

layout(location = 2) out BlockOut
{
vec4 a;
vec4 b;
} outputs[];

layout(location = 4) perprimitiveEXT out BlockOutPrim
{
vec4 a;
vec4 b;
} prim_outputs[];

shared float shared_float[16];

struct TaskPayload
{
float a;
float b;
int c;
};

taskPayloadSharedEXT TaskPayload payload;

void main()
{
SetMeshOutputsEXT(24, 22);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(gl_GlobalInvocationID, 1.0);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_PointSize = 2.0;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0] = 4.0;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1] = 5.0;
vOut[gl_LocalInvocationIndex] = vec4(gl_GlobalInvocationID, 2.0);
outputs[gl_LocalInvocationIndex].a = vec4(5.0);
outputs[gl_LocalInvocationIndex].b = vec4(6.0);
barrier();
if (gl_LocalInvocationIndex < 22)
{
vPrim[gl_LocalInvocationIndex] = vec4(gl_WorkGroupID, 3.0);
prim_outputs[gl_LocalInvocationIndex].a = vec4(payload.a);
prim_outputs[gl_LocalInvocationIndex].b = vec4(payload.b);
gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0, 1, 2) + gl_LocalInvocationIndex;
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = int(gl_GlobalInvocationID.x);
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = int(gl_GlobalInvocationID.x) + 1;
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_ViewportIndex = int(gl_GlobalInvocationID.x) + 2;
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_CullPrimitiveEXT = bool(gl_GlobalInvocationID.x & 1);
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveShadingRateEXT = int(gl_GlobalInvocationID.x) + 3;
}
}
1 change: 1 addition & 0 deletions spirv_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ struct SPIREntryPoint
} workgroup_size;
uint32_t invocations = 0;
uint32_t output_vertices = 0;
uint32_t output_primitives = 0;
spv::ExecutionModel model = spv::ExecutionModelMax;
bool geometry_passthrough = false;
};
Expand Down
14 changes: 14 additions & 0 deletions spirv_cross.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
case OpEmitVertex:
return false;

// Mesh shader functions modify global state.
case OpSetMeshOutputsEXT:
return false;

// Barriers disallow any reordering, so we should treat blocks with barrier as writing.
case OpControlBarrier:
case OpMemoryBarrier:
Expand Down Expand Up @@ -1069,8 +1073,11 @@ void Compiler::parse_fixup()
{
auto &var = id.get<SPIRVariable>();
if (var.storage == StorageClassPrivate || var.storage == StorageClassWorkgroup ||
var.storage == StorageClassTaskPayloadWorkgroupEXT ||
var.storage == StorageClassOutput)
{
global_variables.push_back(var.self);
}
if (variable_storage_is_aliased(var))
aliased_variables.push_back(var.self);
}
Expand Down Expand Up @@ -2177,6 +2184,10 @@ void Compiler::set_execution_mode(ExecutionMode mode, uint32_t arg0, uint32_t ar
execution.output_vertices = arg0;
break;

case ExecutionModeOutputPrimitivesEXT:
execution.output_primitives = arg0;
break;

default:
break;
}
Expand Down Expand Up @@ -2297,6 +2308,9 @@ uint32_t Compiler::get_execution_mode_argument(spv::ExecutionMode mode, uint32_t
case ExecutionModeOutputVertices:
return execution.output_vertices;

case ExecutionModeOutputPrimitivesEXT:
return execution.output_primitives;

default:
return 0;
}
Expand Down
Loading

0 comments on commit aa14c36

Please sign in to comment.