Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-11-02 15:26:45 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-11-02 15:34:11 +0300
commitebf779dcfbeca9f6609fb825cda342621f0c7607 (patch)
treee6ee47b062c673ca494b04ef258e35b764507854
parent94160e88909fe588a06415fb30c8f05fe6e42af0 (diff)
HLSL: Do not support ClipCull size > 4 in mesh shaders.
The array mechanism breaks DXC which needs to observe that all components have been written. Uninitialized outputs will be undefined. Resort to simple vector instead.
-rw-r--r--reference/opt/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh27
-rw-r--r--reference/opt/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh19
-rw-r--r--reference/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh9
-rw-r--r--reference/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh9
-rw-r--r--shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh1
-rw-r--r--shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh1
-rw-r--r--spirv_glsl.cpp11
-rw-r--r--spirv_hlsl.cpp40
8 files changed, 70 insertions, 47 deletions
diff --git a/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh b/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
index 46a166c5..4819b14f 100644
--- a/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
+++ b/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
@@ -34,8 +34,8 @@ struct gl_MeshPerVertexEXT
float4 vOut : TEXCOORD0;
BlockOut outputs : TEXCOORD2;
float4 gl_Position : SV_Position;
- float4 gl_ClipDistance[1] : SV_ClipDistance;
- float4 gl_CullDistance[1] : SV_CullDistance;
+ float gl_ClipDistance[1] : SV_ClipDistance;
+ float2 gl_CullDistance : SV_CullDistance;
};
struct gl_MeshPerPrimitiveEXT
@@ -54,12 +54,13 @@ groupshared float shared_float[16];
void mesh_main(inout gl_MeshPerVertexEXT gl_MeshVerticesEXT[24], inout gl_MeshPerPrimitiveEXT gl_MeshPrimitivesEXT[22], TaskPayload _payload, inout uint2 gl_PrimitiveLineIndicesEXT[22])
{
SetMeshOutputCounts(24u, 22u);
- float3 _171 = float3(gl_GlobalInvocationID);
- float _172 = _171.x;
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = float4(_172, _171.yz, 1.0f);
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0 / 4][0 % 4] = 4.0f;
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1 / 4][1 % 4] = 5.0f;
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].vOut = float4(_172, _171.yz, 2.0f);
+ float3 _173 = float3(gl_GlobalInvocationID);
+ float _174 = _173.x;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = float4(_174, _173.yz, 1.0f);
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0] = 4.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[0] = 6.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1] = 5.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].vOut = float4(_174, _173.yz, 2.0f);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.a = 5.0f.xxxx;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.b = 6.0f.xxxx;
GroupMemoryBarrierWithGroupSync();
@@ -69,12 +70,12 @@ void mesh_main(inout gl_MeshPerVertexEXT gl_MeshVerticesEXT[24], inout gl_MeshPe
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].prim_outputs.a = _payload.a.xxxx;
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].prim_outputs.b = _payload.b.xxxx;
gl_PrimitiveLineIndicesEXT[gl_LocalInvocationIndex] = uint2(0u, 1u) + gl_LocalInvocationIndex.xx;
- int _225 = int(gl_GlobalInvocationID.x);
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = _225;
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = _225 + 1;
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_ViewportIndex = _225 + 2;
+ int _229 = int(gl_GlobalInvocationID.x);
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = _229;
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = _229 + 1;
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_ViewportIndex = _229 + 2;
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_CullPrimitiveEXT = (gl_GlobalInvocationID.x & 1u) != 0u;
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveShadingRateEXT = _225 + 3;
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveShadingRateEXT = _229 + 3;
}
}
diff --git a/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh b/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
index f3e40fd8..7436c463 100644
--- a/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
+++ b/reference/opt/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
@@ -34,8 +34,8 @@ struct gl_MeshPerVertexEXT
float4 vOut : TEXCOORD0;
BlockOut outputs : TEXCOORD2;
float4 gl_Position : SV_Position;
- float4 gl_ClipDistance[1] : SV_ClipDistance;
- float4 gl_CullDistance[1] : SV_CullDistance;
+ float gl_ClipDistance[1] : SV_ClipDistance;
+ float2 gl_CullDistance : SV_CullDistance;
};
struct gl_MeshPerPrimitiveEXT
@@ -57,8 +57,9 @@ void mesh_main(inout gl_MeshPerVertexEXT gl_MeshVerticesEXT[24], inout gl_MeshPe
float3 _29 = float3(gl_GlobalInvocationID);
float _31 = _29.x;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = float4(_31, _29.yz, 1.0f);
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0 / 4][0 % 4] = 4.0f;
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1 / 4][1 % 4] = 5.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0] = 4.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[0] = 3.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1] = 5.0f;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].vOut = float4(_31, _29.yz, 2.0f);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.a = 5.0f.xxxx;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.b = 6.0f.xxxx;
@@ -69,12 +70,12 @@ void mesh_main(inout gl_MeshPerVertexEXT gl_MeshVerticesEXT[24], inout gl_MeshPe
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].prim_outputs.a = _payload.a.xxxx;
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].prim_outputs.b = _payload.b.xxxx;
gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uint3(0u, 1u, 2u) + gl_LocalInvocationIndex.xxx;
- int _125 = int(gl_GlobalInvocationID.x);
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = _125;
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = _125 + 1;
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_ViewportIndex = _125 + 2;
+ int _127 = int(gl_GlobalInvocationID.x);
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveID = _127;
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_Layer = _127 + 1;
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_ViewportIndex = _127 + 2;
gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_CullPrimitiveEXT = (gl_GlobalInvocationID.x & 1u) != 0u;
- gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveShadingRateEXT = _125 + 3;
+ gl_MeshPrimitivesEXT[gl_LocalInvocationIndex].gl_PrimitiveShadingRateEXT = _127 + 3;
}
}
diff --git a/reference/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh b/reference/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
index 1609cd5d..dad35928 100644
--- a/reference/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
+++ b/reference/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
@@ -34,8 +34,8 @@ struct gl_MeshPerVertexEXT
float4 vOut : TEXCOORD0;
BlockOut outputs : TEXCOORD2;
float4 gl_Position : SV_Position;
- float4 gl_ClipDistance[1] : SV_ClipDistance;
- float4 gl_CullDistance[1] : SV_CullDistance;
+ float gl_ClipDistance[1] : SV_ClipDistance;
+ float2 gl_CullDistance : SV_CullDistance;
};
struct gl_MeshPerPrimitiveEXT
@@ -65,8 +65,9 @@ void main2(inout gl_MeshPerVertexEXT gl_MeshVerticesEXT[24], inout gl_MeshPerPri
{
SetMeshOutputCounts(24u, 22u);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = float4(float3(gl_GlobalInvocationID), 1.0f);
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0 / 4][0 % 4] = 4.0f;
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1 / 4][1 % 4] = 5.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0] = 4.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[0] = 6.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1] = 5.0f;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].vOut = float4(float3(gl_GlobalInvocationID), 2.0f);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.a = 5.0f.xxxx;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.b = 6.0f.xxxx;
diff --git a/reference/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh b/reference/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
index 0249cda0..e636453d 100644
--- a/reference/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
+++ b/reference/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
@@ -34,8 +34,8 @@ struct gl_MeshPerVertexEXT
float4 vOut : TEXCOORD0;
BlockOut outputs : TEXCOORD2;
float4 gl_Position : SV_Position;
- float4 gl_ClipDistance[1] : SV_ClipDistance;
- float4 gl_CullDistance[1] : SV_CullDistance;
+ float gl_ClipDistance[1] : SV_ClipDistance;
+ float2 gl_CullDistance : SV_CullDistance;
};
struct gl_MeshPerPrimitiveEXT
@@ -55,8 +55,9 @@ void mesh_main(inout gl_MeshPerVertexEXT gl_MeshVerticesEXT[24], inout gl_MeshPe
{
SetMeshOutputCounts(24u, 22u);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = float4(float3(gl_GlobalInvocationID), 1.0f);
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0 / 4][0 % 4] = 4.0f;
- gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1 / 4][1 % 4] = 5.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_ClipDistance[0] = 4.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[0] = 3.0f;
+ gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_CullDistance[1] = 5.0f;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].vOut = float4(float3(gl_GlobalInvocationID), 2.0f);
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.a = 5.0f.xxxx;
gl_MeshVerticesEXT[gl_LocalInvocationIndex].outputs.b = 6.0f.xxxx;
diff --git a/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh b/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
index 70aac964..4f9500fe 100644
--- a/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
+++ b/shaders-hlsl/mesh/mesh-shader-basic-lines.spv14.vk.nocompat.mesh
@@ -53,6 +53,7 @@ void main2()
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[0] = 6.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);
diff --git a/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh b/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
index c981a26e..4d8e3f64 100644
--- a/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
+++ b/shaders-hlsl/mesh/mesh-shader-basic-triangle.spv14.vk.nocompat.mesh
@@ -43,6 +43,7 @@ void main()
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[0] = 3.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);
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index ce95729c..31af3b2d 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -9214,7 +9214,6 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
bool relaxed_precision = has_decoration(base, DecorationRelaxedPrecision);
bool pending_array_enclose = false;
bool dimension_flatten = false;
- bool clip_cull_fixup = false;
const auto append_index = [&](uint32_t index, bool is_literal, bool is_ptr_chain = false) {
AccessChainFlags mod_flags = flags;
@@ -9377,14 +9376,6 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
if (!pending_array_enclose)
expr += "]";
}
- else if (clip_cull_fixup)
- {
- string idx_expr = is_literal ? convert_to_string(index) : to_enclosed_unpacked_expression(index, register_expression_read);
-
- expr += "[" + idx_expr + " / 4]";
- expr += "[" + idx_expr + " % 4]";
- clip_cull_fixup = false;
- }
// Some builtins are arrays in SPIR-V but not in other languages, e.g. gl_SampleMask[] is an array in SPIR-V but not in Metal.
// By throwing away the index, we imply the index was 0, which it must be for gl_SampleMask.
else if (!builtin_translates_to_nonarray(BuiltIn(get_decoration(base, DecorationBuiltIn))))
@@ -9444,8 +9435,6 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
else
physical_type = 0;
- clip_cull_fixup = (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance) && backend.force_merged_mesh_block;
-
row_major_matrix_needs_conversion = member_is_non_native_row_major_matrix(*type, index);
type = &get<SPIRType>(type->member_types[index]);
}
diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp
index 86dcbd1c..f06fb47e 100644
--- a/spirv_hlsl.cpp
+++ b/spirv_hlsl.cpp
@@ -603,11 +603,25 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
break;
case BuiltInClipDistance:
+ {
+ static const char *types[] = { "float", "float2", "float3", "float4" };
+
// HLSL is a bit weird here, use SV_ClipDistance0, SV_ClipDistance1 and so on with vectors.
if (execution.model == ExecutionModelMeshEXT)
{
- uint32_t clip = (clip_distance_count + 3) / 4;
- statement("float4 gl_ClipDistance", "[", clip,"] : SV_ClipDistance;");
+ if (clip_distance_count > 4)
+ SPIRV_CROSS_THROW("Clip distance count > 4 not supported for mesh shaders.");
+
+ if (clip_distance_count == 1)
+ {
+ // Avoids having to hack up access_chain code. Makes it trivially indexable.
+ statement("float gl_ClipDistance[1] : SV_ClipDistance;");
+ }
+ else
+ {
+ // Replace array with vector directly, avoids any weird fixup path.
+ statement(types[clip_distance_count - 1], " gl_ClipDistance : SV_ClipDistance;");
+ }
}
else
{
@@ -619,19 +633,33 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
uint32_t semantic_index = clip / 4;
- static const char *types[] = { "float", "float2", "float3", "float4" };
statement(types[to_declare - 1], " ", builtin_to_glsl(builtin, StorageClassOutput), semantic_index,
" : SV_ClipDistance", semantic_index, ";");
}
}
break;
+ }
case BuiltInCullDistance:
+ {
+ static const char *types[] = { "float", "float2", "float3", "float4" };
+
// HLSL is a bit weird here, use SV_CullDistance0, SV_CullDistance1 and so on with vectors.
if (execution.model == ExecutionModelMeshEXT)
{
- uint32_t cull = (cull_distance_count + 3) / 4;
- statement("float4 gl_CullDistance", "[", cull,"] : SV_CullDistance;");
+ if (cull_distance_count > 4)
+ SPIRV_CROSS_THROW("Cull distance count > 4 not supported for mesh shaders.");
+
+ if (cull_distance_count == 1)
+ {
+ // Avoids having to hack up access_chain code. Makes it trivially indexable.
+ statement("float gl_CullDistance[1] : SV_CullDistance;");
+ }
+ else
+ {
+ // Replace array with vector directly, avoids any weird fixup path.
+ statement(types[cull_distance_count - 1], " gl_CullDistance : SV_CullDistance;");
+ }
}
else
{
@@ -643,12 +671,12 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
uint32_t semantic_index = cull / 4;
- static const char *types[] = { "float", "float2", "float3", "float4" };
statement(types[to_declare - 1], " ", builtin_to_glsl(builtin, StorageClassOutput), semantic_index,
" : SV_CullDistance", semantic_index, ";");
}
}
break;
+ }
case BuiltInPointSize:
// If point_size_compat is enabled, just ignore PointSize.