Handles argument_decl() correctly.
-#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)]];
fragment main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
- spvUnsafeArray<float, 2> gl_ClipDistance = {};
+ float gl_ClipDistance[2] = {};
gl_ClipDistance[0] = in.gl_ClipDistance_0;
gl_ClipDistance[1] = in.gl_ClipDistance_1;
out.FragColor = float4((1.0 - gl_ClipDistance[0]) - gl_ClipDistance[1]);
-#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 v0 [[user(locn0)]];
vertex main0_out main0()
{
main0_out out = {};
- spvUnsafeArray<float, 2> gl_ClipDistance = {};
+ float gl_ClipDistance[2] = {};
out.v0 = float4(1.0);
out.v1 = float4(2.0);
out.gl_Position = float4(3.0);
--- /dev/null
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 gl_Position [[position]];
+};
+
+struct main0_patchIn
+{
+ float4 gl_TessLevel [[attribute(0)]];
+};
+
+[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
+{
+ main0_out out = {};
+ float gl_TessLevelOuter[4] = {};
+ gl_TessLevelOuter[0] = patchIn.gl_TessLevel.x;
+ gl_TessLevelOuter[1] = patchIn.gl_TessLevel.y;
+ gl_TessLevelOuter[2] = patchIn.gl_TessLevel.z;
+ out.gl_Position = float4(gl_TessLevelOuter[0], gl_TessLevelOuter[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]);
+ return out;
+}
+
-#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 gl_Position [[position]];
[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
- spvUnsafeArray<float, 2> gl_TessLevelInner = {};
- spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
+ float gl_TessLevelInner[2] = {};
+ float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevel.w;
gl_TessLevelOuter[0] = patchIn.gl_TessLevel.x;
gl_TessLevelOuter[1] = patchIn.gl_TessLevel.y;
-#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)]];
fragment main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
- spvUnsafeArray<float, 2> gl_ClipDistance = {};
+ float gl_ClipDistance[2] = {};
gl_ClipDistance[0] = in.gl_ClipDistance_0;
gl_ClipDistance[1] = in.gl_ClipDistance_1;
out.FragColor = float4((1.0 - gl_ClipDistance[0]) - gl_ClipDistance[1]);
#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 v0 [[user(locn0)]];
vertex main0_out main0()
{
main0_out out = {};
- spvUnsafeArray<float, 2> gl_ClipDistance = {};
+ float gl_ClipDistance[2] = {};
write_in_func(out.v0, out.v1, out.gl_Position, out.gl_PointSize, gl_ClipDistance);
return out;
}
--- /dev/null
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 gl_Position [[position]];
+};
+
+struct main0_patchIn
+{
+ float4 gl_TessLevel [[attribute(0)]];
+};
+
+static inline __attribute__((always_inline))
+float4 read_tess_levels(thread float (&gl_TessLevelOuter)[4])
+{
+ return float4(gl_TessLevelOuter[0], gl_TessLevelOuter[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]);
+}
+
+[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
+{
+ main0_out out = {};
+ float gl_TessLevelOuter[4] = {};
+ gl_TessLevelOuter[0] = patchIn.gl_TessLevel.x;
+ gl_TessLevelOuter[1] = patchIn.gl_TessLevel.y;
+ gl_TessLevelOuter[2] = patchIn.gl_TessLevel.z;
+ out.gl_Position = read_tess_levels(gl_TessLevelOuter);
+ return out;
+}
+
-#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 gl_Position [[position]];
[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
- spvUnsafeArray<float, 2> gl_TessLevelInner = {};
- spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
+ float gl_TessLevelInner[2] = {};
+ float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevel.w;
gl_TessLevelOuter[0] = patchIn.gl_TessLevel.x;
gl_TessLevelOuter[1] = patchIn.gl_TessLevel.y;
--- /dev/null
+#version 450
+layout(triangles) in;
+
+vec4 read_tess_levels()
+{
+ return vec4(
+ gl_TessLevelOuter[0],
+ gl_TessLevelOuter[1],
+ gl_TessLevelOuter[2],
+ gl_TessLevelOuter[3]);
+}
+
+void main()
+{
+ gl_Position = read_tess_levels();
+}
!is_patch);
}
-// Threadgroup arrays can't have a wrapper type
std::string CompilerMSL::variable_decl(const SPIRVariable &variable)
{
bool old_is_using_builtin_array = is_using_builtin_array;
- if (variable_decl_is_threadgroup_like(variable))
+
+ // Threadgroup arrays can't have a wrapper type.
+ // More special cases. ClipDistance and CullDistance are emitted as plain arrays in stage out,
+ // so preserve that property when emitting them as masked variables. Avoids lots of extra special casing
+ // in argument_decl(). Similar argument for TessLevels.
+ if (variable_decl_is_threadgroup_like(variable) || has_decoration(variable.self, DecorationBuiltIn))
is_using_builtin_array = true;
+
std::string expr = CompilerGLSL::variable_decl(variable);
is_using_builtin_array = old_is_using_builtin_array;
return expr;