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:
commit
82d1c43e40
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
39
reference/shaders-msl/tesc/matrix-output.multi-patch.tesc
Normal file
39
reference/shaders-msl/tesc/matrix-output.multi-patch.tesc
Normal 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);
|
||||
}
|
||||
|
45
reference/shaders-msl/tesc/struct-output.multi-patch.tesc
Normal file
45
reference/shaders-msl/tesc/struct-output.multi-patch.tesc
Normal 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);
|
||||
}
|
||||
|
28
shaders-msl/tesc/matrix-output.multi-patch.tesc
Normal file
28
shaders-msl/tesc/matrix-output.multi-patch.tesc
Normal 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;
|
||||
}
|
36
shaders-msl/tesc/struct-output.multi-patch.tesc
Normal file
36
shaders-msl/tesc/struct-output.multi-patch.tesc
Normal 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;
|
||||
}
|
@ -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++)
|
||||
|
Loading…
Reference in New Issue
Block a user