diff --git a/reference/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store-single.sm65.nofxc.fxconly.spv16.mesh b/reference/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store-single.sm65.nofxc.fxconly.spv16.mesh new file mode 100644 index 000000000..4141c742e --- /dev/null +++ b/reference/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store-single.sm65.nofxc.fxconly.spv16.mesh @@ -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); +} diff --git a/reference/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store.sm65.nofxc.fxconly.spv16.mesh b/reference/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store.sm65.nofxc.fxconly.spv16.mesh index f8be7dc0b..3940ac336 100644 --- a/reference/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store.sm65.nofxc.fxconly.spv16.mesh +++ b/reference/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store.sm65.nofxc.fxconly.spv16.mesh @@ -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]); diff --git a/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store-single.sm65.nofxc.fxconly.spv16.mesh b/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store-single.sm65.nofxc.fxconly.spv16.mesh new file mode 100644 index 000000000..c7305dad3 --- /dev/null +++ b/shaders-hlsl-no-opt/mesh/clip-cull-array-load-store-single.sm65.nofxc.fxconly.spv16.mesh @@ -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); +} diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 8f8916b41..de3708737 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -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(res_type.parent_type))) + is_array(res_type) && !is_array(get(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 += ", "; } @@ -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++) {