fix codegen for shader with only bindless ssbo

This commit is contained in:
Try 2024-02-04 23:28:58 +01:00
parent 03b485dc47
commit ed7a3e3ebb
4 changed files with 173 additions and 13 deletions

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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)