Skip to content

Commit 8d838b4

Browse files
Merge pull request #2572 from KhronosGroup/fix-2564
MSL: Fix handling of variable pointer arguments which are not BDA.
2 parents 40df537 + 99f1450 commit 8d838b4

12 files changed

+216
-40
lines changed

reference/shaders-msl-no-opt/asm/comp/storage-buffer-pointer-argument.asm.comp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ struct SSBORead
1616
};
1717

1818
static inline __attribute__((always_inline))
19-
void copy_out(device float& A, device float& B)
19+
void copy_out(device float* A, device float* B)
2020
{
21-
A = B;
21+
*A = *B;
2222
}
2323

2424
kernel void main0(device SSBO& _10 [[buffer(0)]], device SSBORead& _14 [[buffer(1)]])
2525
{
26-
copy_out(_10.a, _14.b);
26+
copy_out(&_10.a, &_14.b);
2727
}
2828

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma clang diagnostic ignored "-Wmissing-prototypes"
2+
3+
#include <metal_stdlib>
4+
#include <simd/simd.h>
5+
6+
using namespace metal;
7+
8+
struct _3
9+
{
10+
uchar _m0[1];
11+
};
12+
13+
static inline __attribute__((always_inline))
14+
void _20(device uchar* _21)
15+
{
16+
_21[2u] = uchar(0);
17+
}
18+
19+
kernel void main0(device _3& _2 [[buffer(0)]])
20+
{
21+
_20(&_2._m0[1u]);
22+
}
23+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma clang diagnostic ignored "-Wmissing-prototypes"
2+
3+
#include <metal_stdlib>
4+
#include <simd/simd.h>
5+
6+
using namespace metal;
7+
8+
struct _3
9+
{
10+
uchar _m0[16];
11+
};
12+
13+
static inline __attribute__((always_inline))
14+
void _20(device uchar (*_21)[16])
15+
{
16+
(*_21)[2u] = uchar(0);
17+
}
18+
19+
kernel void main0(device _3& _2 [[buffer(0)]])
20+
{
21+
_20(&_2._m0);
22+
}
23+

reference/shaders-msl/asm/comp/variable-pointers-2.asm.comp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ struct bar
1818
};
1919

2020
static inline __attribute__((always_inline))
21-
device foo* select_buffer(device foo& a, constant bar& cb)
21+
device foo* select_buffer(device foo* a, constant bar& cb)
2222
{
23-
return (cb.d != 0) ? &a : nullptr;
23+
return (cb.d != 0) ? a : nullptr;
2424
}
2525

2626
static inline __attribute__((always_inline))
@@ -31,7 +31,7 @@ thread uint3* select_input(thread uint3& gl_GlobalInvocationID, thread uint3& gl
3131

3232
kernel void main0(device foo& buf [[buffer(0)]], constant bar& cb [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]])
3333
{
34-
device foo* _44 = select_buffer(buf, cb);
34+
device foo* _44 = select_buffer(&buf, cb);
3535
device foo* _65 = _44;
3636
thread uint3* _45 = select_input(gl_GlobalInvocationID, gl_LocalInvocationID, cb);
3737
device foo* _66 = _65;

reference/shaders-msl/asm/comp/variable-pointers-store-forwarding.asm.comp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ struct bar
1616
};
1717

1818
static inline __attribute__((always_inline))
19-
device int* _24(device foo& a, device bar& b, thread uint3& gl_GlobalInvocationID)
19+
device int* _24(device foo* a, device bar* b, thread uint3& gl_GlobalInvocationID)
2020
{
21-
return (gl_GlobalInvocationID.x != 0u) ? &a.a : &b.b;
21+
return (gl_GlobalInvocationID.x != 0u) ? &a->a : &b->b;
2222
}
2323

2424
kernel void main0(device foo& x [[buffer(0)]], device bar& y [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]])
2525
{
26-
device int* _34 = _24(x, y, gl_GlobalInvocationID);
26+
device int* _34 = _24(&x, &y, gl_GlobalInvocationID);
2727
device int* _33 = _34;
2828
int _37 = x.a;
2929
*_33 = 0;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; SPIR-V
2+
; Version: 1.6
3+
; Generator: Khronos SPIR-V Tools Assembler; 0
4+
; Bound: 24
5+
; Schema: 0
6+
OpCapability VariablePointersStorageBuffer
7+
OpCapability Int8
8+
OpMemoryModel Logical GLSL450
9+
OpEntryPoint GLCompute %1 "main" %2
10+
OpExecutionMode %1 LocalSize 16 1 1
11+
OpDecorate %2 DescriptorSet 0
12+
OpDecorate %2 Binding 0
13+
OpDecorate %_struct_3 Block
14+
OpMemberDecorate %_struct_3 0 Offset 0
15+
OpDecorate %_runtimearr_uchar ArrayStride 1
16+
OpDecorate %_ptr_StorageBuffer_uchar ArrayStride 1
17+
%void = OpTypeVoid
18+
%uint = OpTypeInt 32 0
19+
%uint_0 = OpConstant %uint 0
20+
%uint_1 = OpConstant %uint 1
21+
%uint_2 = OpConstant %uint 2
22+
%uint_3 = OpConstant %uint 3
23+
%uchar = OpTypeInt 8 0
24+
%uchar_0 = OpConstant %uchar 0
25+
%_runtimearr_uchar = OpTypeRuntimeArray %uchar
26+
%_struct_3 = OpTypeStruct %_runtimearr_uchar
27+
%_ptr_StorageBuffer_uchar = OpTypePointer StorageBuffer %uchar
28+
%_ptr_StorageBuffer__struct_3 = OpTypePointer StorageBuffer %_struct_3
29+
%2 = OpVariable %_ptr_StorageBuffer__struct_3 StorageBuffer
30+
%15 = OpTypeFunction %void %_ptr_StorageBuffer_uchar
31+
%16 = OpTypeFunction %void
32+
%1 = OpFunction %void None %16
33+
%17 = OpLabel
34+
%18 = OpAccessChain %_ptr_StorageBuffer_uchar %2 %uint_0 %uint_1
35+
%19 = OpFunctionCall %void %20 %18
36+
OpReturn
37+
OpFunctionEnd
38+
%20 = OpFunction %void None %15
39+
%21 = OpFunctionParameter %_ptr_StorageBuffer_uchar
40+
%22 = OpLabel
41+
%23 = OpPtrAccessChain %_ptr_StorageBuffer_uchar %21 %uint_2
42+
OpStore %23 %uchar_0
43+
OpReturn
44+
OpFunctionEnd
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; SPIR-V
2+
; Version: 1.6
3+
; Generator: Khronos SPIR-V Tools Assembler; 0
4+
; Bound: 24
5+
; Schema: 0
6+
OpCapability VariablePointersStorageBuffer
7+
OpCapability Int8
8+
OpMemoryModel Logical GLSL450
9+
OpEntryPoint GLCompute %1 "main" %2
10+
OpExecutionMode %1 LocalSize 16 1 1
11+
OpDecorate %2 DescriptorSet 0
12+
OpDecorate %2 Binding 0
13+
OpDecorate %_struct_3 Block
14+
OpMemberDecorate %_struct_3 0 Offset 0
15+
OpDecorate %uchar_array ArrayStride 1
16+
%void = OpTypeVoid
17+
%uint = OpTypeInt 32 0
18+
%uint_0 = OpConstant %uint 0
19+
%uint_1 = OpConstant %uint 1
20+
%uint_2 = OpConstant %uint 2
21+
%uint_3 = OpConstant %uint 3
22+
%uint_16 = OpConstant %uint 16
23+
%uchar = OpTypeInt 8 0
24+
%uchar_0 = OpConstant %uchar 0
25+
%uchar_array = OpTypeArray %uchar %uint_16
26+
%_struct_3 = OpTypeStruct %uchar_array
27+
%_ptr_StorageBuffer_uchar = OpTypePointer StorageBuffer %uchar
28+
%_ptr_StorageBuffer_uchar_array = OpTypePointer StorageBuffer %uchar_array
29+
%_ptr_StorageBuffer__struct_3 = OpTypePointer StorageBuffer %_struct_3
30+
%2 = OpVariable %_ptr_StorageBuffer__struct_3 StorageBuffer
31+
%15 = OpTypeFunction %void %_ptr_StorageBuffer_uchar_array
32+
%16 = OpTypeFunction %void
33+
%1 = OpFunction %void None %16
34+
%17 = OpLabel
35+
%18 = OpAccessChain %_ptr_StorageBuffer_uchar_array %2 %uint_0
36+
%19 = OpFunctionCall %void %20 %18
37+
OpReturn
38+
OpFunctionEnd
39+
%20 = OpFunction %void None %15
40+
%21 = OpFunctionParameter %_ptr_StorageBuffer_uchar_array
41+
%22 = OpLabel
42+
%23 = OpAccessChain %_ptr_StorageBuffer_uchar %21 %uint_2
43+
OpStore %23 %uchar_0
44+
OpReturn
45+
OpFunctionEnd

spirv_cross.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,14 @@ bool Compiler::is_physical_pointer(const SPIRType &type) const
742742
return type.op == OpTypePointer && type.storage == StorageClassPhysicalStorageBuffer;
743743
}
744744

745+
bool Compiler::is_physical_or_buffer_pointer(const SPIRType &type) const
746+
{
747+
return type.op == OpTypePointer &&
748+
(type.storage == StorageClassPhysicalStorageBuffer || type.storage == StorageClassUniform ||
749+
type.storage == StorageClassStorageBuffer || type.storage == StorageClassWorkgroup ||
750+
type.storage == StorageClassPushConstant);
751+
}
752+
745753
bool Compiler::is_physical_pointer_to_buffer_block(const SPIRType &type) const
746754
{
747755
return is_physical_pointer(type) && get_pointee_type(type).self == type.parent_type &&

spirv_cross.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ class Compiler
694694
bool is_array(const SPIRType &type) const;
695695
bool is_pointer(const SPIRType &type) const;
696696
bool is_physical_pointer(const SPIRType &type) const;
697+
bool is_physical_or_buffer_pointer(const SPIRType &type) const;
697698
bool is_physical_pointer_to_buffer_block(const SPIRType &type) const;
698699
static bool is_runtime_size_array(const SPIRType &type);
699700
uint32_t expression_type_id(uint32_t id) const;

spirv_glsl.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5051,10 +5051,10 @@ void CompilerGLSL::emit_polyfills(uint32_t polyfills, bool relaxed)
50515051
// Returns a string representation of the ID, usable as a function arg.
50525052
// Default is to simply return the expression representation fo the arg ID.
50535053
// Subclasses may override to modify the return value.
5054-
string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &, uint32_t id)
5054+
string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id)
50555055
{
50565056
// BDA expects pointers through function interface.
5057-
if (is_physical_pointer(expression_type(id)))
5057+
if (!arg.alias_global_variable && is_physical_or_buffer_pointer(expression_type(id)))
50585058
return to_pointer_expression(id);
50595059

50605060
// Make sure that we use the name of the original variable, and not the parameter alias.
@@ -11581,7 +11581,7 @@ bool CompilerGLSL::should_dereference(uint32_t id)
1158111581
// If id is a variable but not a phi variable, we should not dereference it.
1158211582
// BDA passed around as parameters are always pointers.
1158311583
if (auto *var = maybe_get<SPIRVariable>(id))
11584-
return (var->parameter && is_physical_pointer(type)) || var->phi_variable;
11584+
return (var->parameter && is_physical_or_buffer_pointer(type)) || var->phi_variable;
1158511585

1158611586
if (auto *expr = maybe_get<SPIRExpression>(id))
1158711587
{
@@ -11617,8 +11617,8 @@ bool CompilerGLSL::should_dereference(uint32_t id)
1161711617
bool CompilerGLSL::should_dereference_caller_param(uint32_t id)
1161811618
{
1161911619
const auto &type = expression_type(id);
11620-
// BDA is always passed around as pointers.
11621-
if (is_physical_pointer(type))
11620+
// BDA is always passed around as pointers. Similarly, we need to pass variable buffer pointers as pointers.
11621+
if (is_physical_or_buffer_pointer(type))
1162211622
return false;
1162311623

1162411624
return should_dereference(id);

0 commit comments

Comments
 (0)