From f4fb069216ea7944545022e2813c736e63a8de3e Mon Sep 17 00:00:00 2001 From: Stenzek Date: Mon, 18 Dec 2023 18:44:22 +1000 Subject: [PATCH] MetalDevice: Explicitly bind fragment resources Fixes adaptive downsampling with Metal renderer. --- src/util/metal_device.mm | 2 +- src/util/shadergen.cpp | 8 ++++---- src/util/spirv_compiler.cpp | 19 ++++++++++++++++++- src/util/spirv_compiler.h | 2 +- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/util/metal_device.mm b/src/util/metal_device.mm index 02785fc93..a8d23cbfb 100644 --- a/src/util/metal_device.mm +++ b/src/util/metal_device.mm @@ -638,7 +638,7 @@ std::unique_ptr MetalDevice::CreateShaderFromSource(GPUShaderStage st return {}; } - std::optional msl = SPIRVCompiler::CompileSPIRVToMSL(spirv.value()); + std::optional msl = SPIRVCompiler::CompileSPIRVToMSL(stage, spirv.value()); if (!msl.has_value()) { Log_ErrorPrintf("Failed to compile SPIR-V to MSL."); diff --git a/src/util/shadergen.cpp b/src/util/shadergen.cpp index 7e0d881a5..445b390e1 100644 --- a/src/util/shadergen.cpp +++ b/src/util/shadergen.cpp @@ -336,8 +336,8 @@ void ShaderGen::DeclareTexture(std::stringstream& ss, const char* name, u32 inde { if (m_glsl) { - if (IsVulkan()) - ss << "layout(set = " << (m_has_uniform_buffer ? 1 : 0) << ", binding = " << index << ") "; + if (m_spirv) + ss << "layout(set = " << ((m_has_uniform_buffer || IsMetal()) ? 1 : 0) << ", binding = " << index << ") "; else if (m_use_glsl_binding_layout) ss << "layout(binding = " << index << ") "; @@ -354,8 +354,8 @@ void ShaderGen::DeclareTextureBuffer(std::stringstream& ss, const char* name, u3 { if (m_glsl) { - if (IsVulkan()) - ss << "layout(set = 0, binding = " << index << ") "; + if (m_spirv) + ss << "layout(set = " << ((m_has_uniform_buffer || IsMetal()) ? 1 : 0) << ", binding = " << index << ") "; else if (m_use_glsl_binding_layout) ss << "layout(binding = " << index << ") "; diff --git a/src/util/spirv_compiler.cpp b/src/util/spirv_compiler.cpp index 1fa451267..20a963ee1 100644 --- a/src/util/spirv_compiler.cpp +++ b/src/util/spirv_compiler.cpp @@ -173,12 +173,29 @@ std::optional SPIRVCompiler::CompileShader(GPUSh #ifdef __APPLE__ -std::optional SPIRVCompiler::CompileSPIRVToMSL(std::span spv) +std::optional SPIRVCompiler::CompileSPIRVToMSL(GPUShaderStage stage, std::span spv) { spirv_cross::CompilerMSL compiler(spv.data(), spv.size()); spirv_cross::CompilerMSL::Options options = compiler.get_msl_options(); options.pad_fragment_output_components = true; + + if (stage == GPUShaderStage::Fragment) + { + for (u32 i = 0; i < GPUDevice::MAX_TEXTURE_SAMPLERS; i++) + { + spirv_cross::MSLResourceBinding rb; + rb.stage = spv::ExecutionModelFragment; + rb.desc_set = 1; + rb.binding = i; + rb.count = 1; + rb.msl_texture = i; + rb.msl_sampler = i; + rb.msl_buffer = i; + compiler.add_msl_resource_binding(rb); + } + } + compiler.set_msl_options(options); std::string msl = compiler.compile(); diff --git a/src/util/spirv_compiler.h b/src/util/spirv_compiler.h index 1e4885421..8774ee1ef 100644 --- a/src/util/spirv_compiler.h +++ b/src/util/spirv_compiler.h @@ -42,7 +42,7 @@ std::optional CompileShader(GPUShaderStage stage, std::string_v #ifdef __APPLE__ // Converts a SPIR-V shader into MSL. -std::optional CompileSPIRVToMSL(std::span spv); +std::optional CompileSPIRVToMSL(GPUShaderStage stage, std::span spv); #endif