From e58a108387b8fafe2e3be2f4d48e9290193c225b Mon Sep 17 00:00:00 2001 From: Attila Kocsis Date: Sat, 10 Aug 2019 18:27:57 +0200 Subject: [PATCH] Metal: Fix resource binding for latest spirv-cross More info: https://github.com/KhronosGroup/SPIRV-Cross/pull/1036 https://github.com/KhronosGroup/SPIRV-Cross/issues/1072 --- tools/shaderc/shaderc.cpp | 8 +++-- tools/shaderc/shaderc_metal.cpp | 59 +++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 057915209..262e8a111 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -2278,9 +2278,13 @@ namespace bgfx code += _comment; code += preprocessor.m_preprocessed; - if (0 != spirv || 0 != metal) + if (0 != metal) { - compiled = compileSPIRVShader(_options, metal ? BX_MAKEFOURCC('M', 'T', 'L', 0) : 0, code, _writer); + compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), code, _writer); + } + else if (0 != spirv) + { + compiled = compileSPIRVShader(_options, 0, code, _writer); } else if (0 != pssl) { diff --git a/tools/shaderc/shaderc_metal.cpp b/tools/shaderc/shaderc_metal.cpp index cb3cadcc1..5c51c9ebf 100644 --- a/tools/shaderc/shaderc_metal.cpp +++ b/tools/shaderc/shaderc_metal.cpp @@ -621,6 +621,11 @@ namespace bgfx { namespace metal ); shader->setEntryPoint("main"); + shader->setAutoMapBindings(true); + const int textureBindingOffset = 16; + shader->setShiftBinding(glslang::EResTexture, textureBindingOffset); + shader->setShiftBinding(glslang::EResSampler, textureBindingOffset); + shader->setShiftBinding(glslang::EResImage, textureBindingOffset); const char* shaderStrings[] = { _code.c_str() }; shader->setStrings( @@ -857,6 +862,10 @@ namespace bgfx { namespace metal } spirv_cross::CompilerMSL msl(std::move(spirv)); + + auto executionModel = msl.get_execution_model(); + spirv_cross::MSLResourceBinding newBinding; + newBinding.stage = executionModel; spirv_cross::ShaderResources resources = msl.get_shader_resources(); @@ -866,13 +875,35 @@ namespace bgfx { namespace metal for (auto &resource : resources.uniform_buffers) { + unsigned set = msl.get_decoration( resource.id, spv::DecorationDescriptorSet ); + unsigned binding = msl.get_decoration( resource.id, spv::DecorationBinding ); + newBinding.desc_set = set; + newBinding.binding = binding; + newBinding.msl_buffer = 0; + msl.add_msl_resource_binding( newBinding ); + msl.set_name(resource.id, "_mtl_u"); } for (auto &resource : resources.storage_buffers) { - unsigned binding = msl.get_decoration(resource.id, spv::DecorationBinding); - msl.set_decoration(resource.id, spv::DecorationBinding, binding + 1); + unsigned set = msl.get_decoration( resource.id, spv::DecorationDescriptorSet ); + unsigned binding = msl.get_decoration( resource.id, spv::DecorationBinding ); + newBinding.desc_set = set; + newBinding.binding = binding; + newBinding.msl_buffer = binding + 1; + msl.add_msl_resource_binding( newBinding ); + } + + for (auto &resource : resources.separate_samplers) + { + unsigned set = msl.get_decoration( resource.id, spv::DecorationDescriptorSet ); + unsigned binding = msl.get_decoration( resource.id, spv::DecorationBinding ); + newBinding.desc_set = set; + newBinding.binding = binding; + newBinding.msl_texture = binding - textureBindingOffset; + newBinding.msl_sampler = binding - textureBindingOffset; + msl.add_msl_resource_binding( newBinding ); } for (auto &resource : resources.separate_images) @@ -880,7 +911,31 @@ namespace bgfx { namespace metal std::string name = msl.get_name(resource.id); if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") ) msl.set_name(resource.id, name.substr(0, name.length() - 7)); + + unsigned set = msl.get_decoration( resource.id, spv::DecorationDescriptorSet ); + unsigned binding = msl.get_decoration( resource.id, spv::DecorationBinding ); + newBinding.desc_set = set; + newBinding.binding = binding; + newBinding.msl_texture = binding - textureBindingOffset; + newBinding.msl_sampler = binding - textureBindingOffset; + msl.add_msl_resource_binding( newBinding ); } + + for (auto &resource : resources.storage_images) + { + std::string name = msl.get_name(resource.id); + if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") ) + msl.set_name(resource.id, name.substr(0, name.length() - 7)); + + unsigned set = msl.get_decoration( resource.id, spv::DecorationDescriptorSet ); + unsigned binding = msl.get_decoration( resource.id, spv::DecorationBinding ); + newBinding.desc_set = set; + newBinding.binding = binding; + newBinding.msl_texture = binding - textureBindingOffset; + newBinding.msl_sampler = binding - textureBindingOffset; + msl.add_msl_resource_binding( newBinding ); + } + std::string source = msl.compile(); if ('c' == _options.shaderType)