Skip to content

Commit

Permalink
Merge pull request #2430 from KhronosGroup/hlsl-mesh-single-clip-cull…
Browse files Browse the repository at this point in the history
…-fix

HLSL: Fix clip/cull lowering for single element.
  • Loading branch information
HansKristian-Work authored Dec 13, 2024
2 parents ebe2aa0 + d1106b0 commit 6173e24
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
static uint gl_LocalInvocationIndex;
struct SPIRV_Cross_Input
{
uint gl_LocalInvocationIndex : SV_GroupIndex;
};

struct gl_MeshPerVertexEXT
{
float gl_ClipDistance[1] : SV_ClipDistance;
};

struct gl_MeshPerPrimitiveEXT
{
};

void write_clip_distance(inout float v[1])
{
v[0] += 1.0f;
}

void mesh_main(out gl_MeshPerVertexEXT gl_MeshVerticesEXT[3])
{
SetMeshOutputCounts(3u, 1u);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0] = 4.0f;
float param[1] = gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance;
write_clip_distance(param);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance = param;
}

[outputtopology("triangle")]
[numthreads(1, 1, 1)]
void main(SPIRV_Cross_Input stage_input, out vertices gl_MeshPerVertexEXT gl_MeshVerticesEXT[3])
{
gl_LocalInvocationIndex = stage_input.gl_LocalInvocationIndex;
mesh_main(gl_MeshVerticesEXT);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void mesh_main(out gl_MeshPerVertexEXT gl_MeshVerticesEXT[3])
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[1] = 4.0f;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[2] = 4.0f;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[3] = 4.0f;
float _62[4] = { gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0], gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[1], gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[2], gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[3] };
float _62[4] = { gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance.x, gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance.y, gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance.z, gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance.w };
float param[4] = _62;
write_clip_distance(param);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance = float4(param[0], param[1], param[2], param[3]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#version 450
#extension GL_EXT_mesh_shader : require
layout(triangles, max_vertices = 3, max_primitives = 1) out;

out gl_MeshPerVertexEXT
{
float gl_ClipDistance[1];
} gl_MeshVerticesEXT[];

void write_clip_distance(inout float v[1])
{
v[0] += 1.0;
}

void main()
{
SetMeshOutputsEXT(3, 1);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0] = 4.0;
write_clip_distance(gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance);
}
12 changes: 10 additions & 2 deletions spirv_hlsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4827,14 +4827,15 @@ void CompilerHLSL::emit_load(const Instruction &instruction)
has_decoration(ptr, DecorationBuiltIn) &&
(get_decoration(ptr, DecorationBuiltIn) == BuiltInClipDistance ||
get_decoration(ptr, DecorationBuiltIn) == BuiltInCullDistance) &&
is_array(res_type) && !is_array(get<SPIRType>(res_type.parent_type)))
is_array(res_type) && !is_array(get<SPIRType>(res_type.parent_type)) &&
to_array_size_literal(res_type) > 1)
{
track_expression_read(ptr);
string load_expr = "{ ";
uint32_t num_elements = to_array_size_literal(res_type);
for (uint32_t i = 0; i < num_elements; i++)
{
load_expr += join(to_expression(ptr), "[", i, "]");
load_expr += join(to_expression(ptr), ".", index_to_swizzle(i));
if (i + 1 < num_elements)
load_expr += ", ";
}
Expand Down Expand Up @@ -6960,6 +6961,13 @@ void CompilerHLSL::cast_to_variable_store(uint32_t target_id, std::string &expr,
if (num_clip > 4)
SPIRV_CROSS_THROW("Number of clip or cull distances exceeds 4, this will not work with mesh shaders.");

if (num_clip == 1)
{
// We already emit array here.
CompilerGLSL::cast_to_variable_store(target_id, expr, expr_type);
return;
}

auto unrolled_expr = join("float", num_clip, "(");
for (uint32_t i = 0; i < num_clip; i++)
{
Expand Down

0 comments on commit 6173e24

Please sign in to comment.