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>2021-04-16 13:18:31 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2021-04-19 13:10:49 +0300
commit682a227f4b2e251a5bae89fa76849ace743926ad (patch)
tree386a3a10015b231332157c317f170c2c4479040f
parentc1edd35d579e708336cf8f8e2c981960ce6dd6e8 (diff)
MSL: Make builtin argument type declaration context sensitive.
Sometimes we'll need array template, sometimes not :shrug:.
-rw-r--r--reference/opt/shaders-msl/frag/read-cull-clip-distance-in-function.frag72
-rw-r--r--reference/shaders-msl/frag/read-cull-clip-distance-in-function.frag78
-rw-r--r--reference/shaders-msl/masking/write-outputs.mask-location-0.for-tess.vert2
-rw-r--r--reference/shaders-msl/masking/write-outputs.mask-location-1.for-tess.vert2
-rw-r--r--reference/shaders-msl/masking/write-outputs.mask-point-size.for-tess.vert2
-rw-r--r--shaders-msl/frag/read-cull-clip-distance-in-function.frag20
-rw-r--r--spirv_msl.cpp30
7 files changed, 196 insertions, 10 deletions
diff --git a/reference/opt/shaders-msl/frag/read-cull-clip-distance-in-function.frag b/reference/opt/shaders-msl/frag/read-cull-clip-distance-in-function.frag
new file mode 100644
index 00000000..3c9757eb
--- /dev/null
+++ b/reference/opt/shaders-msl/frag/read-cull-clip-distance-in-function.frag
@@ -0,0 +1,72 @@
+#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 main0_out
+{
+ float4 FragColor [[color(0)]];
+};
+
+struct main0_in
+{
+ float gl_ClipDistance_0 [[user(clip0)]];
+ float gl_ClipDistance_1 [[user(clip1)]];
+ float gl_CullDistance_0 [[user(cull0)]];
+ float gl_CullDistance_1 [[user(cull1)]];
+};
+
+fragment main0_out main0(main0_in in [[stage_in]])
+{
+ main0_out out = {};
+ spvUnsafeArray<float, 2> gl_CullDistance = {};
+ spvUnsafeArray<float, 2> gl_ClipDistance = {};
+ gl_CullDistance[0] = in.gl_CullDistance_0;
+ gl_CullDistance[1] = in.gl_CullDistance_1;
+ gl_ClipDistance[0] = in.gl_ClipDistance_0;
+ gl_ClipDistance[1] = in.gl_ClipDistance_1;
+ out.FragColor = float4(gl_CullDistance[0], gl_CullDistance[1], gl_ClipDistance[0], gl_ClipDistance[1]);
+ return out;
+}
+
diff --git a/reference/shaders-msl/frag/read-cull-clip-distance-in-function.frag b/reference/shaders-msl/frag/read-cull-clip-distance-in-function.frag
new file mode 100644
index 00000000..02d57d9b
--- /dev/null
+++ b/reference/shaders-msl/frag/read-cull-clip-distance-in-function.frag
@@ -0,0 +1,78 @@
+#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 main0_out
+{
+ float4 FragColor [[color(0)]];
+};
+
+struct main0_in
+{
+ float gl_ClipDistance_0 [[user(clip0)]];
+ float gl_ClipDistance_1 [[user(clip1)]];
+ float gl_CullDistance_0 [[user(cull0)]];
+ float gl_CullDistance_1 [[user(cull1)]];
+};
+
+static inline __attribute__((always_inline))
+float4 read_in_func(thread spvUnsafeArray<float, 2>& gl_CullDistance, thread spvUnsafeArray<float, 2>& gl_ClipDistance)
+{
+ return float4(gl_CullDistance[0], gl_CullDistance[1], gl_ClipDistance[0], gl_ClipDistance[1]);
+}
+
+fragment main0_out main0(main0_in in [[stage_in]])
+{
+ main0_out out = {};
+ spvUnsafeArray<float, 2> gl_CullDistance = {};
+ spvUnsafeArray<float, 2> gl_ClipDistance = {};
+ gl_CullDistance[0] = in.gl_CullDistance_0;
+ gl_CullDistance[1] = in.gl_CullDistance_1;
+ gl_ClipDistance[0] = in.gl_ClipDistance_0;
+ gl_ClipDistance[1] = in.gl_ClipDistance_1;
+ out.FragColor = read_in_func(gl_CullDistance, gl_ClipDistance);
+ return out;
+}
+
diff --git a/reference/shaders-msl/masking/write-outputs.mask-location-0.for-tess.vert b/reference/shaders-msl/masking/write-outputs.mask-location-0.for-tess.vert
index a004a380..53f76b57 100644
--- a/reference/shaders-msl/masking/write-outputs.mask-location-0.for-tess.vert
+++ b/reference/shaders-msl/masking/write-outputs.mask-location-0.for-tess.vert
@@ -53,7 +53,7 @@ struct main0_out
};
static inline __attribute__((always_inline))
-void write_in_func(thread float4& v0, device float4& v1, device float4& gl_Position, device float& gl_PointSize, device float (&gl_ClipDistance)[2])
+void write_in_func(thread float4& v0, device float4& v1, device float4& gl_Position, device float& gl_PointSize, device spvUnsafeArray<float, 2>& gl_ClipDistance)
{
v0 = float4(1.0);
v1 = float4(2.0);
diff --git a/reference/shaders-msl/masking/write-outputs.mask-location-1.for-tess.vert b/reference/shaders-msl/masking/write-outputs.mask-location-1.for-tess.vert
index 02288822..8f9cfce5 100644
--- a/reference/shaders-msl/masking/write-outputs.mask-location-1.for-tess.vert
+++ b/reference/shaders-msl/masking/write-outputs.mask-location-1.for-tess.vert
@@ -53,7 +53,7 @@ struct main0_out
};
static inline __attribute__((always_inline))
-void write_in_func(device float4& v0, thread float4& v1, device float4& gl_Position, device float& gl_PointSize, device float (&gl_ClipDistance)[2])
+void write_in_func(device float4& v0, thread float4& v1, device float4& gl_Position, device float& gl_PointSize, device spvUnsafeArray<float, 2>& gl_ClipDistance)
{
v0 = float4(1.0);
v1 = float4(2.0);
diff --git a/reference/shaders-msl/masking/write-outputs.mask-point-size.for-tess.vert b/reference/shaders-msl/masking/write-outputs.mask-point-size.for-tess.vert
index 1307b5b8..07494ea3 100644
--- a/reference/shaders-msl/masking/write-outputs.mask-point-size.for-tess.vert
+++ b/reference/shaders-msl/masking/write-outputs.mask-point-size.for-tess.vert
@@ -53,7 +53,7 @@ struct main0_out
};
static inline __attribute__((always_inline))
-void write_in_func(device float4& v0, device float4& v1, device float4& gl_Position, thread float& gl_PointSize, device float (&gl_ClipDistance)[2])
+void write_in_func(device float4& v0, device float4& v1, device float4& gl_Position, thread float& gl_PointSize, device spvUnsafeArray<float, 2>& gl_ClipDistance)
{
v0 = float4(1.0);
v1 = float4(2.0);
diff --git a/shaders-msl/frag/read-cull-clip-distance-in-function.frag b/shaders-msl/frag/read-cull-clip-distance-in-function.frag
new file mode 100644
index 00000000..0b82dc2d
--- /dev/null
+++ b/shaders-msl/frag/read-cull-clip-distance-in-function.frag
@@ -0,0 +1,20 @@
+#version 450
+
+layout(location = 0) out vec4 FragColor;
+
+in float gl_CullDistance[2];
+in float gl_ClipDistance[2];
+
+vec4 read_in_func()
+{
+ return vec4(
+ gl_CullDistance[0],
+ gl_CullDistance[1],
+ gl_ClipDistance[0],
+ gl_ClipDistance[1]);
+}
+
+void main()
+{
+ FragColor = read_in_func();
+}
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index f13e8451..3c9338fb 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -12387,7 +12387,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
auto &var = get<SPIRVariable>(arg.id);
auto &type = get_variable_data_type(var);
auto &var_type = get<SPIRType>(arg.type);
- StorageClass storage = var_type.storage;
+ StorageClass type_storage = var_type.storage;
bool is_pointer = var_type.pointer;
// If we need to modify the name of the variable, make sure we use the original variable.
@@ -12424,15 +12424,30 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
string address_space = get_argument_address_space(var);
bool builtin = has_decoration(var.self, DecorationBuiltIn);
auto builtin_type = BuiltIn(get_decoration(arg.id, DecorationBuiltIn));
- is_using_builtin_array = builtin;
+
if (address_space == "threadgroup")
is_using_builtin_array = true;
if (var.basevariable && (var.basevariable == stage_in_ptr_var_id || var.basevariable == stage_out_ptr_var_id))
decl = join(cv_qualifier, type_to_glsl(type, arg.id));
else if (builtin)
- decl = join(cv_qualifier, builtin_type_decl(builtin_type, arg.id));
- else if ((storage == StorageClassUniform || storage == StorageClassStorageBuffer) && is_array(type))
+ {
+ // Only use templated array for Clip/Cull distance when feasible.
+ // In other scenarios, we need need to override array length for tess levels,
+ // or we need to emit the expected type for builtins (uint vs int).
+ if (builtin_type != BuiltInClipDistance && builtin_type != BuiltInCullDistance)
+ is_using_builtin_array = true;
+
+ auto storage = get<SPIRType>(var.basetype).storage;
+ if (storage == StorageClassOutput && variable_storage_requires_stage_io(storage))
+ is_using_builtin_array = true;
+
+ if (is_using_builtin_array)
+ decl = join(cv_qualifier, builtin_type_decl(builtin_type, arg.id));
+ else
+ decl = join(cv_qualifier, type_to_glsl(type, arg.id));
+ }
+ else if ((type_storage == StorageClassUniform || type_storage == StorageClassStorageBuffer) && is_array(type))
{
is_using_builtin_array = true;
decl += join(cv_qualifier, type_to_glsl(type, arg.id), "*");
@@ -12456,10 +12471,10 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
decl = join(cv_qualifier, type_to_glsl(type, arg.id));
}
- bool opaque_handle = storage == StorageClassUniformConstant;
+ bool opaque_handle = type_storage == StorageClassUniformConstant;
if (!builtin && !opaque_handle && !is_pointer &&
- (storage == StorageClassFunction || storage == StorageClassGeneric))
+ (type_storage == StorageClassFunction || type_storage == StorageClassGeneric))
{
// If the argument is a pure value and not an opaque type, we will pass by value.
if (msl_options.force_native_arrays && is_array(type))
@@ -12500,7 +12515,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
if (msl_options.argument_buffers)
{
uint32_t desc_set = get_decoration(name_id, DecorationDescriptorSet);
- if ((storage == StorageClassUniform || storage == StorageClassStorageBuffer) &&
+ if ((type_storage == StorageClassUniform || type_storage == StorageClassStorageBuffer) &&
descriptor_set_is_argument_buffer(desc_set))
{
// An awkward case where we need to emit *more* address space declarations (yay!).
@@ -14226,6 +14241,7 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin, uint32_t id)
// Vertex function out
case BuiltInClipDistance:
+ case BuiltInCullDistance:
return "float";
case BuiltInPointSize:
return "float";