Skip to content

Commit

Permalink
Merge pull request #2276 from Try/msl-descriptor-array-fixup
Browse files Browse the repository at this point in the history
Fix codegen for shader with only bindless ssbo
  • Loading branch information
HansKristian-Work authored Feb 5, 2024
2 parents 03b485d + ed7a3e3 commit 3198ac2
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"

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

using namespace metal;

template<typename T>
struct spvBufferDescriptor
{
T value;
int length;
const device T& operator -> () const device
{
return value;
}
const device T& operator * () const device
{
return value;
}
};

template<typename T>
struct spvDescriptorArray;

template<typename T>
struct spvDescriptorArray<device T*>
{
spvDescriptorArray(const device spvBufferDescriptor<device T*>* ptr) : ptr(ptr)
{
}
const device T* operator [] (size_t i) const
{
return ptr[i].value;
}
const int length(int i) const
{
return ptr[i].length;
}
const device spvBufferDescriptor<device T*>* ptr;
};

struct Ssbo
{
uint val;
uint data[1];
};

struct main0_in
{
uint inputId [[user(locn0)]];
};

fragment void main0(main0_in in [[stage_in]], const device spvBufferDescriptor<const device Ssbo*>* ssbo_ [[buffer(0)]])
{
spvDescriptorArray<const device Ssbo*> ssbo {ssbo_};

uint _15 = in.inputId;
if (ssbo[_15]->val == 2u)
{
discard_fragment();
}
if (int((ssbo.length(123) - 4) / 4) == 25)
{
discard_fragment();
}
}

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

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

using namespace metal;

template<typename T>
struct spvBufferDescriptor
{
T value;
int length;
const device T& operator -> () const device
{
return value;
}
const device T& operator * () const device
{
return value;
}
};

template<typename T>
struct spvDescriptorArray;

template<typename T>
struct spvDescriptorArray<device T*>
{
spvDescriptorArray(const device spvBufferDescriptor<device T*>* ptr) : ptr(ptr)
{
}
const device T* operator [] (size_t i) const
{
return ptr[i].value;
}
const int length(int i) const
{
return ptr[i].length;
}
const device spvBufferDescriptor<device T*>* ptr;
};

struct Ssbo
{
uint val;
uint data[1];
};

struct main0_in
{
uint inputId [[user(locn0)]];
};

fragment void main0(main0_in in [[stage_in]], const device spvBufferDescriptor<const device Ssbo*>* ssbo_ [[buffer(0)]])
{
spvDescriptorArray<const device Ssbo*> ssbo {ssbo_};

uint _15 = in.inputId;
if (ssbo[_15]->val == 2u)
{
discard_fragment();
}
if (int((ssbo.length(123) - 4) / 4) == 25)
{
discard_fragment();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 460

#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_nonuniform_qualifier : enable

layout(location = 0) in flat uint inputId;

layout(binding = 0, std430) readonly buffer Ssbo { uint val; uint data[]; } ssbo[];

void main() {
if(ssbo[nonuniformEXT(inputId)].val==2)
discard;
if(ssbo[123].data.length()==25)
discard;
}
35 changes: 22 additions & 13 deletions spirv_msl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7416,19 +7416,28 @@ void CompilerMSL::emit_custom_functions()
break;

case SPVFuncImplVariableDescriptorArray:
statement("template<typename T>");
statement("struct spvDescriptorArray");
begin_scope();
statement("spvDescriptorArray(const device spvDescriptor<T>* ptr) : ptr(ptr)");
begin_scope();
end_scope();
statement("const device T& operator [] (size_t i) const");
begin_scope();
statement("return ptr[i].value;");
end_scope();
statement("const device spvDescriptor<T>* ptr;");
end_scope_decl();
statement("");
if (spv_function_implementations.count(SPVFuncImplVariableDescriptor) != 0)
{
statement("template<typename T>");
statement("struct spvDescriptorArray");
begin_scope();
statement("spvDescriptorArray(const device spvDescriptor<T>* ptr) : ptr(ptr)");
begin_scope();
end_scope();
statement("const device T& operator [] (size_t i) const");
begin_scope();
statement("return ptr[i].value;");
end_scope();
statement("const device spvDescriptor<T>* ptr;");
end_scope_decl();
statement("");
}
else
{
statement("template<typename T>");
statement("struct spvDescriptorArray;");
statement("");
}

if (msl_options.runtime_array_rich_descriptor &&
spv_function_implementations.count(SPVFuncImplVariableSizedDescriptor) != 0)
Expand Down

0 comments on commit 3198ac2

Please sign in to comment.