MSL: Handle aliased variable names for resources placed in IB struct.
Just remember to register the names.
This commit is contained in:
parent
213c5f42ea
commit
1ec9d018fd
@ -0,0 +1,105 @@
|
|||||||
|
#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 Foo
|
||||||
|
{
|
||||||
|
float a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float4 FragColor [[color(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_in
|
||||||
|
{
|
||||||
|
float ALIAS_0_a [[user(locn1)]];
|
||||||
|
float ALIAS_0_b [[user(locn2)]];
|
||||||
|
float ALIAS_1_a [[user(locn3)]];
|
||||||
|
float ALIAS_1_b [[user(locn4)]];
|
||||||
|
float ALIAS_2_a [[user(locn5)]];
|
||||||
|
float ALIAS_2_b [[user(locn6)]];
|
||||||
|
float ALIAS_3_a [[user(locn7)]];
|
||||||
|
float ALIAS_3_b [[user(locn8)]];
|
||||||
|
float ALIAS_1_0_a [[user(locn10)]];
|
||||||
|
float ALIAS_1_0_b [[user(locn11)]];
|
||||||
|
float ALIAS_1_1_a [[user(locn12)]];
|
||||||
|
float ALIAS_1_1_b [[user(locn13)]];
|
||||||
|
float ALIAS_1_2_a [[user(locn14)]];
|
||||||
|
float ALIAS_1_2_b [[user(locn15)]];
|
||||||
|
float ALIAS_1_3_a [[user(locn16)]];
|
||||||
|
float ALIAS_1_3_b [[user(locn17)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment main0_out main0(main0_in in [[stage_in]])
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
spvUnsafeArray<Foo, 4> ALIAS = {};
|
||||||
|
spvUnsafeArray<Foo, 4> ALIAS_1 = {};
|
||||||
|
ALIAS[0].a = in.ALIAS_0_a;
|
||||||
|
ALIAS[0].b = in.ALIAS_0_b;
|
||||||
|
ALIAS[1].a = in.ALIAS_1_a;
|
||||||
|
ALIAS[1].b = in.ALIAS_1_b;
|
||||||
|
ALIAS[2].a = in.ALIAS_2_a;
|
||||||
|
ALIAS[2].b = in.ALIAS_2_b;
|
||||||
|
ALIAS[3].a = in.ALIAS_3_a;
|
||||||
|
ALIAS[3].b = in.ALIAS_3_b;
|
||||||
|
ALIAS_1[0].a = in.ALIAS_1_0_a;
|
||||||
|
ALIAS_1[0].b = in.ALIAS_1_0_b;
|
||||||
|
ALIAS_1[1].a = in.ALIAS_1_1_a;
|
||||||
|
ALIAS_1[1].b = in.ALIAS_1_1_b;
|
||||||
|
ALIAS_1[2].a = in.ALIAS_1_2_a;
|
||||||
|
ALIAS_1[2].b = in.ALIAS_1_2_b;
|
||||||
|
ALIAS_1[3].a = in.ALIAS_1_3_a;
|
||||||
|
ALIAS_1[3].b = in.ALIAS_1_3_b;
|
||||||
|
out.FragColor.x = ALIAS[0].a;
|
||||||
|
out.FragColor.y = ALIAS[1].b;
|
||||||
|
out.FragColor.z = ALIAS[2].a;
|
||||||
|
out.FragColor.w = ALIAS_1[3].b;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
|||||||
|
; SPIR-V
|
||||||
|
; Version: 1.0
|
||||||
|
; Generator: Khronos Glslang Reference Front End; 10
|
||||||
|
; Bound: 40
|
||||||
|
; Schema: 0
|
||||||
|
OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %main "main" %FragColor %foos %bars
|
||||||
|
OpExecutionMode %main OriginUpperLeft
|
||||||
|
OpSource GLSL 450
|
||||||
|
OpName %main "main"
|
||||||
|
OpName %FragColor "FragColor"
|
||||||
|
OpName %Foo "Foo"
|
||||||
|
OpMemberName %Foo 0 "a"
|
||||||
|
OpMemberName %Foo 1 "b"
|
||||||
|
OpName %foos "ALIAS"
|
||||||
|
OpName %bars "ALIAS"
|
||||||
|
OpDecorate %FragColor Location 0
|
||||||
|
OpDecorate %foos Location 1
|
||||||
|
OpDecorate %bars Location 10
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%3 = OpTypeFunction %void
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%v4float = OpTypeVector %float 4
|
||||||
|
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||||
|
%FragColor = OpVariable %_ptr_Output_v4float Output
|
||||||
|
%Foo = OpTypeStruct %float %float
|
||||||
|
%uint = OpTypeInt 32 0
|
||||||
|
%uint_4 = OpConstant %uint 4
|
||||||
|
%_arr_Foo_uint_4 = OpTypeArray %Foo %uint_4
|
||||||
|
%_ptr_Input__arr_Foo_uint_4 = OpTypePointer Input %_arr_Foo_uint_4
|
||||||
|
%foos = OpVariable %_ptr_Input__arr_Foo_uint_4 Input
|
||||||
|
%int = OpTypeInt 32 1
|
||||||
|
%int_0 = OpConstant %int 0
|
||||||
|
%_ptr_Input_float = OpTypePointer Input %float
|
||||||
|
%uint_0 = OpConstant %uint 0
|
||||||
|
%_ptr_Output_float = OpTypePointer Output %float
|
||||||
|
%int_1 = OpConstant %int 1
|
||||||
|
%uint_1 = OpConstant %uint 1
|
||||||
|
%int_2 = OpConstant %int 2
|
||||||
|
%uint_2 = OpConstant %uint 2
|
||||||
|
%bars = OpVariable %_ptr_Input__arr_Foo_uint_4 Input
|
||||||
|
%int_3 = OpConstant %int 3
|
||||||
|
%uint_3 = OpConstant %uint 3
|
||||||
|
%main = OpFunction %void None %3
|
||||||
|
%5 = OpLabel
|
||||||
|
%19 = OpAccessChain %_ptr_Input_float %foos %int_0 %int_0
|
||||||
|
%20 = OpLoad %float %19
|
||||||
|
%23 = OpAccessChain %_ptr_Output_float %FragColor %uint_0
|
||||||
|
OpStore %23 %20
|
||||||
|
%25 = OpAccessChain %_ptr_Input_float %foos %int_1 %int_1
|
||||||
|
%26 = OpLoad %float %25
|
||||||
|
%28 = OpAccessChain %_ptr_Output_float %FragColor %uint_1
|
||||||
|
OpStore %28 %26
|
||||||
|
%30 = OpAccessChain %_ptr_Input_float %foos %int_2 %int_0
|
||||||
|
%31 = OpLoad %float %30
|
||||||
|
%33 = OpAccessChain %_ptr_Output_float %FragColor %uint_2
|
||||||
|
OpStore %33 %31
|
||||||
|
%36 = OpAccessChain %_ptr_Input_float %bars %int_3 %int_1
|
||||||
|
%37 = OpLoad %float %36
|
||||||
|
%39 = OpAccessChain %_ptr_Output_float %FragColor %uint_3
|
||||||
|
OpStore %39 %37
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
@ -3132,6 +3132,14 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If variable names alias, they will end up with wrong names in the interface struct, because
|
||||||
|
// there might be aliases in the member name cache and there would be a mismatch in fixup_in code.
|
||||||
|
// Make sure to register the variables as unique resource names ahead of time.
|
||||||
|
// This would normally conflict with the name cache when emitting local variables,
|
||||||
|
// but this happens in the setup stage, before we hit compilation loops.
|
||||||
|
// The name cache is cleared before we actually emit code, so this is safe.
|
||||||
|
add_resource_name(var.self);
|
||||||
|
|
||||||
if (var_type.basetype == SPIRType::Struct)
|
if (var_type.basetype == SPIRType::Struct)
|
||||||
{
|
{
|
||||||
bool block_requires_flattening = variable_storage_requires_stage_io(storage) || is_block;
|
bool block_requires_flattening = variable_storage_requires_stage_io(storage) || is_block;
|
||||||
|
Loading…
Reference in New Issue
Block a user