Skip to content

Commit c89787e

Browse files
committed
Fixed discard when targeting Metal < 2.3.
SPV_EXT_demote_to_helper_invocation extension was made core in SPIRV 1.6, which use features not supported until Metal 2.3. Force SPIRV 1.5 when targeting Metal < 2.3 to ensure that the older and less optimal method of discard is used.
1 parent f28dd84 commit c89787e

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ endif()
9090

9191
set(MSL_MAJOR_VERSION 1)
9292
set(MSL_MINOR_VERSION 8)
93-
set(MSL_PATCH_VERSION 2)
93+
set(MSL_PATCH_VERSION 3)
9494
set(MSL_VERSION ${MSL_MAJOR_VERSION}.${MSL_MINOR_VERSION}.${MSL_PATCH_VERSION})
9595

9696
set(MSL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})

Compile/include/MSL/Compile/TargetMetal.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2022 Aaron Barany
2+
* Copyright 2016-2025 Aaron Barany
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -95,9 +95,10 @@ class MSL_COMPILE_EXPORT TargetMetal : public Target
9595
* @param metal The metal shader string.
9696
* @return False if the compilation failed.
9797
*/
98-
virtual bool compileMetal(std::vector<std::uint8_t>& data, Output& output,
99-
const std::string& metal);
98+
virtual bool compileMetal(
99+
std::vector<std::uint8_t>& data, Output& output, const std::string& metal);
100100

101+
std::uint32_t getSpirVVersion() const override;
101102
void willCompile() override;
102103
bool crossCompile(std::vector<std::uint8_t>& data, Output& output, const std::string& fileName,
103104
std::size_t line, std::size_t column,

Compile/src/TargetMetal.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2022 Aaron Barany
2+
* Copyright 2016-2025 Aaron Barany
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818
#include <MSL/Compile/Output.h>
1919
#include "ExecuteCommand.h"
2020
#include "MetalOutput.h"
21+
#include <spirv/unified1/spirv.hpp>
2122
#include <cassert>
2223
#include <fstream>
2324
#include <sstream>
@@ -42,8 +43,8 @@ namespace msl
4243

4344
using namespace compile;
4445

45-
static void setBinding(std::vector<uint32_t>& spirv, std::uint32_t id, std::uint32_t set,
46-
std::uint32_t binding)
46+
static void setBinding(
47+
std::vector<uint32_t>& spirv, std::uint32_t id, std::uint32_t set, std::uint32_t binding)
4748
{
4849
const unsigned int firstInstruction = 5;
4950
const std::uint32_t opCodeMask = 0xFFFF;
@@ -131,8 +132,8 @@ static std::vector<std::uint32_t> setBindingIndices(const std::vector<std::uint3
131132
return adjustedSpirv;
132133
}
133134

134-
static std::string setFragmentGroup(const std::string& metal, const std::string& entryPoint,
135-
std::uint32_t fragmentGroup)
135+
static std::string setFragmentGroup(
136+
const std::string& metal, const std::string& entryPoint, std::uint32_t fragmentGroup)
136137
{
137138
std::string structDecl = "struct " + entryPoint + "_out";
138139
std::size_t outStructStart = metal.find(structDecl);
@@ -164,8 +165,8 @@ static std::string setFragmentGroup(const std::string& metal, const std::string&
164165
return result;
165166
}
166167

167-
static std::string patchEntryPointInputGroup(const std::string& metal,
168-
const FragmentInputGroup& inputGroup)
168+
static std::string patchEntryPointInputGroup(
169+
const std::string& metal, const FragmentInputGroup& inputGroup)
169170
{
170171
// Expect one primary declaration in the entry point.
171172
std::string declStart = "constant " + inputGroup.type + "& " + inputGroup.name + " [[buffer(";
@@ -279,14 +280,23 @@ std::vector<std::pair<std::string, std::string>> TargetMetal::getExtraDefines()
279280
return defines;
280281
}
281282

283+
std::uint32_t TargetMetal::getSpirVVersion() const
284+
{
285+
// SPV_EXT_demote_to_helper_invocation is core with SPIRV 1.6, and breaks discard operations
286+
// when targeting Metal < 2.3.
287+
if (m_version < 203)
288+
return 0x10500;
289+
return spv::Version;
290+
}
291+
282292
void TargetMetal::willCompile()
283293
{
284294
// Need dummy bindings for internal usage.
285295
setDummyBindings(true);
286296
}
287297

288-
bool TargetMetal::compileMetal(std::vector<std::uint8_t>& data, Output& output,
289-
const std::string& metal)
298+
bool TargetMetal::compileMetal(
299+
std::vector<std::uint8_t>& data, Output& output, const std::string& metal)
290300
{
291301
// Compile this entry point.
292302
std::stringstream versionStr;

0 commit comments

Comments
 (0)