Merge pull request #1441 from cdavis5e/msl-tesc-composite-out

MSL: Fix handling of matrices and structs in the output control point array.
This commit is contained in:
Hans-Kristian Arntzen 2020-08-04 01:19:21 +02:00 committed by GitHub
commit 82d1c43e40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 242 additions and 4 deletions

View File

@ -0,0 +1,41 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float in_te_attr;
float4x3 in_te_data0;
float4x3 in_te_data1;
};
struct main0_in
{
float3 in_tc_attr;
ushort2 m_104;
};
kernel void main0(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], device main0_out* spvOut [[buffer(28)]], constant uint* spvIndirectParams [[buffer(29)]], device MTLQuadTessellationFactorsHalf* spvTessLevel [[buffer(26)]], device main0_in* spvIn [[buffer(22)]])
{
device main0_out* gl_out = &spvOut[gl_GlobalInvocationID.x - gl_GlobalInvocationID.x % 3];
device main0_in* gl_in = &spvIn[min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1] - 1) * spvIndirectParams[0]];
uint gl_InvocationID = gl_GlobalInvocationID.x % 3;
uint gl_PrimitiveID = min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1]);
float _15 = float(gl_InvocationID);
float3 _18 = float3(_15, 0.0, 0.0);
float3 _19 = float3(0.0, _15, 0.0);
float3 _20 = float3(0.0, 0.0, _15);
gl_out[gl_InvocationID].in_te_data0 = float4x3(_18, _19, _20, float3(0.0));
threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup);
int _42 = (gl_InvocationID + 1) % 3;
gl_out[gl_InvocationID].in_te_data1 = float4x3(_18 + gl_out[_42].in_te_data0[0], _19 + gl_out[_42].in_te_data0[1], _20 + gl_out[_42].in_te_data0[2], gl_out[_42].in_te_data0[3]);
gl_out[gl_InvocationID].in_te_attr = gl_in[gl_InvocationID].in_tc_attr.x;
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[2] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[3] = half(1.0);
}

View File

@ -0,0 +1,48 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct te_data
{
float a;
float b;
uint c;
};
struct main0_out
{
float in_te_attr;
te_data in_te_data0;
te_data in_te_data1;
};
struct main0_in
{
float3 in_tc_attr;
ushort2 m_119;
};
kernel void main0(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], device main0_out* spvOut [[buffer(28)]], constant uint* spvIndirectParams [[buffer(29)]], device MTLQuadTessellationFactorsHalf* spvTessLevel [[buffer(26)]], device main0_in* spvIn [[buffer(22)]])
{
device main0_out* gl_out = &spvOut[gl_GlobalInvocationID.x - gl_GlobalInvocationID.x % 3];
device main0_in* gl_in = &spvIn[min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1] - 1) * spvIndirectParams[0]];
uint gl_InvocationID = gl_GlobalInvocationID.x % 3;
uint gl_PrimitiveID = min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1]);
float _15 = float(gl_InvocationID);
int _18 = gl_InvocationID + 1;
float _19 = float(_18);
uint _21 = uint(gl_InvocationID);
gl_out[gl_InvocationID].in_te_data0 = te_data{ _15, _19, _21 };
threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup);
int _38 = _18 % 3;
gl_out[gl_InvocationID].in_te_data1 = te_data{ _15 + gl_out[_38].in_te_data0.a, _19 + gl_out[_38].in_te_data0.b, _21 + gl_out[_38].in_te_data0.c };
gl_out[gl_InvocationID].in_te_attr = gl_in[gl_InvocationID].in_tc_attr.x;
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[2] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[3] = half(1.0);
}

View File

@ -0,0 +1,39 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float in_te_attr;
float4x3 in_te_data0;
float4x3 in_te_data1;
};
struct main0_in
{
float3 in_tc_attr;
ushort2 m_103;
};
kernel void main0(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], device main0_out* spvOut [[buffer(28)]], constant uint* spvIndirectParams [[buffer(29)]], device MTLQuadTessellationFactorsHalf* spvTessLevel [[buffer(26)]], device main0_in* spvIn [[buffer(22)]])
{
device main0_out* gl_out = &spvOut[gl_GlobalInvocationID.x - gl_GlobalInvocationID.x % 3];
device main0_in* gl_in = &spvIn[min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1] - 1) * spvIndirectParams[0]];
uint gl_InvocationID = gl_GlobalInvocationID.x % 3;
uint gl_PrimitiveID = min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1]);
float _15 = float(gl_InvocationID);
float4x3 d = float4x3(float3(_15, 0.0, 0.0), float3(0.0, _15, 0.0), float3(0.0, 0.0, _15), float3(0.0));
gl_out[gl_InvocationID].in_te_data0 = d;
threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup);
int _42 = (gl_InvocationID + 1) % 3;
gl_out[gl_InvocationID].in_te_data1 = float4x3(d[0] + gl_out[_42].in_te_data0[0], d[1] + gl_out[_42].in_te_data0[1], d[2] + gl_out[_42].in_te_data0[2], d[3] + gl_out[_42].in_te_data0[3]);
gl_out[gl_InvocationID].in_te_attr = gl_in[gl_InvocationID].in_tc_attr.x;
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[2] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[3] = half(1.0);
}

View File

@ -0,0 +1,45 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct te_data
{
float a;
float b;
uint c;
};
struct main0_out
{
float in_te_attr;
te_data in_te_data0;
te_data in_te_data1;
};
struct main0_in
{
float3 in_tc_attr;
ushort2 m_107;
};
kernel void main0(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], device main0_out* spvOut [[buffer(28)]], constant uint* spvIndirectParams [[buffer(29)]], device MTLQuadTessellationFactorsHalf* spvTessLevel [[buffer(26)]], device main0_in* spvIn [[buffer(22)]])
{
device main0_out* gl_out = &spvOut[gl_GlobalInvocationID.x - gl_GlobalInvocationID.x % 3];
device main0_in* gl_in = &spvIn[min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1] - 1) * spvIndirectParams[0]];
uint gl_InvocationID = gl_GlobalInvocationID.x % 3;
uint gl_PrimitiveID = min(gl_GlobalInvocationID.x / 3, spvIndirectParams[1]);
te_data d = te_data{ float(gl_InvocationID), float(gl_InvocationID + 1), uint(gl_InvocationID) };
gl_out[gl_InvocationID].in_te_data0 = d;
threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup);
te_data e = gl_out[(gl_InvocationID + 1) % 3].in_te_data0;
gl_out[gl_InvocationID].in_te_data1 = te_data{ d.a + e.a, d.b + e.b, d.c + e.c };
gl_out[gl_InvocationID].in_te_attr = gl_in[gl_InvocationID].in_tc_attr.x;
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].insideTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[1] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[2] = half(1.0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[3] = half(1.0);
}

View File

@ -0,0 +1,28 @@
#version 310 es
#extension GL_EXT_tessellation_shader : require
layout(vertices = 3) out;
layout(location = 0) in highp float in_tc_attr[];
layout(location = 0) out highp float in_te_attr[];
layout(location = 1) out mediump mat4x3 in_te_data0[];
layout(location = 5) out mediump mat4x3 in_te_data1[];
void main (void)
{
mat4x3 d = mat4x3(gl_InvocationID);
in_te_data0[gl_InvocationID] = d;
barrier();
in_te_data1[gl_InvocationID] = d + in_te_data0[(gl_InvocationID + 1) % 3];
in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID];
gl_TessLevelInner[0] = 1.0;
gl_TessLevelInner[1] = 1.0;
gl_TessLevelOuter[0] = 1.0;
gl_TessLevelOuter[1] = 1.0;
gl_TessLevelOuter[2] = 1.0;
gl_TessLevelOuter[3] = 1.0;
}

View File

@ -0,0 +1,36 @@
#version 310 es
#extension GL_EXT_tessellation_shader : require
layout(vertices = 3) out;
layout(location = 0) in highp float in_tc_attr[];
layout(location = 0) out highp float in_te_attr[];
struct te_data
{
mediump float a;
mediump float b;
mediump uint c;
};
layout(location = 1) out te_data in_te_data0[];
layout(location = 4) out te_data in_te_data1[];
void main (void)
{
te_data d = te_data(float(gl_InvocationID), float(gl_InvocationID + 1), uint(gl_InvocationID));
in_te_data0[gl_InvocationID] = d;
barrier();
te_data e = in_te_data0[(gl_InvocationID + 1) % 3];
in_te_data1[gl_InvocationID] = te_data(d.a + e.a, d.b + e.b, d.c + e.c);
in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID];
gl_TessLevelInner[0] = 1.0;
gl_TessLevelInner[1] = 1.0;
gl_TessLevelOuter[0] = 1.0;
gl_TessLevelOuter[1] = 1.0;
gl_TessLevelOuter[2] = 1.0;
gl_TessLevelOuter[3] = 1.0;
}

View File

@ -5580,8 +5580,9 @@ bool CompilerMSL::emit_tessellation_io_load(uint32_t result_type_id, uint32_t id
bool multi_patch_tess_ctl = get_execution_model() == ExecutionModelTessellationControl &&
msl_options.multi_patch_workgroup && ptr_type.storage == StorageClassInput;
bool flat_matrix = is_matrix(result_type) && !multi_patch_tess_ctl;
bool flat_data_type = flat_matrix || is_array(result_type) || result_type.basetype == SPIRType::Struct;
bool flat_matrix = is_matrix(result_type) && ptr_type.storage == StorageClassInput && !multi_patch_tess_ctl;
bool flat_struct = result_type.basetype == SPIRType::Struct && ptr_type.storage == StorageClassInput;
bool flat_data_type = flat_matrix || is_array(result_type) || flat_struct;
if (!flat_data_type)
return false;
@ -5669,7 +5670,7 @@ bool CompilerMSL::emit_tessellation_io_load(uint32_t result_type_id, uint32_t id
}
expr += " })";
}
else if (result_type.basetype == SPIRType::Struct)
else if (flat_struct)
{
bool is_array_of_struct = is_array(result_type);
if (is_array_of_struct && !ptr_is_io_variable)
@ -5702,7 +5703,7 @@ bool CompilerMSL::emit_tessellation_io_load(uint32_t result_type_id, uint32_t id
const auto &mbr_type = get<SPIRType>(struct_type.member_types[j]);
const auto &expr_mbr_type = get<SPIRType>(expr_type.member_types[j]);
if (is_matrix(mbr_type) && !multi_patch_tess_ctl)
if (is_matrix(mbr_type) && ptr_type.storage == StorageClassInput && !multi_patch_tess_ctl)
{
expr += type_to_glsl(mbr_type) + "(";
for (uint32_t k = 0; k < mbr_type.columns; k++, interface_index++)