Merge pull request #1660 from KhronosGroup/fix-1658
MSL: Use proper array for quad tess levels.
This commit is contained in:
commit
c624d5387c
@ -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 main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
@ -17,7 +58,15 @@ struct main0_patchIn
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w), 0.0, 1.0);
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
out.gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0]) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner[0]) * gl_TessLevelOuter[2]), ((gl_TessCoord.y * gl_TessLevelInner[1]) * gl_TessLevelOuter[1]) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner[1]) * gl_TessLevelOuter[3]), 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -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 main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
@ -17,8 +58,16 @@ struct main0_patchIn
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
gl_TessCoord.y = 1.0 - gl_TessCoord.y;
|
||||
out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y), 0.0, 1.0);
|
||||
out.gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0]) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner[0]) * gl_TessLevelOuter[2]), ((gl_TessCoord.y * gl_TessLevelInner[1]) * gl_TessLevelOuter[3]) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner[1]) * gl_TessLevelOuter[1]), 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -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 main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
@ -17,7 +58,15 @@ struct main0_patchIn
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w), 0.0, 1.0);
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
out.gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0]) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner[0]) * gl_TessLevelOuter[2]), ((gl_TessCoord.y * gl_TessLevelInner[1]) * gl_TessLevelOuter[1]) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner[1]) * gl_TessLevelOuter[3]), 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -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 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_patchIn
|
||||
{
|
||||
float4 gl_TessLevelOuter [[attribute(0)]];
|
||||
float2 gl_TessLevelInner [[attribute(1)]];
|
||||
};
|
||||
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
out.gl_Position = float4(gl_TessLevelOuter[0], gl_TessLevelOuter[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]) + float2(gl_TessLevelInner[0], gl_TessLevelInner[1]).xyxy;
|
||||
return out;
|
||||
}
|
||||
|
@ -58,10 +58,12 @@ struct main0_patchIn
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
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]);
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevel.w;
|
||||
out.gl_Position = float4(gl_TessLevelOuter[0], gl_TessLevelOuter[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]) + float2(gl_TessLevelInner[0], gl_TessLevelInner[1]).xyxy;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,73 @@
|
||||
#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 out_var_CUSTOM_VALUE [[user(locn0)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_patchIn
|
||||
{
|
||||
float4 gl_TessLevelOuter [[attribute(0)]];
|
||||
float2 gl_TessLevelInner [[attribute(1)]];
|
||||
};
|
||||
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
out.out_var_CUSTOM_VALUE = float4(gl_TessLevelOuter[0] + gl_TessLevelInner[0], gl_TessLevelOuter[1] + gl_TessLevelInner[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]);
|
||||
return out;
|
||||
}
|
||||
|
@ -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 main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
@ -25,7 +66,15 @@ struct main0_patchIn
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], uint gl_PrimitiveID [[patch_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = (((((float4(1.0) + patchIn.FragColor) + patchIn.gl_in[0].FragColors) + patchIn.gl_in[1].FragColors) + float4(patchIn.gl_TessLevelInner.x)) + float4(patchIn.gl_TessLevelOuter[int(gl_PrimitiveID) & 1])) + patchIn.gl_in[0].gl_Position;
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
out.gl_Position = (((((float4(1.0) + patchIn.FragColor) + patchIn.gl_in[0].FragColors) + patchIn.gl_in[1].FragColors) + float4(gl_TessLevelInner[0])) + float4(gl_TessLevelOuter[int(gl_PrimitiveID) & 1])) + patchIn.gl_in[0].gl_Position;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -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 main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
@ -17,7 +58,15 @@ struct main0_patchIn
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w), 0.0, 1.0);
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
out.gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0]) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner[0]) * gl_TessLevelOuter[2]), ((gl_TessCoord.y * gl_TessLevelInner[1]) * gl_TessLevelOuter[1]) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner[1]) * gl_TessLevelOuter[3]), 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -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 main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
@ -17,8 +58,16 @@ struct main0_patchIn
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
gl_TessCoord.y = 1.0 - gl_TessCoord.y;
|
||||
out.gl_Position = float4(((gl_TessCoord.x * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * patchIn.gl_TessLevelInner.x) * patchIn.gl_TessLevelOuter.z), ((gl_TessCoord.y * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.w) + (((1.0 - gl_TessCoord.y) * patchIn.gl_TessLevelInner.y) * patchIn.gl_TessLevelOuter.y), 0.0, 1.0);
|
||||
out.gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0]) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner[0]) * gl_TessLevelOuter[2]), ((gl_TessCoord.y * gl_TessLevelInner[1]) * gl_TessLevelOuter[3]) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner[1]) * gl_TessLevelOuter[1]), 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -1,10 +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 main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
@ -17,15 +56,23 @@ struct main0_patchIn
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void set_position(thread float4& gl_Position, thread float2& gl_TessCoord, thread float2& gl_TessLevelInner, thread float4& gl_TessLevelOuter)
|
||||
void set_position(thread float4& gl_Position, thread float2& gl_TessCoord, thread spvUnsafeArray<float, 2>& gl_TessLevelInner, thread spvUnsafeArray<float, 4>& gl_TessLevelOuter)
|
||||
{
|
||||
gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner.x) * gl_TessLevelOuter.x) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner.x) * gl_TessLevelOuter.z), ((gl_TessCoord.y * gl_TessLevelInner.y) * gl_TessLevelOuter.y) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner.y) * gl_TessLevelOuter.w), 0.0, 1.0);
|
||||
gl_Position = float4(((gl_TessCoord.x * gl_TessLevelInner[0]) * gl_TessLevelOuter[0]) + (((1.0 - gl_TessCoord.x) * gl_TessLevelInner[0]) * gl_TessLevelOuter[2]), ((gl_TessCoord.y * gl_TessLevelInner[1]) * gl_TessLevelOuter[1]) + (((1.0 - gl_TessCoord.y) * gl_TessLevelInner[1]) * gl_TessLevelOuter[3]), 0.0, 1.0);
|
||||
}
|
||||
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
|
||||
{
|
||||
main0_out out = {};
|
||||
set_position(out.gl_Position, gl_TessCoord, patchIn.gl_TessLevelInner, patchIn.gl_TessLevelOuter);
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
set_position(out.gl_Position, gl_TessCoord, gl_TessLevelInner, gl_TessLevelOuter);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -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 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_patchIn
|
||||
{
|
||||
float4 gl_TessLevelOuter [[attribute(0)]];
|
||||
float2 gl_TessLevelInner [[attribute(1)]];
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float4 read_tess_levels(thread spvUnsafeArray<float, 4>& gl_TessLevelOuter, thread spvUnsafeArray<float, 2>& gl_TessLevelInner)
|
||||
{
|
||||
return float4(gl_TessLevelOuter[0], gl_TessLevelOuter[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]) + float2(gl_TessLevelInner[0], gl_TessLevelInner[1]).xyxy;
|
||||
}
|
||||
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter.x;
|
||||
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter.y;
|
||||
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter.z;
|
||||
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter.w;
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner.x;
|
||||
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner.y;
|
||||
out.gl_Position = read_tess_levels(gl_TessLevelOuter, gl_TessLevelInner);
|
||||
return out;
|
||||
}
|
||||
|
@ -55,19 +55,21 @@ struct main0_patchIn
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float4 read_tess_levels(thread spvUnsafeArray<float, 4>& gl_TessLevelOuter)
|
||||
float4 read_tess_levels(thread spvUnsafeArray<float, 4>& gl_TessLevelOuter, thread spvUnsafeArray<float, 2>& gl_TessLevelInner)
|
||||
{
|
||||
return float4(gl_TessLevelOuter[0], gl_TessLevelOuter[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]);
|
||||
return float4(gl_TessLevelOuter[0], gl_TessLevelOuter[1], gl_TessLevelOuter[2], gl_TessLevelOuter[3]) + float2(gl_TessLevelInner[0], gl_TessLevelInner[1]).xyxy;
|
||||
}
|
||||
|
||||
[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float, 4> gl_TessLevelOuter = {};
|
||||
spvUnsafeArray<float, 2> gl_TessLevelInner = {};
|
||||
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);
|
||||
gl_TessLevelInner[0] = patchIn.gl_TessLevel.w;
|
||||
out.gl_Position = read_tess_levels(gl_TessLevelOuter, gl_TessLevelInner);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
58
shaders-msl-no-opt/asm/tese/copy-tess-level.asm.msl2.tese
Normal file
58
shaders-msl-no-opt/asm/tese/copy-tess-level.asm.msl2.tese
Normal file
@ -0,0 +1,58 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Google spiregg; 0
|
||||
; Bound: 35
|
||||
; Schema: 0
|
||||
OpCapability Tessellation
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint TessellationEvaluation %Domain "main" %gl_TessLevelOuter %gl_TessLevelInner %in_var_CUSTOM_VALUE %gl_TessCoord %out_var_CUSTOM_VALUE
|
||||
OpExecutionMode %Domain Quads
|
||||
OpSource HLSL 600
|
||||
OpName %in_var_CUSTOM_VALUE "in.var.CUSTOM_VALUE"
|
||||
OpName %out_var_CUSTOM_VALUE "out.var.CUSTOM_VALUE"
|
||||
OpName %Domain "Domain"
|
||||
OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
|
||||
OpDecorate %gl_TessLevelOuter Patch
|
||||
OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
|
||||
OpDecorate %gl_TessLevelInner Patch
|
||||
OpDecorate %gl_TessCoord BuiltIn TessCoord
|
||||
OpDecorate %gl_TessCoord Patch
|
||||
OpDecorate %in_var_CUSTOM_VALUE Location 0
|
||||
OpDecorate %out_var_CUSTOM_VALUE Location 0
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%float = OpTypeFloat 32
|
||||
%_arr_float_uint_4 = OpTypeArray %float %uint_4
|
||||
%_ptr_Input__arr_float_uint_4 = OpTypePointer Input %_arr_float_uint_4
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr_float_uint_2 = OpTypeArray %float %uint_2
|
||||
%_ptr_Input__arr_float_uint_2 = OpTypePointer Input %_arr_float_uint_2
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4
|
||||
%_ptr_Input__arr_v4float_uint_4 = OpTypePointer Input %_arr_v4float_uint_4
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Input_v3float = OpTypePointer Input %v3float
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%void = OpTypeVoid
|
||||
%22 = OpTypeFunction %void
|
||||
%gl_TessLevelOuter = OpVariable %_ptr_Input__arr_float_uint_4 Input
|
||||
%gl_TessLevelInner = OpVariable %_ptr_Input__arr_float_uint_2 Input
|
||||
%in_var_CUSTOM_VALUE = OpVariable %_ptr_Input__arr_v4float_uint_4 Input
|
||||
%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
|
||||
%out_var_CUSTOM_VALUE = OpVariable %_ptr_Output_v4float Output
|
||||
%Domain = OpFunction %void None %22
|
||||
%23 = OpLabel
|
||||
%24 = OpLoad %_arr_float_uint_4 %gl_TessLevelOuter
|
||||
%25 = OpLoad %_arr_float_uint_2 %gl_TessLevelInner
|
||||
%26 = OpCompositeExtract %float %24 0
|
||||
%27 = OpCompositeExtract %float %24 1
|
||||
%28 = OpCompositeExtract %float %24 2
|
||||
%29 = OpCompositeExtract %float %24 3
|
||||
%30 = OpCompositeExtract %float %25 0
|
||||
%31 = OpCompositeExtract %float %25 1
|
||||
%32 = OpFAdd %float %26 %30
|
||||
%33 = OpFAdd %float %27 %31
|
||||
%34 = OpCompositeConstruct %v4float %32 %33 %28 %29
|
||||
OpStore %out_var_CUSTOM_VALUE %34
|
||||
OpReturn
|
||||
OpFunctionEnd
|
17
shaders-msl/tese/read-tess-level-in-func-quad.msl2.tese
Normal file
17
shaders-msl/tese/read-tess-level-in-func-quad.msl2.tese
Normal file
@ -0,0 +1,17 @@
|
||||
#version 450
|
||||
layout(quads) in;
|
||||
|
||||
vec4 read_tess_levels()
|
||||
{
|
||||
return vec4(
|
||||
gl_TessLevelOuter[0],
|
||||
gl_TessLevelOuter[1],
|
||||
gl_TessLevelOuter[2],
|
||||
gl_TessLevelOuter[3]) +
|
||||
vec2(gl_TessLevelInner[0], gl_TessLevelInner[1]).xyxy;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = read_tess_levels();
|
||||
}
|
@ -7,7 +7,8 @@ vec4 read_tess_levels()
|
||||
gl_TessLevelOuter[0],
|
||||
gl_TessLevelOuter[1],
|
||||
gl_TessLevelOuter[2],
|
||||
gl_TessLevelOuter[3]);
|
||||
gl_TessLevelOuter[3]) +
|
||||
vec2(gl_TessLevelInner[0], gl_TessLevelInner[1]).xyxy;
|
||||
}
|
||||
|
||||
void main()
|
||||
|
193
spirv_msl.cpp
193
spirv_msl.cpp
@ -2797,100 +2797,19 @@ void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_
|
||||
BuiltIn builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn));
|
||||
|
||||
// Force the variable to have the proper name.
|
||||
set_name(var.self, builtin_to_glsl(builtin, StorageClassFunction));
|
||||
string var_name = builtin_to_glsl(builtin, StorageClassFunction);
|
||||
set_name(var.self, var_name);
|
||||
|
||||
if (get_execution_mode_bitset().get(ExecutionModeTriangles))
|
||||
{
|
||||
// Triangles are tricky, because we want only one member in the struct.
|
||||
// We need to declare the variable early and at entry-point scope.
|
||||
entry_func.add_local_variable(var.self);
|
||||
vars_needing_early_declaration.push_back(var.self);
|
||||
bool triangles = get_execution_mode_bitset().get(ExecutionModeTriangles);
|
||||
string mbr_name;
|
||||
|
||||
// We need to declare the variable early and at entry-point scope.
|
||||
entry_func.add_local_variable(var.self);
|
||||
vars_needing_early_declaration.push_back(var.self);
|
||||
|
||||
string mbr_name = "gl_TessLevel";
|
||||
|
||||
// If we already added the other one, we can skip this step.
|
||||
if (!added_builtin_tess_level)
|
||||
{
|
||||
// Add a reference to the variable type to the interface struct.
|
||||
uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size());
|
||||
|
||||
uint32_t type_id = build_extended_vector_type(var_type.self, 4);
|
||||
|
||||
ib_type.member_types.push_back(type_id);
|
||||
|
||||
// Give the member a name
|
||||
set_member_name(ib_type.self, ib_mbr_idx, mbr_name);
|
||||
|
||||
// We cannot decorate both, but the important part is that
|
||||
// it's marked as builtin so we can get automatic attribute assignment if needed.
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationBuiltIn, builtin);
|
||||
|
||||
// There is no qualified alias since we need to flatten the internal array on return.
|
||||
if (get_decoration_bitset(var.self).get(DecorationLocation))
|
||||
{
|
||||
uint32_t locn = get_decoration(var.self, DecorationLocation);
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, var_type, StorageClassInput);
|
||||
}
|
||||
else if (inputs_by_builtin.count(builtin))
|
||||
{
|
||||
uint32_t locn = inputs_by_builtin[builtin].location;
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, var_type, StorageClassInput);
|
||||
}
|
||||
|
||||
added_builtin_tess_level = true;
|
||||
}
|
||||
|
||||
switch (builtin)
|
||||
{
|
||||
case BuiltInTessLevelOuter:
|
||||
entry_func.fixup_hooks_in.push_back([=, &var]() {
|
||||
statement(to_name(var.self), "[0] = ", ib_var_ref, ".", mbr_name, ".x;");
|
||||
statement(to_name(var.self), "[1] = ", ib_var_ref, ".", mbr_name, ".y;");
|
||||
statement(to_name(var.self), "[2] = ", ib_var_ref, ".", mbr_name, ".z;");
|
||||
});
|
||||
break;
|
||||
|
||||
case BuiltInTessLevelInner:
|
||||
entry_func.fixup_hooks_in.push_back(
|
||||
[=, &var]() { statement(to_name(var.self), "[0] = ", ib_var_ref, ".", mbr_name, ".w;"); });
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add a reference to the variable type to the interface struct.
|
||||
uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size());
|
||||
|
||||
uint32_t type_id = build_extended_vector_type(var_type.self, builtin == BuiltInTessLevelOuter ? 4 : 2);
|
||||
// Change the type of the variable, too.
|
||||
uint32_t ptr_type_id = ir.increase_bound_by(1);
|
||||
auto &new_var_type = set<SPIRType>(ptr_type_id, get<SPIRType>(type_id));
|
||||
new_var_type.pointer = true;
|
||||
new_var_type.pointer_depth++;
|
||||
new_var_type.storage = StorageClassInput;
|
||||
new_var_type.parent_type = type_id;
|
||||
var.basetype = ptr_type_id;
|
||||
|
||||
ib_type.member_types.push_back(type_id);
|
||||
|
||||
// Give the member a name
|
||||
string mbr_name = to_expression(var.self);
|
||||
set_member_name(ib_type.self, ib_mbr_idx, mbr_name);
|
||||
|
||||
// Since vectors can be indexed like arrays, there is no need to unpack this. We can
|
||||
// just refer to the vector directly. So give it a qualified alias.
|
||||
string qual_var_name = ib_var_ref + "." + mbr_name;
|
||||
ir.meta[var.self].decoration.qualified_alias = qual_var_name;
|
||||
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationBuiltIn, builtin);
|
||||
// Add a reference to the variable type to the interface struct.
|
||||
uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size());
|
||||
|
||||
const auto mark_locations = [&](const SPIRType &new_var_type) {
|
||||
if (get_decoration_bitset(var.self).get(DecorationLocation))
|
||||
{
|
||||
uint32_t locn = get_decoration(var.self, DecorationLocation);
|
||||
@ -2903,6 +2822,76 @@ void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
|
||||
mark_location_as_used_by_shader(locn, new_var_type, StorageClassInput);
|
||||
}
|
||||
};
|
||||
|
||||
if (triangles)
|
||||
{
|
||||
// Triangles are tricky, because we want only one member in the struct.
|
||||
mbr_name = "gl_TessLevel";
|
||||
|
||||
// If we already added the other one, we can skip this step.
|
||||
if (!added_builtin_tess_level)
|
||||
{
|
||||
uint32_t type_id = build_extended_vector_type(var_type.self, 4);
|
||||
|
||||
ib_type.member_types.push_back(type_id);
|
||||
|
||||
// Give the member a name
|
||||
set_member_name(ib_type.self, ib_mbr_idx, mbr_name);
|
||||
|
||||
// We cannot decorate both, but the important part is that
|
||||
// it's marked as builtin so we can get automatic attribute assignment if needed.
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationBuiltIn, builtin);
|
||||
|
||||
mark_locations(var_type);
|
||||
added_builtin_tess_level = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mbr_name = var_name;
|
||||
|
||||
uint32_t type_id = build_extended_vector_type(var_type.self, builtin == BuiltInTessLevelOuter ? 4 : 2);
|
||||
|
||||
uint32_t ptr_type_id = ir.increase_bound_by(1);
|
||||
auto &new_var_type = set<SPIRType>(ptr_type_id, get<SPIRType>(type_id));
|
||||
new_var_type.pointer = true;
|
||||
new_var_type.pointer_depth++;
|
||||
new_var_type.storage = StorageClassInput;
|
||||
new_var_type.parent_type = type_id;
|
||||
|
||||
ib_type.member_types.push_back(type_id);
|
||||
|
||||
// Give the member a name
|
||||
set_member_name(ib_type.self, ib_mbr_idx, mbr_name);
|
||||
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationBuiltIn, builtin);
|
||||
|
||||
mark_locations(new_var_type);
|
||||
}
|
||||
|
||||
if (builtin == BuiltInTessLevelOuter)
|
||||
{
|
||||
entry_func.fixup_hooks_in.push_back([=]() {
|
||||
statement(var_name, "[0] = ", ib_var_ref, ".", mbr_name, ".x;");
|
||||
statement(var_name, "[1] = ", ib_var_ref, ".", mbr_name, ".y;");
|
||||
statement(var_name, "[2] = ", ib_var_ref, ".", mbr_name, ".z;");
|
||||
if (!triangles)
|
||||
statement(var_name, "[3] = ", ib_var_ref, ".", mbr_name, ".w;");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
entry_func.fixup_hooks_in.push_back([=]() {
|
||||
if (triangles)
|
||||
{
|
||||
statement(var_name, "[0] = ", ib_var_ref, ".", mbr_name, ".w;");
|
||||
}
|
||||
else
|
||||
{
|
||||
statement(var_name, "[0] = ", ib_var_ref, ".", mbr_name, ".x;");
|
||||
statement(var_name, "[1] = ", ib_var_ref, ".", mbr_name, ".y;");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -13979,31 +13968,21 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
|
||||
break;
|
||||
|
||||
case BuiltInTessLevelOuter:
|
||||
if (get_execution_model() == ExecutionModelTessellationEvaluation)
|
||||
if (get_execution_model() == ExecutionModelTessellationControl &&
|
||||
storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
|
||||
{
|
||||
if (storage != StorageClassOutput && !get_entry_point().flags.get(ExecutionModeTriangles) &&
|
||||
current_function && (current_function->self == ir.default_entry_point))
|
||||
return join(patch_stage_in_var_name, ".", CompilerGLSL::builtin_to_glsl(builtin, storage));
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
|
||||
return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id),
|
||||
"].edgeTessellationFactor");
|
||||
}
|
||||
break;
|
||||
|
||||
case BuiltInTessLevelInner:
|
||||
if (get_execution_model() == ExecutionModelTessellationEvaluation)
|
||||
if (get_execution_model() == ExecutionModelTessellationControl &&
|
||||
storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
|
||||
{
|
||||
if (storage != StorageClassOutput && !get_entry_point().flags.get(ExecutionModeTriangles) &&
|
||||
current_function && (current_function->self == ir.default_entry_point))
|
||||
return join(patch_stage_in_var_name, ".", CompilerGLSL::builtin_to_glsl(builtin, storage));
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
|
||||
return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id),
|
||||
"].insideTessellationFactor");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user