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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
bool block_requires_flattening = variable_storage_requires_stage_io(storage) || is_block;
|
||||
|
Loading…
Reference in New Issue
Block a user