From 3136e342157d0b29efba7402e33e23d7373b893c Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Thu, 7 Jan 2021 14:30:35 +0100 Subject: MSL: Always use input_attachment_index for framebuffer fetch binding. --msl-decoration-binding would end up overriding the input attachment index to binding which is very unexpected and broken. --- ...inding.ios.framebuffer-fetch.msl2.argument.frag | 23 ++++++++++++++++++++++ ...inding.ios.framebuffer-fetch.msl2.argument.frag | 12 +++++++++++ spirv_msl.cpp | 23 +++++++++++----------- test_shaders.py | 2 ++ 4 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 reference/shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag create mode 100644 shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag diff --git a/reference/shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag b/reference/shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag new file mode 100644 index 00000000..8c7f67b6 --- /dev/null +++ b/reference/shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag @@ -0,0 +1,23 @@ +#include +#include + +using namespace metal; + +struct spvDescriptorSetBuffer0 +{ + sampler uSampler [[id(8)]]; + texture2d uTex [[id(9)]]; +}; + +struct main0_out +{ + float4 FragColor [[color(0)]]; +}; + +fragment main0_out main0(constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 uSub [[color(1)]]) +{ + main0_out out = {}; + out.FragColor = uSub + spvDescriptorSet0.uTex.sample(spvDescriptorSet0.uSampler, float2(0.5)); + return out; +} + diff --git a/shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag b/shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag new file mode 100644 index 00000000..671a4d1b --- /dev/null +++ b/shaders-msl-no-opt/frag/subpass-input.decoration-binding.ios.framebuffer-fetch.msl2.argument.frag @@ -0,0 +1,12 @@ +#version 450 + +layout(set = 0, binding = 10, input_attachment_index = 1) uniform subpassInput uSub; +layout(location = 0) out vec4 FragColor; + +layout(set = 0, binding = 9) uniform texture2D uTex; +layout(set = 0, binding = 8) uniform sampler uSampler; + +void main() +{ + FragColor = subpassLoad(uSub) + texture(sampler2D(uTex, uSampler), vec2(0.5)); +} diff --git a/spirv_msl.cpp b/spirv_msl.cpp index daca7c76..1060bb27 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -11723,10 +11723,18 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base if (has_extended_decoration(var.self, resource_decoration)) return get_extended_decoration(var.self, resource_decoration); - // Allow user to enable decoration binding - if (msl_options.enable_decoration_binding) + auto &type = get(var.basetype); + + if (type_is_msl_framebuffer_fetch(type)) + { + // Frame-buffer fetch gets its fallback resource index from the input attachment index, + // which is then treated as color index. + return get_decoration(var.self, DecorationInputAttachmentIndex); + } + else if (msl_options.enable_decoration_binding) { - // If there is no explicit mapping of bindings to MSL, use the declared binding. + // Allow user to enable decoration binding. + // If there is no explicit mapping of bindings to MSL, use the declared binding as a fallback. if (has_decoration(var.self, DecorationBinding)) { var_binding = get_decoration(var.self, DecorationBinding); @@ -11745,7 +11753,6 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base allocate_argument_buffer_ids = descriptor_set_is_argument_buffer(var_desc_set); uint32_t binding_stride = 1; - auto &type = get(var.basetype); for (uint32_t i = 0; i < uint32_t(type.array.size()); i++) binding_stride *= to_array_size_literal(type, i); @@ -11754,13 +11761,7 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base // If a binding has not been specified, revert to incrementing resource indices. uint32_t resource_index; - if (type_is_msl_framebuffer_fetch(type)) - { - // Frame-buffer fetch gets its fallback resource index from the input attachment index, - // which is then treated as color index. - resource_index = get_decoration(var.self, DecorationInputAttachmentIndex); - } - else if (allocate_argument_buffer_ids) + if (allocate_argument_buffer_ids) { // Allocate from a flat ID binding space. resource_index = next_metal_resource_ids[var_desc_set]; diff --git a/test_shaders.py b/test_shaders.py index 3e0eae39..3d9969dc 100755 --- a/test_shaders.py +++ b/test_shaders.py @@ -321,6 +321,8 @@ def cross_compile_msl(shader, spirv, opt, iterations, paths): msl_args.append('32') if '.force-sample.' in shader: msl_args.append('--msl-force-sample-rate-shading') + if '.decoration-binding.' in shader: + msl_args.append('--msl-decoration-binding') subprocess.check_call(msl_args) -- cgit v1.2.3