Skip to content

Commit

Permalink
GLSL: Fix Clip/Cull in mesh shaders.
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKristian-Work committed Aug 25, 2023
1 parent 633dc30 commit b76394e
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#version 450
#extension GL_EXT_mesh_shader : require
layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
layout(max_vertices = 32, max_primitives = 30, triangles) out;

out gl_MeshPerVertexEXT
{
vec4 gl_Position;
float gl_ClipDistance[4];
} gl_MeshVerticesEXT[];

layout(location = 2) out vec4 B[32];

void main()
{
SetMeshOutputsEXT(32u, 30u);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.x = 1.0;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.y = 1.0;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.z = 1.0;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position.w = 1.0;
float _40 = float(int((gl_LocalInvocationIndex << 1u) + 4294967295u)) * 0.5;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0u] = _40;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[1u] = _40;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[2u] = _40;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[3u] = _40;
B[gl_LocalInvocationIndex].x = 2.0;
B[gl_LocalInvocationIndex].y = 2.0;
B[gl_LocalInvocationIndex].z = 2.0;
B[gl_LocalInvocationIndex].w = 2.0;
if (gl_LocalInvocationIndex < 30u)
{
gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(gl_LocalInvocationIndex, gl_LocalInvocationIndex + 1u, gl_LocalInvocationIndex + 2u);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
; SPIR-V
; Version: 1.4
; Generator: Unknown(30017); 21022
; Bound: 62
; Schema: 0
OpCapability Shader
OpCapability ClipDistance
OpCapability MeshShadingEXT
OpExtension "SPV_EXT_mesh_shader"
OpMemoryModel Logical GLSL450
OpEntryPoint MeshEXT %main "main" %SV_Position %B %gl_ClipDistance %indices %gl_LocalInvocationIndex
OpExecutionMode %main OutputVertices 32
OpExecutionMode %main OutputPrimitivesNV 30
OpExecutionMode %main OutputTrianglesNV
OpExecutionMode %main LocalSize 32 1 1
OpName %main "main"
OpName %SV_Position "SV_Position"
OpName %B "B"
OpName %indices "indices"
OpDecorate %SV_Position BuiltIn Position
OpDecorate %B Location 2
OpDecorate %gl_ClipDistance BuiltIn ClipDistance
OpDecorate %indices BuiltIn PrimitiveTriangleIndicesEXT
OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex
%void = OpTypeVoid
%2 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
%_ptr_Output__arr_v4float_uint_32 = OpTypePointer Output %_arr_v4float_uint_32
%SV_Position = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
%B = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
%uint_4 = OpConstant %uint 4
%_arr_float_uint_4 = OpTypeArray %float %uint_4
%_arr__arr_float_uint_4_uint_32 = OpTypeArray %_arr_float_uint_4 %uint_32
%_ptr_Output__arr__arr_float_uint_4_uint_32 = OpTypePointer Output %_arr__arr_float_uint_4_uint_32
%gl_ClipDistance = OpVariable %_ptr_Output__arr__arr_float_uint_4_uint_32 Output
%uint_30 = OpConstant %uint 30
%v3uint = OpTypeVector %uint 3
%_arr_v3uint_uint_30 = OpTypeArray %v3uint %uint_30
%_ptr_Output__arr_v3uint_uint_30 = OpTypePointer Output %_arr_v3uint_uint_30
%indices = OpVariable %_ptr_Output__arr_v3uint_uint_30 Output
%_ptr_Input_uint = OpTypePointer Input %uint
%gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input
%_ptr_Output_float = OpTypePointer Output %float
%uint_0 = OpConstant %uint 0
%float_1 = OpConstant %float 1
%uint_1 = OpConstant %uint 1
%uint_2 = OpConstant %uint 2
%uint_3 = OpConstant %uint 3
%uint_4294967295 = OpConstant %uint 4294967295
%float_0_5 = OpConstant %float 0.5
%float_2 = OpConstant %float 2
%bool = OpTypeBool
%_ptr_Output_v3uint = OpTypePointer Output %v3uint
%main = OpFunction %void None %2
%4 = OpLabel
OpBranch %58
%58 = OpLabel
%25 = OpLoad %uint %gl_LocalInvocationIndex
OpSetMeshOutputsEXT %uint_32 %uint_30
%27 = OpAccessChain %_ptr_Output_float %SV_Position %25 %uint_0
OpStore %27 %float_1
%30 = OpAccessChain %_ptr_Output_float %SV_Position %25 %uint_1
OpStore %30 %float_1
%32 = OpAccessChain %_ptr_Output_float %SV_Position %25 %uint_2
OpStore %32 %float_1
%34 = OpAccessChain %_ptr_Output_float %SV_Position %25 %uint_3
OpStore %34 %float_1
%36 = OpShiftLeftLogical %uint %25 %uint_1
%37 = OpIAdd %uint %36 %uint_4294967295
%39 = OpConvertSToF %float %37
%40 = OpFMul %float %39 %float_0_5
%42 = OpAccessChain %_ptr_Output_float %gl_ClipDistance %25 %uint_0
OpStore %42 %40
%43 = OpAccessChain %_ptr_Output_float %gl_ClipDistance %25 %uint_1
OpStore %43 %40
%44 = OpAccessChain %_ptr_Output_float %gl_ClipDistance %25 %uint_2
OpStore %44 %40
%45 = OpAccessChain %_ptr_Output_float %gl_ClipDistance %25 %uint_3
OpStore %45 %40
%46 = OpAccessChain %_ptr_Output_float %B %25 %uint_0
OpStore %46 %float_2
%48 = OpAccessChain %_ptr_Output_float %B %25 %uint_1
OpStore %48 %float_2
%49 = OpAccessChain %_ptr_Output_float %B %25 %uint_2
OpStore %49 %float_2
%50 = OpAccessChain %_ptr_Output_float %B %25 %uint_3
OpStore %50 %float_2
%52 = OpULessThan %bool %25 %uint_30
OpSelectionMerge %60 None
OpBranchConditional %52 %59 %60
%59 = OpLabel
%53 = OpIAdd %uint %25 %uint_1
%54 = OpIAdd %uint %25 %uint_2
%55 = OpCompositeConstruct %v3uint %25 %53 %54
%57 = OpAccessChain %_ptr_Output_v3uint %indices %25
OpStore %57 %55
OpBranch %60
%60 = OpLabel
OpReturn
OpFunctionEnd
16 changes: 12 additions & 4 deletions spirv_glsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3306,11 +3306,13 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo
auto &m = ir.meta[var.self].decoration;
if (m.builtin && builtin_is_per_vertex_set(m.builtin_type))
{
// For mesh/tesc output, Clip/Cull is an array-of-array. Look at innermost array type
// for correct result.
global_builtins.set(m.builtin_type);
if (m.builtin_type == BuiltInCullDistance)
cull_distance_size = to_array_size_literal(type);
cull_distance_size = to_array_size_literal(type, 0);
else if (m.builtin_type == BuiltInClipDistance)
clip_distance_size = to_array_size_literal(type);
clip_distance_size = to_array_size_literal(type, 0);

if (is_block_builtin(m.builtin_type) && m.decoration_flags.get(DecorationXfbStride) &&
m.decoration_flags.get(DecorationXfbBuffer) && m.decoration_flags.get(DecorationOffset))
Expand Down Expand Up @@ -10069,8 +10071,14 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice

switch (builtin)
{
// case BuiltInCullDistance: // These are already arrays, need to figure out rules for these in tess/geom.
// case BuiltInClipDistance:
case BuiltInCullDistance:
case BuiltInClipDistance:
if (type->array.size() == 1) // Red herring. Only consider block IO for two-dimensional arrays here.
{
append_index(index, is_literal);
break;
}
// fallthrough
case BuiltInPosition:
case BuiltInPointSize:
if (mesh_shader)
Expand Down

0 comments on commit b76394e

Please sign in to comment.