Support the SPV_KHR_post_depth_coverage extension.
Using the `PostDepthCoverage` mode specifies that the `gl_SampleMaskIn` variable is to contain the computed coverage mask following the early fragment tests, which this mode requires and implicitly enables. Note that unlike Vulkan and OpenGL, Metal places this on the sample mask input itself, and furthermore does *not* implicitly enable early fragment testing. If it isn't enabled explicitly with an `[[early_fragment_tests]]` attribute, the compiler will error out. So we have to enable that mode explicitly if `PostDepthCoverage` is enabled but `EarlyFragmentTests` isn't. For Metal, only iOS supports this; for some reason, Apple has yet to implement it on macOS, even though many desktop cards support it.
This commit is contained in:
parent
9f3bebe3d0
commit
1df47db6ba
@ -0,0 +1,17 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
[[ early_fragment_tests ]] fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask, post_depth_coverage]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = float4(float(gl_SampleMaskIn));
|
||||
return out;
|
||||
}
|
||||
|
11
reference/opt/shaders/frag/post-depth-coverage.frag
Normal file
11
reference/opt/shaders/frag/post-depth-coverage.frag
Normal file
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_ARB_post_depth_coverage : require
|
||||
layout(early_fragment_tests, post_depth_coverage) in;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(float(gl_SampleMaskIn[0]));
|
||||
}
|
||||
|
17
reference/shaders-msl/frag/post-depth-coverage.ios.msl2.frag
Normal file
17
reference/shaders-msl/frag/post-depth-coverage.ios.msl2.frag
Normal file
@ -0,0 +1,17 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
[[ early_fragment_tests ]] fragment main0_out main0(uint gl_SampleMaskIn [[sample_mask, post_depth_coverage]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = float4(float(gl_SampleMaskIn));
|
||||
return out;
|
||||
}
|
||||
|
11
reference/shaders/frag/post-depth-coverage.frag
Normal file
11
reference/shaders/frag/post-depth-coverage.frag
Normal file
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_ARB_post_depth_coverage : require
|
||||
layout(early_fragment_tests, post_depth_coverage) in;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(float(gl_SampleMaskIn[0]));
|
||||
}
|
||||
|
11
shaders-msl/frag/post-depth-coverage.ios.msl2.frag
Normal file
11
shaders-msl/frag/post-depth-coverage.ios.msl2.frag
Normal file
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_ARB_post_depth_coverage : require
|
||||
|
||||
layout(post_depth_coverage) in;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(gl_SampleMaskIn[0]);
|
||||
}
|
11
shaders/frag/post-depth-coverage.frag
Normal file
11
shaders/frag/post-depth-coverage.frag
Normal file
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
#extension GL_ARB_post_depth_coverage : require
|
||||
|
||||
layout(post_depth_coverage) in;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(gl_SampleMaskIn[0]);
|
||||
}
|
@ -600,6 +600,10 @@ void CompilerGLSL::emit_header()
|
||||
require_extension_internal("GL_ARB_shader_image_load_store");
|
||||
}
|
||||
|
||||
// Needed for: layout(post_depth_coverage) in;
|
||||
if (execution.flags.get(ExecutionModePostDepthCoverage))
|
||||
require_extension_internal("GL_ARB_post_depth_coverage");
|
||||
|
||||
for (auto &ext : forced_extensions)
|
||||
{
|
||||
if (ext == "GL_EXT_shader_explicit_arithmetic_types_float16")
|
||||
@ -763,6 +767,8 @@ void CompilerGLSL::emit_header()
|
||||
|
||||
if (execution.flags.get(ExecutionModeEarlyFragmentTests))
|
||||
inputs.push_back("early_fragment_tests");
|
||||
if (execution.flags.get(ExecutionModePostDepthCoverage))
|
||||
inputs.push_back("post_depth_coverage");
|
||||
|
||||
if (!options.es && execution.flags.get(ExecutionModeDepthGreater))
|
||||
statement("layout(depth_greater) out float gl_FragDepth;");
|
||||
|
@ -6165,8 +6165,10 @@ string CompilerMSL::func_type_decl(SPIRType &type)
|
||||
execution.output_vertices, ") ]] vertex");
|
||||
break;
|
||||
case ExecutionModelFragment:
|
||||
entry_type =
|
||||
execution.flags.get(ExecutionModeEarlyFragmentTests) ? "[[ early_fragment_tests ]] fragment" : "fragment";
|
||||
entry_type = execution.flags.get(ExecutionModeEarlyFragmentTests) ||
|
||||
execution.flags.get(ExecutionModePostDepthCoverage) ?
|
||||
"[[ early_fragment_tests ]] fragment" :
|
||||
"fragment";
|
||||
break;
|
||||
case ExecutionModelTessellationControl:
|
||||
if (!msl_options.supports_msl_version(1, 2))
|
||||
@ -6330,6 +6332,7 @@ string CompilerMSL::entry_point_arg_stage_in()
|
||||
void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
||||
{
|
||||
// Builtin variables
|
||||
SmallVector<pair<SPIRVariable *, BuiltIn>, 8> active_builtins;
|
||||
ir.for_each_typed_id<SPIRVariable>([&](uint32_t var_id, SPIRVariable &var) {
|
||||
auto bi_type = BuiltIn(get_decoration(var_id, DecorationBuiltIn));
|
||||
|
||||
@ -6344,6 +6347,9 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
||||
if (!active_input_builtins.get(bi_type) || !interface_variable_exists_in_entry_point(var_id))
|
||||
return;
|
||||
|
||||
// Remember this variable. We may need to correct its type.
|
||||
active_builtins.push_back(make_pair(&var, bi_type));
|
||||
|
||||
// These builtins are emitted specially. If we pass this branch, the builtin directly matches
|
||||
// a MSL builtin.
|
||||
if (bi_type != BuiltInSamplePosition && bi_type != BuiltInHelperInvocation &&
|
||||
@ -6363,11 +6369,26 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
||||
ep_args += ", ";
|
||||
|
||||
ep_args += builtin_type_decl(bi_type, var_id) + " " + to_expression(var_id);
|
||||
ep_args += " [[" + builtin_qualifier(bi_type) + "]]";
|
||||
ep_args += " [[" + builtin_qualifier(bi_type);
|
||||
if (bi_type == BuiltInSampleMask && get_entry_point().flags.get(ExecutionModePostDepthCoverage))
|
||||
{
|
||||
if (!msl_options.supports_msl_version(2))
|
||||
SPIRV_CROSS_THROW("Post-depth coverage requires Metal 2.0.");
|
||||
if (!msl_options.is_ios())
|
||||
SPIRV_CROSS_THROW("Post-depth coverage is only supported on iOS.");
|
||||
ep_args += ", post_depth_coverage";
|
||||
}
|
||||
ep_args += "]]";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Correct the types of all encountered active builtins. We couldn't do this before
|
||||
// because ensure_correct_builtin_type() may increase the bound, which isn't allowed
|
||||
// while iterating over IDs.
|
||||
for (auto &var : active_builtins)
|
||||
var.first->basetype = ensure_correct_builtin_type(var.first->basetype, var.second);
|
||||
|
||||
// Vertex and instance index built-ins
|
||||
if (needs_vertex_idx_arg)
|
||||
ep_args += built_in_func_arg(BuiltInVertexIndex, !ep_args.empty());
|
||||
|
Loading…
Reference in New Issue
Block a user