diff --git a/reference/opt/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag b/reference/opt/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag new file mode 100644 index 000000000..865178200 --- /dev/null +++ b/reference/opt/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag @@ -0,0 +1,68 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +template +struct spvBufferDescriptor +{ + T value; + int length; + const device T& operator -> () const device + { + return value; + } + const device T& operator * () const device + { + return value; + } +}; + +template +struct spvDescriptorArray; + +template +struct spvDescriptorArray +{ + spvDescriptorArray(const device spvBufferDescriptor* 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* 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* ssbo_ [[buffer(0)]]) +{ + spvDescriptorArray ssbo {ssbo_}; + + uint _15 = in.inputId; + if (ssbo[_15]->val == 2u) + { + discard_fragment(); + } + if (int((ssbo.length(123) - 4) / 4) == 25) + { + discard_fragment(); + } +} + diff --git a/reference/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag b/reference/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag new file mode 100644 index 000000000..865178200 --- /dev/null +++ b/reference/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag @@ -0,0 +1,68 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +template +struct spvBufferDescriptor +{ + T value; + int length; + const device T& operator -> () const device + { + return value; + } + const device T& operator * () const device + { + return value; + } +}; + +template +struct spvDescriptorArray; + +template +struct spvDescriptorArray +{ + spvDescriptorArray(const device spvBufferDescriptor* 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* 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* ssbo_ [[buffer(0)]]) +{ + spvDescriptorArray ssbo {ssbo_}; + + uint _15 = in.inputId; + if (ssbo[_15]->val == 2u) + { + discard_fragment(); + } + if (int((ssbo.length(123) - 4) / 4) == 25) + { + discard_fragment(); + } +} + diff --git a/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag b/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag new file mode 100644 index 000000000..00849d0d4 --- /dev/null +++ b/shaders-msl/frag/runtime_array_as_argument_buffer_buf.msl3.argument-tier-1.rich-descriptor.frag @@ -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; + } diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 2f4a04a8b..a6dd8da9a 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -7416,19 +7416,28 @@ void CompilerMSL::emit_custom_functions() break; case SPVFuncImplVariableDescriptorArray: - statement("template"); - statement("struct spvDescriptorArray"); - begin_scope(); - statement("spvDescriptorArray(const device spvDescriptor* 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* ptr;"); - end_scope_decl(); - statement(""); + if (spv_function_implementations.count(SPVFuncImplVariableDescriptor) != 0) + { + statement("template"); + statement("struct spvDescriptorArray"); + begin_scope(); + statement("spvDescriptorArray(const device spvDescriptor* 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* ptr;"); + end_scope_decl(); + statement(""); + } + else + { + statement("template"); + statement("struct spvDescriptorArray;"); + statement(""); + } if (msl_options.runtime_array_rich_descriptor && spv_function_implementations.count(SPVFuncImplVariableSizedDescriptor) != 0)