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:
-rw-r--r--reference/opt/shaders-msl/frag/depth-out-early-frag-tests.frag19
-rw-r--r--reference/opt/shaders-msl/frag/depth-out-no-early-frag-tests.frag19
-rw-r--r--reference/shaders-msl/frag/depth-out-early-frag-tests.frag19
-rw-r--r--reference/shaders-msl/frag/depth-out-no-early-frag-tests.frag19
-rw-r--r--shaders-msl/frag/depth-out-early-frag-tests.frag11
-rw-r--r--shaders-msl/frag/depth-out-no-early-frag-tests.frag10
-rw-r--r--spirv_msl.cpp23
-rw-r--r--spirv_msl.hpp2
8 files changed, 115 insertions, 7 deletions
diff --git a/reference/opt/shaders-msl/frag/depth-out-early-frag-tests.frag b/reference/opt/shaders-msl/frag/depth-out-early-frag-tests.frag
new file mode 100644
index 00000000..21884d81
--- /dev/null
+++ b/reference/opt/shaders-msl/frag/depth-out-early-frag-tests.frag
@@ -0,0 +1,19 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 color_out [[color(0)]];
+};
+
+[[ early_fragment_tests ]] fragment main0_out main0()
+{
+ float gl_FragDepth;
+ main0_out out = {};
+ out.color_out = float4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = 0.699999988079071044921875;
+ return out;
+}
+
diff --git a/reference/opt/shaders-msl/frag/depth-out-no-early-frag-tests.frag b/reference/opt/shaders-msl/frag/depth-out-no-early-frag-tests.frag
new file mode 100644
index 00000000..57d810fa
--- /dev/null
+++ b/reference/opt/shaders-msl/frag/depth-out-no-early-frag-tests.frag
@@ -0,0 +1,19 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 color_out [[color(0)]];
+ float gl_FragDepth [[depth(less)]];
+};
+
+fragment main0_out main0()
+{
+ main0_out out = {};
+ out.color_out = float4(1.0, 0.0, 0.0, 1.0);
+ out.gl_FragDepth = 0.699999988079071044921875;
+ return out;
+}
+
diff --git a/reference/shaders-msl/frag/depth-out-early-frag-tests.frag b/reference/shaders-msl/frag/depth-out-early-frag-tests.frag
new file mode 100644
index 00000000..21884d81
--- /dev/null
+++ b/reference/shaders-msl/frag/depth-out-early-frag-tests.frag
@@ -0,0 +1,19 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 color_out [[color(0)]];
+};
+
+[[ early_fragment_tests ]] fragment main0_out main0()
+{
+ float gl_FragDepth;
+ main0_out out = {};
+ out.color_out = float4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = 0.699999988079071044921875;
+ return out;
+}
+
diff --git a/reference/shaders-msl/frag/depth-out-no-early-frag-tests.frag b/reference/shaders-msl/frag/depth-out-no-early-frag-tests.frag
new file mode 100644
index 00000000..57d810fa
--- /dev/null
+++ b/reference/shaders-msl/frag/depth-out-no-early-frag-tests.frag
@@ -0,0 +1,19 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 color_out [[color(0)]];
+ float gl_FragDepth [[depth(less)]];
+};
+
+fragment main0_out main0()
+{
+ main0_out out = {};
+ out.color_out = float4(1.0, 0.0, 0.0, 1.0);
+ out.gl_FragDepth = 0.699999988079071044921875;
+ return out;
+}
+
diff --git a/shaders-msl/frag/depth-out-early-frag-tests.frag b/shaders-msl/frag/depth-out-early-frag-tests.frag
new file mode 100644
index 00000000..4208d79a
--- /dev/null
+++ b/shaders-msl/frag/depth-out-early-frag-tests.frag
@@ -0,0 +1,11 @@
+#version 430
+layout(depth_less) out float gl_FragDepth;
+layout(early_fragment_tests) in;
+
+layout(location = 0) out vec4 color_out;
+
+void main()
+{
+ color_out = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = 0.699999988079071044921875;
+}
diff --git a/shaders-msl/frag/depth-out-no-early-frag-tests.frag b/shaders-msl/frag/depth-out-no-early-frag-tests.frag
new file mode 100644
index 00000000..84502079
--- /dev/null
+++ b/shaders-msl/frag/depth-out-no-early-frag-tests.frag
@@ -0,0 +1,10 @@
+#version 430
+layout(depth_less) out float gl_FragDepth;
+
+layout(location = 0) out vec4 color_out;
+
+void main()
+{
+ color_out = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = 0.699999988079071044921875;
+}
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index b08bb86f..fabf2e9c 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -3364,16 +3364,22 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
// It's not enough to simply avoid marking fragment outputs if the pipeline won't
// accept them. We can't put them in the struct at all, or otherwise the compiler
// complains that the outputs weren't explicitly marked.
+ // Frag depth and stencil outputs are incompatible with explicit early fragment tests.
+ // In GLSL, depth and stencil outputs are just ignored when explicit early fragment tests are required.
+ // In Metal, it's a compilation error, so we need to exclude them from the output struct.
if (get_execution_model() == ExecutionModelFragment && storage == StorageClassOutput && !patch &&
- ((is_builtin && ((bi_type == BuiltInFragDepth && !msl_options.enable_frag_depth_builtin) ||
- (bi_type == BuiltInFragStencilRefEXT && !msl_options.enable_frag_stencil_ref_builtin))) ||
+ ((is_builtin && ((bi_type == BuiltInFragDepth && (!msl_options.enable_frag_depth_builtin || uses_explicit_early_fragment_test())) ||
+ (bi_type == BuiltInFragStencilRefEXT && (!msl_options.enable_frag_stencil_ref_builtin || uses_explicit_early_fragment_test())))) ||
(!is_builtin && !(msl_options.enable_frag_output_mask & (1 << location)))))
{
hidden = true;
disabled_frag_outputs.push_back(var_id);
- // If a builtin, force it to have the proper name.
+ // If a builtin, force it to have the proper name, and mark it as not part of the output struct.
if (is_builtin)
+ {
set_name(var_id, builtin_to_glsl(bi_type, StorageClassFunction));
+ mask_stage_output_by_builtin(bi_type);
+ }
}
// Barycentric inputs must be emitted in stage-in, because they can have interpolation arguments.
@@ -11156,10 +11162,7 @@ string CompilerMSL::func_type_decl(SPIRType &type)
execution.output_vertices, ") ]] vertex");
break;
case ExecutionModelFragment:
- entry_type = execution.flags.get(ExecutionModeEarlyFragmentTests) ||
- execution.flags.get(ExecutionModePostDepthCoverage) ?
- "[[ early_fragment_tests ]] fragment" :
- "fragment";
+ entry_type = uses_explicit_early_fragment_test() ? "[[ early_fragment_tests ]] fragment" : "fragment";
break;
case ExecutionModelTessellationControl:
if (!msl_options.supports_msl_version(1, 2))
@@ -11179,6 +11182,12 @@ string CompilerMSL::func_type_decl(SPIRType &type)
return entry_type + " " + return_type;
}
+bool CompilerMSL::uses_explicit_early_fragment_test()
+{
+ auto &ep_flags = get_entry_point().flags;
+ return ep_flags.get(ExecutionModeEarlyFragmentTests) || ep_flags.get(ExecutionModePostDepthCoverage);
+}
+
// In MSL, address space qualifiers are required for all pointer or reference variables
string CompilerMSL::get_argument_address_space(const SPIRVariable &argument)
{
diff --git a/spirv_msl.hpp b/spirv_msl.hpp
index d1d2ef3e..f01cceaf 100644
--- a/spirv_msl.hpp
+++ b/spirv_msl.hpp
@@ -932,6 +932,8 @@ protected:
void build_implicit_builtins();
uint32_t build_constant_uint_array_pointer();
void emit_entry_point_declarations() override;
+ bool uses_explicit_early_fragment_test();
+
uint32_t builtin_frag_coord_id = 0;
uint32_t builtin_sample_id_id = 0;
uint32_t builtin_sample_mask_id = 0;