Skip to content

Commit

Permalink
MSL: Improve handling of sample masks.
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKristian-Work committed Oct 23, 2023
1 parent 56bdcfa commit 2fba284
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct main0_out
[[ early_fragment_tests ]] fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask, post_depth_coverage]])
{
main0_out out = {};
out.FragColor = float4(float(gl_SampleMaskIn));
out.FragColor = float4(float(int(gl_SampleMaskIn)));
return out;
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct main0_out
[[ early_fragment_tests ]] fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask, post_depth_coverage]])
{
main0_out out = {};
out.FragColor = float4(float(gl_SampleMaskIn));
out.FragColor = float4(float(int(gl_SampleMaskIn)));
return out;
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask]], uint gl_SampleID
{
main0_out out = {};
out.FragColor = float4(1.0);
out.gl_SampleMask = (gl_SampleMaskIn & 0x22 & (1 << gl_SampleID));
out.gl_SampleMask = int((gl_SampleMaskIn & 0x22 & (1 << gl_SampleID)));
out.gl_SampleMask &= 0x22;
return out;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask]])
{
main0_out out = {};
out.FragColor = float4(1.0);
out.gl_SampleMask = (gl_SampleMaskIn & 0x22);
out.gl_SampleMask = int((gl_SampleMaskIn & 0x22));
out.gl_SampleMask &= 0x22;
return out;
}
Expand Down
45 changes: 43 additions & 2 deletions reference/opt/shaders-ue4/asm/frag/sample-mask-not-array.asm.frag
Original file line number Diff line number Diff line change
@@ -1,8 +1,49 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wmissing-braces"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

template<typename T, size_t Num>
struct spvUnsafeArray
{
T elements[Num ? Num : 1];

thread T& operator [] (size_t pos) thread
{
return elements[pos];
}
constexpr const thread T& operator [] (size_t pos) const thread
{
return elements[pos];
}

device T& operator [] (size_t pos) device
{
return elements[pos];
}
constexpr const device T& operator [] (size_t pos) const device
{
return elements[pos];
}

constexpr const constant T& operator [] (size_t pos) const constant
{
return elements[pos];
}

threadgroup T& operator [] (size_t pos) threadgroup
{
return elements[pos];
}
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
{
return elements[pos];
}
};

struct type_View
{
float4x4 View_TranslatedWorldToClip;
Expand Down Expand Up @@ -489,12 +530,12 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_View& View [[bu
if (View.View_NumSceneColorMSAASamples > 1)
{
_268 = _255 * float4(float(View.View_NumSceneColorMSAASamples) * 0.25);
_269 = gl_SampleMaskIn & 15u;
_269 = (spvUnsafeArray<uint, 1>({ uint(gl_SampleMaskIn) }))[0] & 15u;
}
else
{
_268 = _255;
_269 = gl_SampleMaskIn;
_269 = (spvUnsafeArray<uint, 1>({ uint(gl_SampleMaskIn) }))[0];
}
out.out_var_SV_Target0 = _268;
out.gl_SampleMask = _269;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ struct main0_out
fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask]])
{
main0_out out = {};
spvUnsafeArray<uint, 1> copy_sample_mask = gl_SampleMaskIn;
out.gl_SampleMask = copy_sample_mask;
spvUnsafeArray<uint, 1> copy_sample_mask = spvUnsafeArray<uint, 1>({ uint(gl_SampleMaskIn) });
out.gl_SampleMask = copy_sample_mask[0];
return out;
}

Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ struct main0_out
fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask]])
{
main0_out out = {};
spvUnsafeArray<int, 1> copy_sample_mask = gl_SampleMaskIn;
out.gl_SampleMask = copy_sample_mask;
spvUnsafeArray<int, 1> copy_sample_mask = spvUnsafeArray<int, 1>({ int(gl_SampleMaskIn) });
out.gl_SampleMask = copy_sample_mask[0];
return out;
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct main0_out
[[ early_fragment_tests ]] fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask, post_depth_coverage]])
{
main0_out out = {};
out.FragColor = float4(float(gl_SampleMaskIn));
out.FragColor = float4(float(int(gl_SampleMaskIn)));
return out;
}

2 changes: 1 addition & 1 deletion reference/shaders-msl/frag/post-depth-coverage.msl23.frag
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct main0_out
[[ early_fragment_tests ]] fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask, post_depth_coverage]])
{
main0_out out = {};
out.FragColor = float4(float(gl_SampleMaskIn));
out.FragColor = float4(float(int(gl_SampleMaskIn)));
return out;
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask]], uint gl_SampleID
{
main0_out out = {};
out.FragColor = float4(1.0);
out.gl_SampleMask = (gl_SampleMaskIn & 0x22 & (1 << gl_SampleID));
out.gl_SampleMask = int((gl_SampleMaskIn & 0x22 & (1 << gl_SampleID)));
out.gl_SampleMask &= 0x22;
return out;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask]])
{
main0_out out = {};
out.FragColor = float4(1.0);
out.gl_SampleMask = (gl_SampleMaskIn & 0x22);
out.gl_SampleMask = int((gl_SampleMaskIn & 0x22));
out.gl_SampleMask &= 0x22;
return out;
}
Expand Down
45 changes: 43 additions & 2 deletions reference/shaders-ue4/asm/frag/sample-mask-not-array.asm.frag
Original file line number Diff line number Diff line change
@@ -1,8 +1,49 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wmissing-braces"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

template<typename T, size_t Num>
struct spvUnsafeArray
{
T elements[Num ? Num : 1];

thread T& operator [] (size_t pos) thread
{
return elements[pos];
}
constexpr const thread T& operator [] (size_t pos) const thread
{
return elements[pos];
}

device T& operator [] (size_t pos) device
{
return elements[pos];
}
constexpr const device T& operator [] (size_t pos) const device
{
return elements[pos];
}

constexpr const constant T& operator [] (size_t pos) const constant
{
return elements[pos];
}

threadgroup T& operator [] (size_t pos) threadgroup
{
return elements[pos];
}
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
{
return elements[pos];
}
};

struct type_View
{
float4x4 View_TranslatedWorldToClip;
Expand Down Expand Up @@ -489,12 +530,12 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_View& View [[bu
if (View.View_NumSceneColorMSAASamples > 1)
{
_268 = _255 * float4(float(View.View_NumSceneColorMSAASamples) * 0.25);
_269 = gl_SampleMaskIn & 15u;
_269 = (spvUnsafeArray<uint, 1>({ uint(gl_SampleMaskIn) }))[0] & 15u;
}
else
{
_268 = _255;
_269 = gl_SampleMaskIn;
_269 = (spvUnsafeArray<uint, 1>({ uint(gl_SampleMaskIn) }))[0];
}
out.out_var_SV_Target0 = _268;
out.gl_SampleMask = _269;
Expand Down
7 changes: 4 additions & 3 deletions spirv_glsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10158,10 +10158,11 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
if (!pending_array_enclose)
expr += "]";
}
// 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))))
else if (index_is_literal || !builtin_translates_to_nonarray(BuiltIn(get_decoration(base, DecorationBuiltIn))))
{
// 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.
// For literal indices we are working on composites, so we ignore this since we have already converted to proper array.
append_index(index, is_literal);
}

Expand Down
26 changes: 22 additions & 4 deletions spirv_msl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4911,9 +4911,18 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp

bool transpose = lhs_e && lhs_e->need_transpose;

// No physical type remapping, and no packed type, so can just emit a store directly.
if (!lhs_remapped_type && !lhs_packed_type)
if (has_decoration(lhs_expression, DecorationBuiltIn) &&
BuiltIn(get_decoration(lhs_expression, DecorationBuiltIn)) == BuiltInSampleMask &&
type_is_top_level_array(type))
{
// Storing an array to SampleMask, have to remove the array-ness before storing.
statement(to_expression(lhs_expression), " = ", to_enclosed_unpacked_expression(rhs_expression), "[0];");
register_write(lhs_expression);
}
else if (!lhs_remapped_type && !lhs_packed_type)
{
// No physical type remapping, and no packed type, so can just emit a store directly.

// We might not be dealing with remapped physical types or packed types,
// but we might be doing a clean store to a row-major matrix.
// In this case, we just flip transpose states, and emit the store, a transpose must be in the RHS expression, if any.
Expand Down Expand Up @@ -17178,6 +17187,7 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr,
case BuiltInInstanceIndex:
case BuiltInBaseInstance:
case BuiltInBaseVertex:
case BuiltInSampleMask:
expected_type = SPIRType::UInt;
expected_width = 32;
break;
Expand All @@ -17195,9 +17205,17 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr,
break;
}

if (expected_type != expr_type.basetype)
if (type_is_top_level_array(expr_type) && builtin == BuiltInSampleMask)
{
// Needs special handling.
auto wrap_expr = join(type_to_glsl(expr_type), "({ ");
wrap_expr += join(type_to_glsl(get<SPIRType>(expr_type.parent_type)), "(", expr, ")");
wrap_expr += " })";
expr = std::move(wrap_expr);
}
else if (expected_type != expr_type.basetype)
{
if (!expr_type.array.empty() && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter))
if (type_is_top_level_array(expr_type) && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter))
{
// Triggers when loading TessLevel directly as an array.
// Need explicit padding + cast.
Expand Down

0 comments on commit 2fba284

Please sign in to comment.