diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-08-09 14:48:28 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-08-09 14:49:40 +0300 |
commit | bc3987e59ab7a6881ad0782d49e70756c3f57a14 (patch) | |
tree | 6478fe2113fdcad37048faf9201b44b2dff3900d | |
parent | c084973c67aca615e3f24f04bfa29f735f5e97dc (diff) |
MSL: Fix various bugs with Ptr/U bitcasts.
7 files changed, 320 insertions, 26 deletions
diff --git a/reference/opt/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp b/reference/opt/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp index f2ba5416..fb561482 100644 --- a/reference/opt/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp +++ b/reference/opt/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp @@ -18,10 +18,10 @@ struct SSBO kernel void main0(constant UBO& _10 [[buffer(0)]]) { - ((device SSBO*)as_type<uint64_t>(_10.b))->a1 = float3(1.0, 2.0, 3.0); - uint2 _35 = as_type<uint2>((uint64_t)((device SSBO*)as_type<uint64_t>(_10.b + uint2(32u)))); + (reinterpret_cast<device SSBO*>(as_type<ulong>(_10.b)))->a1 = float3(1.0, 2.0, 3.0); + uint2 _35 = as_type<uint2>(reinterpret_cast<ulong>(reinterpret_cast<device SSBO*>(as_type<ulong>(_10.b + uint2(32u))))); uint2 v2 = _35; - device SSBO* _39 = ((device SSBO*)as_type<uint64_t>(_35)); + device SSBO* _39 = reinterpret_cast<device SSBO*>(as_type<ulong>(_35)); float3 v3 = float3(_39->a1); _39->a1 = float3(_39->a1) + float3(1.0); } diff --git a/reference/shaders-msl-no-opt/asm/comp/buffer-device-address-ptr-casting.msl24.asm.comp b/reference/shaders-msl-no-opt/asm/comp/buffer-device-address-ptr-casting.msl24.asm.comp new file mode 100644 index 00000000..74464092 --- /dev/null +++ b/reference/shaders-msl-no-opt/asm/comp/buffer-device-address-ptr-casting.msl24.asm.comp @@ -0,0 +1,33 @@ +#include <metal_stdlib> +#include <simd/simd.h> + +using namespace metal; + +struct SomeBuffer; + +struct SomeBuffer +{ + float4 v; + ulong a; + uint2 b; +}; + +struct Registers +{ + ulong address; + uint2 address2; +}; + +kernel void main0(constant Registers& registers [[buffer(0)]]) +{ + device SomeBuffer* _44 = reinterpret_cast<device SomeBuffer*>(registers.address); + device SomeBuffer* _45 = reinterpret_cast<device SomeBuffer*>(registers.address); + device SomeBuffer* _46 = reinterpret_cast<device SomeBuffer*>(as_type<ulong>(registers.address2)); + _44->v = float4(1.0, 2.0, 3.0, 4.0); + _45->v = float4(1.0, 2.0, 3.0, 4.0); + _46->v = float4(1.0, 2.0, 3.0, 4.0); + _44->a = reinterpret_cast<ulong>(_44); + _45->a = reinterpret_cast<ulong>(_45); + _46->b = as_type<uint2>(reinterpret_cast<ulong>(_46)); +} + diff --git a/reference/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp b/reference/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp index 474d5092..f79a8b52 100644 --- a/reference/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp +++ b/reference/shaders-msl/comp/buffer_device_address-packed-vec-and-cast-to-and-from-uvec2.msl23.comp @@ -18,9 +18,9 @@ struct SSBO kernel void main0(constant UBO& _10 [[buffer(0)]]) { - ((device SSBO*)as_type<uint64_t>(_10.b))->a1 = float3(1.0, 2.0, 3.0); - uint2 v2 = as_type<uint2>((uint64_t)((device SSBO*)as_type<uint64_t>(_10.b + uint2(32u)))); - float3 v3 = float3(((device SSBO*)as_type<uint64_t>(v2))->a1); - ((device SSBO*)as_type<uint64_t>(v2))->a1 = v3 + float3(1.0); + (reinterpret_cast<device SSBO*>(as_type<ulong>(_10.b)))->a1 = float3(1.0, 2.0, 3.0); + uint2 v2 = as_type<uint2>(reinterpret_cast<ulong>(reinterpret_cast<device SSBO*>(as_type<ulong>(_10.b + uint2(32u))))); + float3 v3 = float3((reinterpret_cast<device SSBO*>(as_type<ulong>(v2)))->a1); + (reinterpret_cast<device SSBO*>(as_type<ulong>(v2)))->a1 = v3 + float3(1.0); } diff --git a/reference/shaders-no-opt/asm/comp/buffer-device-address-ptr-casting.vk.nocompat.asm.comp.vk b/reference/shaders-no-opt/asm/comp/buffer-device-address-ptr-casting.vk.nocompat.asm.comp.vk new file mode 100644 index 00000000..f082267f --- /dev/null +++ b/reference/shaders-no-opt/asm/comp/buffer-device-address-ptr-casting.vk.nocompat.asm.comp.vk @@ -0,0 +1,37 @@ +#version 450 +#if defined(GL_ARB_gpu_shader_int64) +#extension GL_ARB_gpu_shader_int64 : require +#else +#error No extension available for 64-bit integers. +#endif +#extension GL_EXT_buffer_reference : require +#extension GL_EXT_buffer_reference_uvec2 : require +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +layout(buffer_reference) buffer SomeBuffer; +layout(buffer_reference, buffer_reference_align = 16, std430) buffer SomeBuffer +{ + vec4 v; + uint64_t a; + uvec2 b; +}; + +layout(push_constant, std430) uniform Registers +{ + uint64_t address; + uvec2 address2; +} registers; + +void main() +{ + SomeBuffer _44 = SomeBuffer(registers.address); + SomeBuffer _45 = SomeBuffer(registers.address); + SomeBuffer _46 = SomeBuffer(registers.address2); + _44.v = vec4(1.0, 2.0, 3.0, 4.0); + _45.v = vec4(1.0, 2.0, 3.0, 4.0); + _46.v = vec4(1.0, 2.0, 3.0, 4.0); + _44.a = uint64_t(_44); + _45.a = uint64_t(_45); + _46.b = uvec2(_46); +} + diff --git a/shaders-msl-no-opt/asm/comp/buffer-device-address-ptr-casting.msl24.asm.comp b/shaders-msl-no-opt/asm/comp/buffer-device-address-ptr-casting.msl24.asm.comp new file mode 100644 index 00000000..ed8d0ba6 --- /dev/null +++ b/shaders-msl-no-opt/asm/comp/buffer-device-address-ptr-casting.msl24.asm.comp @@ -0,0 +1,106 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 10 +; Bound: 62 +; Schema: 0 + OpCapability Shader + OpCapability Int64 + OpCapability PhysicalStorageBufferAddresses + OpExtension "SPV_KHR_physical_storage_buffer" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel PhysicalStorageBuffer64 GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 1 1 1 + OpSource GLSL 450 + OpSourceExtension "GL_ARB_gpu_shader_int64" + OpSourceExtension "GL_EXT_buffer_reference" + OpSourceExtension "GL_EXT_buffer_reference_uvec2" + OpName %main "main" + OpName %SomeBuffer "SomeBuffer" + OpMemberName %SomeBuffer 0 "v" + OpMemberName %SomeBuffer 1 "a" + OpMemberName %SomeBuffer 2 "b" + OpName %Registers "Registers" + OpMemberName %Registers 0 "address" + OpMemberName %Registers 1 "address2" + OpName %registers "registers" + OpName %a "a" + OpName %b "b" + OpMemberDecorate %SomeBuffer 0 Offset 0 + OpMemberDecorate %SomeBuffer 1 Offset 16 + OpMemberDecorate %SomeBuffer 2 Offset 24 + OpDecorate %SomeBuffer Block + OpMemberDecorate %Registers 0 Offset 0 + OpMemberDecorate %Registers 1 Offset 8 + OpDecorate %Registers Block + %void = OpTypeVoid + %3 = OpTypeFunction %void + OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_SomeBuffer PhysicalStorageBuffer + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %ulong = OpTypeInt 64 0 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %SomeBuffer = OpTypeStruct %v4float %ulong %v2uint +%_ptr_PhysicalStorageBuffer_SomeBuffer = OpTypePointer PhysicalStorageBuffer %SomeBuffer +%_ptr_Function__ptr_PhysicalStorageBuffer_SomeBuffer = OpTypePointer Function %_ptr_PhysicalStorageBuffer_SomeBuffer + %Registers = OpTypeStruct %ulong %v2uint +%_ptr_PushConstant_Registers = OpTypePointer PushConstant %Registers + %registers = OpVariable %_ptr_PushConstant_Registers PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_ulong = OpTypePointer PushConstant %ulong + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %float_1 = OpConstant %float 1 + %float_2 = OpConstant %float 2 + %float_3 = OpConstant %float 3 + %float_4 = OpConstant %float 4 + %35 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4 +%_ptr_PhysicalStorageBuffer_v4float = OpTypePointer PhysicalStorageBuffer %v4float + %float_5 = OpConstant %float 5 + %float_6 = OpConstant %float 6 + %float_7 = OpConstant %float 7 + %float_8 = OpConstant %float 8 + %43 = OpConstantComposite %v4float %float_5 %float_6 %float_7 %float_8 +%_ptr_Function_ulong = OpTypePointer Function %ulong +%_ptr_Function_v2uint = OpTypePointer Function %v2uint +%_ptr_PhysicalStorageBuffer_ulong = OpTypePointer PhysicalStorageBuffer %ulong + %int_2 = OpConstant %int 2 +%_ptr_PhysicalStorageBuffer_v2uint = OpTypePointer PhysicalStorageBuffer %v2uint + %main = OpFunction %void None %3 + %5 = OpLabel + %a = OpVariable %_ptr_Function_ulong Function + %b = OpVariable %_ptr_Function_v2uint Function + %21 = OpAccessChain %_ptr_PushConstant_ulong %registers %int_0 + %27 = OpAccessChain %_ptr_PushConstant_v2uint %registers %int_1 + %uint_ptr0 = OpLoad %ulong %21 + %uint_ptr1 = OpLoad %v2uint %27 + + ; ConvertUToPtr and vice versa do not accept vectors. + %ulong_ptr0 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_SomeBuffer %uint_ptr0 + %ulong_ptr1 = OpBitcast %_ptr_PhysicalStorageBuffer_SomeBuffer %uint_ptr0 + %uvec2_ptr0 = OpBitcast %_ptr_PhysicalStorageBuffer_SomeBuffer %uint_ptr1 + + %vec4_write0 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %ulong_ptr0 %int_0 + %vec4_write1 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %ulong_ptr1 %int_0 + %vec4_write2 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %uvec2_ptr0 %int_0 + + OpStore %vec4_write0 %35 Aligned 16 + OpStore %vec4_write1 %35 Aligned 16 + OpStore %vec4_write2 %35 Aligned 16 + + %ulong_from_ptr0 = OpConvertPtrToU %ulong %ulong_ptr0 + %ulong_from_ptr1 = OpBitcast %ulong %ulong_ptr1 + %uvec2_from_ptr0 = OpBitcast %v2uint %uvec2_ptr0 + + %ptr0 = OpAccessChain %_ptr_PhysicalStorageBuffer_ulong %ulong_ptr0 %int_1 + %ptr1 = OpAccessChain %_ptr_PhysicalStorageBuffer_ulong %ulong_ptr1 %int_1 + %ptr2 = OpAccessChain %_ptr_PhysicalStorageBuffer_v2uint %uvec2_ptr0 %int_2 + + OpStore %ptr0 %ulong_from_ptr0 Aligned 8 + OpStore %ptr1 %ulong_from_ptr1 Aligned 8 + OpStore %ptr2 %uvec2_from_ptr0 Aligned 8 + + OpReturn + OpFunctionEnd diff --git a/shaders-no-opt/asm/comp/buffer-device-address-ptr-casting.vk.nocompat.asm.comp b/shaders-no-opt/asm/comp/buffer-device-address-ptr-casting.vk.nocompat.asm.comp new file mode 100644 index 00000000..ed8d0ba6 --- /dev/null +++ b/shaders-no-opt/asm/comp/buffer-device-address-ptr-casting.vk.nocompat.asm.comp @@ -0,0 +1,106 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 10 +; Bound: 62 +; Schema: 0 + OpCapability Shader + OpCapability Int64 + OpCapability PhysicalStorageBufferAddresses + OpExtension "SPV_KHR_physical_storage_buffer" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel PhysicalStorageBuffer64 GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main LocalSize 1 1 1 + OpSource GLSL 450 + OpSourceExtension "GL_ARB_gpu_shader_int64" + OpSourceExtension "GL_EXT_buffer_reference" + OpSourceExtension "GL_EXT_buffer_reference_uvec2" + OpName %main "main" + OpName %SomeBuffer "SomeBuffer" + OpMemberName %SomeBuffer 0 "v" + OpMemberName %SomeBuffer 1 "a" + OpMemberName %SomeBuffer 2 "b" + OpName %Registers "Registers" + OpMemberName %Registers 0 "address" + OpMemberName %Registers 1 "address2" + OpName %registers "registers" + OpName %a "a" + OpName %b "b" + OpMemberDecorate %SomeBuffer 0 Offset 0 + OpMemberDecorate %SomeBuffer 1 Offset 16 + OpMemberDecorate %SomeBuffer 2 Offset 24 + OpDecorate %SomeBuffer Block + OpMemberDecorate %Registers 0 Offset 0 + OpMemberDecorate %Registers 1 Offset 8 + OpDecorate %Registers Block + %void = OpTypeVoid + %3 = OpTypeFunction %void + OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_SomeBuffer PhysicalStorageBuffer + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %ulong = OpTypeInt 64 0 + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 + %SomeBuffer = OpTypeStruct %v4float %ulong %v2uint +%_ptr_PhysicalStorageBuffer_SomeBuffer = OpTypePointer PhysicalStorageBuffer %SomeBuffer +%_ptr_Function__ptr_PhysicalStorageBuffer_SomeBuffer = OpTypePointer Function %_ptr_PhysicalStorageBuffer_SomeBuffer + %Registers = OpTypeStruct %ulong %v2uint +%_ptr_PushConstant_Registers = OpTypePointer PushConstant %Registers + %registers = OpVariable %_ptr_PushConstant_Registers PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_PushConstant_ulong = OpTypePointer PushConstant %ulong + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_v2uint = OpTypePointer PushConstant %v2uint + %float_1 = OpConstant %float 1 + %float_2 = OpConstant %float 2 + %float_3 = OpConstant %float 3 + %float_4 = OpConstant %float 4 + %35 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4 +%_ptr_PhysicalStorageBuffer_v4float = OpTypePointer PhysicalStorageBuffer %v4float + %float_5 = OpConstant %float 5 + %float_6 = OpConstant %float 6 + %float_7 = OpConstant %float 7 + %float_8 = OpConstant %float 8 + %43 = OpConstantComposite %v4float %float_5 %float_6 %float_7 %float_8 +%_ptr_Function_ulong = OpTypePointer Function %ulong +%_ptr_Function_v2uint = OpTypePointer Function %v2uint +%_ptr_PhysicalStorageBuffer_ulong = OpTypePointer PhysicalStorageBuffer %ulong + %int_2 = OpConstant %int 2 +%_ptr_PhysicalStorageBuffer_v2uint = OpTypePointer PhysicalStorageBuffer %v2uint + %main = OpFunction %void None %3 + %5 = OpLabel + %a = OpVariable %_ptr_Function_ulong Function + %b = OpVariable %_ptr_Function_v2uint Function + %21 = OpAccessChain %_ptr_PushConstant_ulong %registers %int_0 + %27 = OpAccessChain %_ptr_PushConstant_v2uint %registers %int_1 + %uint_ptr0 = OpLoad %ulong %21 + %uint_ptr1 = OpLoad %v2uint %27 + + ; ConvertUToPtr and vice versa do not accept vectors. + %ulong_ptr0 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_SomeBuffer %uint_ptr0 + %ulong_ptr1 = OpBitcast %_ptr_PhysicalStorageBuffer_SomeBuffer %uint_ptr0 + %uvec2_ptr0 = OpBitcast %_ptr_PhysicalStorageBuffer_SomeBuffer %uint_ptr1 + + %vec4_write0 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %ulong_ptr0 %int_0 + %vec4_write1 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %ulong_ptr1 %int_0 + %vec4_write2 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %uvec2_ptr0 %int_0 + + OpStore %vec4_write0 %35 Aligned 16 + OpStore %vec4_write1 %35 Aligned 16 + OpStore %vec4_write2 %35 Aligned 16 + + %ulong_from_ptr0 = OpConvertPtrToU %ulong %ulong_ptr0 + %ulong_from_ptr1 = OpBitcast %ulong %ulong_ptr1 + %uvec2_from_ptr0 = OpBitcast %v2uint %uvec2_ptr0 + + %ptr0 = OpAccessChain %_ptr_PhysicalStorageBuffer_ulong %ulong_ptr0 %int_1 + %ptr1 = OpAccessChain %_ptr_PhysicalStorageBuffer_ulong %ulong_ptr1 %int_1 + %ptr2 = OpAccessChain %_ptr_PhysicalStorageBuffer_v2uint %uvec2_ptr0 %int_2 + + OpStore %ptr0 %ulong_from_ptr0 Aligned 8 + OpStore %ptr1 %ulong_from_ptr1 Aligned 8 + OpStore %ptr2 %uvec2_from_ptr0 Aligned 8 + + OpReturn + OpFunctionEnd diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 09a063b2..583a9232 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -8851,6 +8851,34 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) #undef MSL_RAY_QUERY_IS_OP2 #undef MSL_RAY_QUERY_GET_OP2 #undef MSL_RAY_QUERY_OP_INNER2 + + case OpConvertPtrToU: + case OpConvertUToPtr: + case OpBitcast: + { + auto &type = get<SPIRType>(ops[0]); + auto &input_type = expression_type(ops[2]); + + if (opcode != OpBitcast || type.pointer || input_type.pointer) + { + string op; + + if (type.vecsize == 1 && input_type.vecsize == 1) + op = join("reinterpret_cast<", type_to_glsl(type), ">(", to_unpacked_expression(ops[2]), ")"); + else if (input_type.vecsize == 2) + op = join("reinterpret_cast<", type_to_glsl(type), ">(as_type<ulong>(", to_unpacked_expression(ops[2]), "))"); + else + op = join("as_type<", type_to_glsl(type), ">(reinterpret_cast<ulong>(", to_unpacked_expression(ops[2]), "))"); + + emit_op(ops[0], ops[1], op, should_forward(ops[2])); + inherit_expression_dependencies(ops[1], ops[2]); + } + else + CompilerGLSL::emit_instruction(instruction); + + break; + } + default: CompilerGLSL::emit_instruction(instruction); break; @@ -14590,26 +14618,10 @@ string CompilerMSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in return type_to_glsl(out_type); } -bool CompilerMSL::emit_complex_bitcast(uint32_t result_type, uint32_t id, uint32_t op0) +bool CompilerMSL::emit_complex_bitcast(uint32_t, uint32_t, uint32_t) { - auto &out_type = get<SPIRType>(result_type); - auto &in_type = expression_type(op0); - bool uvec2_to_ptr = (in_type.basetype == SPIRType::UInt && in_type.vecsize == 2 && - out_type.pointer && out_type.storage == StorageClassPhysicalStorageBuffer); - bool ptr_to_uvec2 = (in_type.pointer && in_type.storage == StorageClassPhysicalStorageBuffer && - out_type.basetype == SPIRType::UInt && out_type.vecsize == 2); - string expr; - - // Casting between uvec2 and buffer storage pointer per GL_EXT_buffer_reference_uvec2 - if (uvec2_to_ptr) - expr = join("((", type_to_glsl(out_type), ")as_type<uint64_t>(", to_unpacked_expression(op0), "))"); - else if (ptr_to_uvec2) - expr = join("as_type<", type_to_glsl(out_type), ">((uint64_t)", to_unpacked_expression(op0), ")"); - else - return false; - - emit_op(result_type, id, expr, should_forward(op0)); - return true; + // This is handled from the outside where we deal with PtrToU/UToPtr and friends. + return false; } // Returns an MSL string identifying the name of a SPIR-V builtin. |