Skip to content

Commit

Permalink
MSL: Treat pointer to vector as scalar type when bitcasting
Browse files Browse the repository at this point in the history
Otherwise, they will be misregarded as vectors and can be used in
as_type, which does not support pointer type as destination.
  • Loading branch information
dboyan committed Mar 4, 2025
1 parent 2c32b6b commit 764abd5
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

template<typename T>
struct spvDescriptor
{
T value;
};

template<typename T>
struct spvDescriptorArray
{
spvDescriptorArray(const device spvDescriptor<T>* ptr) : ptr(&ptr->value)
{
}
const device T& operator [] (size_t i) const
{
return ptr[i];
}
const device T* ptr;
};

struct type_ConstantBuffer_PushConstants
{
ulong VertexShaderConstants;
ulong PixelShaderConstants;
ulong SharedConstants;
};

struct main0_out
{
float4 out_var_SV_Target [[color(0)]];
};

fragment main0_out main0(constant type_ConstantBuffer_PushConstants& g_PushConstants [[buffer(0)]], const device spvDescriptor<texture2d<float>>* g_Texture2DDescriptorHeap_ [[buffer(1)]], float4 gl_FragCoord [[position]])
{
spvDescriptorArray<texture2d<float>> g_Texture2DDescriptorHeap {g_Texture2DDescriptorHeap_};

main0_out out = {};
int2 _55 = int2(gl_FragCoord.xy) - (*(reinterpret_cast<device int2*>(g_PushConstants.SharedConstants + 16ul)));
bool _66;
if (!any(_55 < int2(0)))
{
_66 = any(_55 >= (*(reinterpret_cast<device int2*>(g_PushConstants.SharedConstants + 24ul))));
}
else
{
_66 = true;
}
float4 _77;
if (_66)
{
_77 = float4(0.0);
}
else
{
_77 = g_Texture2DDescriptorHeap[*(reinterpret_cast<device uint*>(g_PushConstants.SharedConstants + 12ul))].read(uint2(int3(select(_55, int2(0), bool2(_66)), 0).xy), 0);
}
float3 _81 = powr(_77.xyz, *(reinterpret_cast<device float3*>(g_PushConstants.SharedConstants)));
out.out_var_SV_Target = float4(_81.x, _81.y, _81.z, _77.w);
return out;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

template<typename T>
struct spvDescriptor
{
T value;
};

template<typename T>
struct spvDescriptorArray
{
spvDescriptorArray(const device spvDescriptor<T>* ptr) : ptr(&ptr->value)
{
}
const device T& operator [] (size_t i) const
{
return ptr[i];
}
const device T* ptr;
};

struct type_ConstantBuffer_PushConstants
{
ulong VertexShaderConstants;
ulong PixelShaderConstants;
ulong SharedConstants;
};

struct main0_out
{
float4 out_var_SV_Target [[color(0)]];
};

fragment main0_out main0(constant type_ConstantBuffer_PushConstants& g_PushConstants [[buffer(0)]], const device spvDescriptor<texture2d<float>>* g_Texture2DDescriptorHeap_ [[buffer(1)]], float4 gl_FragCoord [[position]])
{
spvDescriptorArray<texture2d<float>> g_Texture2DDescriptorHeap {g_Texture2DDescriptorHeap_};

main0_out out = {};
int2 _55 = int2(gl_FragCoord.xy) - (*(reinterpret_cast<device int2*>(g_PushConstants.SharedConstants + 16ul)));
bool _66;
if (!any(_55 < int2(0)))
{
_66 = any(_55 >= (*(reinterpret_cast<device int2*>(g_PushConstants.SharedConstants + 24ul))));
}
else
{
_66 = true;
}
float4 _77;
if (_66)
{
_77 = float4(0.0);
}
else
{
_77 = g_Texture2DDescriptorHeap[*(reinterpret_cast<device uint*>(g_PushConstants.SharedConstants + 12ul))].read(uint2(int3(select(_55, int2(0), bool2(_66)), 0).xy), 0);
}
float3 _81 = powr(_77.xyz, *(reinterpret_cast<device float3*>(g_PushConstants.SharedConstants)));
out.out_var_SV_Target = float4(_81.x, _81.y, _81.z, _77.w);
return out;
}

124 changes: 124 additions & 0 deletions shaders-msl/asm/frag/bitcast-ptr-vec.argument-tier-1.msl23.asm.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 83
; Schema: 0
OpCapability Shader
OpCapability Int64
OpCapability RuntimeDescriptorArray
OpCapability PhysicalStorageBufferAddresses
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_physical_storage_buffer"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint Fragment %2 "main" %3 %4
OpExecutionMode %2 OriginUpperLeft
OpSource HLSL 600
OpName %5 "type.ConstantBuffer.PushConstants"
OpMemberName %5 0 "VertexShaderConstants"
OpMemberName %5 1 "PixelShaderConstants"
OpMemberName %5 2 "SharedConstants"
OpName %6 "g_PushConstants"
OpName %7 "type.2d.image"
OpName %8 "g_Texture2DDescriptorHeap"
OpName %4 "out.var.SV_Target"
OpName %2 "main"
OpDecorate %3 BuiltIn FragCoord
OpDecorate %4 Location 0
OpDecorate %8 DescriptorSet 0
OpDecorate %8 Binding 0
OpMemberDecorate %5 0 Offset 0
OpMemberDecorate %5 1 Offset 8
OpMemberDecorate %5 2 Offset 16
OpDecorate %5 Block
%9 = OpTypeInt 32 0
%10 = OpTypeInt 32 1
%11 = OpConstant %10 2
%12 = OpTypeInt 64 0
%13 = OpConstant %12 12
%14 = OpConstant %12 16
%15 = OpConstant %10 0
%16 = OpTypeVector %10 2
%17 = OpConstantComposite %16 %15 %15
%18 = OpTypeBool
%19 = OpConstantTrue %18
%20 = OpConstant %12 24
%21 = OpTypeFloat 32
%22 = OpConstant %21 0
%23 = OpTypeVector %21 4
%24 = OpConstantComposite %23 %22 %22 %22 %22
%5 = OpTypeStruct %12 %12 %12
%25 = OpTypePointer PushConstant %5
%7 = OpTypeImage %21 2D 2 0 0 1 Unknown
%26 = OpTypeRuntimeArray %7
%27 = OpTypePointer UniformConstant %26
%28 = OpTypePointer Input %23
%29 = OpTypePointer Output %23
%30 = OpTypeVoid
%31 = OpTypeFunction %30
%32 = OpTypePointer PushConstant %12
%33 = OpTypePointer PhysicalStorageBuffer %9
%34 = OpTypePointer UniformConstant %7
%35 = OpTypeVector %21 2
%36 = OpTypePointer PhysicalStorageBuffer %16
%37 = OpTypeVector %18 2
%38 = OpTypeVector %10 3
%39 = OpTypeVector %21 3
%40 = OpTypePointer PhysicalStorageBuffer %39
%6 = OpVariable %25 PushConstant
%8 = OpVariable %27 UniformConstant
%3 = OpVariable %28 Input
%4 = OpVariable %29 Output
%2 = OpFunction %30 None %31
%41 = OpLabel
%42 = OpLoad %23 %3
%43 = OpAccessChain %32 %6 %11
%44 = OpLoad %12 %43
%45 = OpIAdd %12 %44 %13
%46 = OpBitcast %33 %45
%47 = OpLoad %9 %46 Aligned 4
%48 = OpAccessChain %34 %8 %47
%49 = OpLoad %7 %48
%50 = OpVectorShuffle %35 %42 %42 0 1
%51 = OpConvertFToS %16 %50
%52 = OpIAdd %12 %44 %14
%53 = OpBitcast %36 %52
%54 = OpLoad %16 %53 Aligned 4
%55 = OpISub %16 %51 %54
%56 = OpSLessThan %37 %55 %17
%57 = OpAny %18 %56
%58 = OpLogicalNot %18 %57
OpSelectionMerge %59 None
OpBranchConditional %58 %60 %59
%60 = OpLabel
%61 = OpIAdd %12 %44 %20
%62 = OpBitcast %36 %61
%63 = OpLoad %16 %62 Aligned 4
%64 = OpSGreaterThanEqual %37 %55 %63
%65 = OpAny %18 %64
OpBranch %59
%59 = OpLabel
%66 = OpPhi %18 %19 %41 %65 %60
%67 = OpCompositeConstruct %37 %66 %66
%68 = OpSelect %16 %67 %17 %55
OpSelectionMerge %69 None
OpBranchConditional %66 %70 %71
%70 = OpLabel
OpBranch %69
%71 = OpLabel
%72 = OpCompositeExtract %10 %68 0
%73 = OpCompositeExtract %10 %68 1
%74 = OpCompositeConstruct %38 %72 %73 %15
%75 = OpVectorShuffle %16 %74 %74 0 1
%76 = OpImageFetch %23 %49 %75 Lod %15
OpBranch %69
%69 = OpLabel
%77 = OpPhi %23 %24 %70 %76 %71
%78 = OpVectorShuffle %39 %77 %77 0 1 2
%79 = OpBitcast %40 %44
%80 = OpLoad %39 %79 Aligned 4
%81 = OpExtInst %39 %1 Pow %78 %80
%82 = OpVectorShuffle %23 %77 %81 4 5 6 3
OpStore %4 %82
OpReturn
OpFunctionEnd
2 changes: 1 addition & 1 deletion spirv_msl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10008,7 +10008,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
{
string op;

if (type.vecsize == 1 && input_type.vecsize == 1)
if ((type.vecsize == 1 || type.pointer) && (input_type.vecsize == 1 || input_type.pointer))
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]), "))");
Expand Down

0 comments on commit 764abd5

Please sign in to comment.