Skip to content

Commit 26c7e8f

Browse files
committed
Added support for newer versions of SPIR-V.
The version config value is now respected for "spirv" shader type and and used to control the version that is targeted when compiling. Other targets use the latest version before cross-compiling. Added support for new storage buffer representation when extracting uniforms from SPIR-V, which has been in use since SPIR-V 1.6. SPIR-V version define now follows the standard version code representation. This also fixes the fact that the define improperly reported the latest rather than the actual target, and the documentation didn't match how the version was represented. The version for Metal is now properly forwarded to SPIRV-Cross for cross-compilation. This may fix some features not being enabled. Updated glslang and SPIRV-Cross. Incremented the version to 1.8.0.
1 parent d4053a7 commit 26c7e8f

File tree

19 files changed

+428
-71
lines changed

19 files changed

+428
-71
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ if (MSL_OUTPUT_DIR)
8989
endif()
9090

9191
set(MSL_MAJOR_VERSION 1)
92-
set(MSL_MINOR_VERSION 7)
93-
set(MSL_PATCH_VERSION 6)
92+
set(MSL_MINOR_VERSION 8)
93+
set(MSL_PATCH_VERSION 0)
9494
set(MSL_VERSION ${MSL_MAJOR_VERSION}.${MSL_MINOR_VERSION}.${MSL_PATCH_VERSION})
9595

9696
set(MSL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})

Compile/SPIRV-Cross

Submodule SPIRV-Cross updated 35 files

Compile/glslang

Submodule glslang updated 102 files

Compile/include/MSL/Compile/Target.h

Lines changed: 7 additions & 1 deletion
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.
@@ -436,6 +436,12 @@ class MSL_COMPILE_EXPORT Target
436436
*/
437437
virtual bool needsReflectionNames() const;
438438

439+
/**
440+
* @brief Gets the SPIR-V version to compile with.
441+
* @return The SPIR-V version. Defaults to the latest supported version.
442+
*/
443+
virtual std::uint32_t getSpirVVersion() const;
444+
439445
/**
440446
* @brief Function called when about to compile a shader.
441447
*/

Compile/include/MSL/Compile/TargetSpirV.h

Lines changed: 11 additions & 1 deletion
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.
@@ -39,20 +39,30 @@ namespace msl
3939
class MSL_COMPILE_EXPORT TargetSpirV : public Target
4040
{
4141
public:
42+
/**
43+
* @brief Constructs this with the version number.
44+
* @param version The Metal version number.
45+
*/
46+
explicit TargetSpirV(std::uint32_t version);
47+
4248
std::uint32_t getId() const override;
4349
std::uint32_t getVersion() const override;
4450
bool featureSupported(Feature feature) const override;
4551
std::vector<std::pair<std::string, std::string>> getExtraDefines() const override;
4652

4753
protected:
4854
bool needsReflectionNames() const override;
55+
std::uint32_t getSpirVVersion() const override;
4956
bool crossCompile(std::vector<std::uint8_t>& data, Output& output,
5057
const std::string& fileName, std::size_t line, std::size_t column,
5158
const std::array<bool, compile::stageCount>& pipelineStages, compile::Stage stage,
5259
const std::vector<std::uint32_t>& spirv, const std::string& entryPoint,
5360
const std::vector<compile::Uniform>& uniforms, std::vector<std::uint32_t>& uniformIds,
5461
const std::vector<compile::FragmentInputGroup>& fragmentInputs,
5562
std::uint32_t fragmentGroup) override;
63+
64+
private:
65+
std::uint32_t m_version;
5666
};
5767

5868
} // namespace msl

Compile/src/Compiler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2021 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.
@@ -281,11 +281,13 @@ const TBuiltInResource& Compiler::getDefaultResources()
281281

282282
bool Compiler::compile(Stages& stages, Output &output, const std::string& baseFileName,
283283
const std::string& glsl, const std::vector<Parser::LineMapping>& lineMappings,
284-
Stage stage, const TBuiltInResource& resources)
284+
Stage stage, const TBuiltInResource& resources, std::uint32_t spirvVersion)
285285
{
286286
const char* glslStr = glsl.c_str();
287287
std::unique_ptr<glslang::TShader> shader(
288288
new glslang::TShader(stageMap[static_cast<unsigned int>(stage)]));
289+
shader->setEnvTarget(glslang::EShTargetSpv,
290+
static_cast<glslang::EShTargetLanguageVersion>(spirvVersion));
289291
shader->setStrings(&glslStr, 1);
290292
shader->setAutoMapBindings(true);
291293
shader->setAutoMapLocations(true);
@@ -325,6 +327,8 @@ Compiler::SpirV Compiler::assemble(Output& output, const Program& program,
325327

326328
SpirV spirv;
327329
spv::SpvBuildLogger logger;
330+
glslang::SpvOptions options;
331+
options.generateDebugInfo = true;
328332
glslang::GlslangToSpv(*intermediate, spirv, &logger);
329333
if (addToOutput(output, logger, pipeline.token->fileName, pipeline.token->line,
330334
pipeline.token->column))

Compile/src/Compiler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 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.
@@ -78,7 +78,7 @@ class MSL_COMPILE_EXPORT Compiler
7878

7979
static bool compile(Stages& stages, Output& output, const std::string& baseFileName,
8080
const std::string& glsl, const std::vector<Parser::LineMapping>& lineMappings,
81-
Stage stage, const TBuiltInResource& resources);
81+
Stage stage, const TBuiltInResource& resources, std::uint32_t spirvVersion);
8282

8383
static bool link(Program& program, Output& output, const Parser::Pipeline& pipeline,
8484
const Stages& stages);

Compile/src/MetalOutput.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 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.
@@ -29,8 +29,8 @@ std::string MetalOutput::disassemble(Output& output, const Compiler::SpirV& spir
2929
spirv_cross::CompilerMSL::Options options;
3030
options.platform = ios ? spirv_cross::CompilerMSL::Options::iOS :
3131
spirv_cross::CompilerMSL::Options::macOS;
32-
options.msl_version = spirv_cross::CompilerMSL::Options::make_msl_version(version/10,
33-
version%10);
32+
options.msl_version = spirv_cross::CompilerMSL::Options::make_msl_version(version/100,
33+
version%100);
3434
options.capture_output_to_buffer = outputToBuffer;
3535

3636
spirv_cross::CompilerMSL compiler(spirv);

Compile/src/Parser.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include <MSL/Compile/Types.h>
2222
#include "TokenList.h"
2323
#include <array>
24-
#include <float.h>
2524

2625
namespace msl
2726
{

Compile/src/SpirVProcessor.cpp

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <cassert>
2323
#include <cstring>
2424
#include <map>
25+
#include <sstream>
2526
#include <unordered_map>
2627
#include <unordered_set>
2728

@@ -141,6 +142,7 @@ struct IntermediateData
141142
std::map<std::uint32_t, std::uint32_t> inputVars;
142143
std::map<std::uint32_t, std::uint32_t> outputVars;
143144
std::map<std::uint32_t, std::uint32_t> imageVars;
145+
std::map<std::uint32_t, std::uint32_t> storageBufferVars;
144146
std::pair<std::uint32_t, std::uint32_t> pushConstantPointer = std::make_pair(unknown, unknown);
145147
std::pair<std::uint32_t, std::uint32_t> clipDistanceMember = std::make_pair(unknown, unknown);
146148
std::pair<std::uint32_t, std::uint32_t> cullDistanceMember = std::make_pair(unknown, unknown);
@@ -1130,7 +1132,8 @@ std::vector<std::uint32_t> makeArrayLengths(const std::vector<ArrayInfo>& arrayE
11301132
void addUniforms(SpirVProcessor& processor, const IntermediateData& data)
11311133
{
11321134
bool hasPushConstant = data.pushConstantPointer.first != unknown;
1133-
std::size_t totalUniforms = data.uniformVars.size() + data.imageVars.size() + hasPushConstant;
1135+
std::size_t totalUniforms = data.uniformVars.size() + data.imageVars.size() +
1136+
data.storageBufferVars.size() + hasPushConstant;
11341137
processor.uniforms.resize(totalUniforms);
11351138
processor.uniformIds.resize(totalUniforms);
11361139
std::size_t i = 0;
@@ -1239,6 +1242,43 @@ void addUniforms(SpirVProcessor& processor, const IntermediateData& data)
12391242

12401243
++i;
12411244
}
1245+
1246+
for (const auto& storageBufferIndices : data.storageBufferVars)
1247+
{
1248+
processor.uniformIds[i] = storageBufferIndices.first;
1249+
std::uint32_t typeId = storageBufferIndices.second;
1250+
1251+
Uniform& uniform = processor.uniforms[i];
1252+
uniform.type = getType(uniform.arrayElements, uniform.structIndex, processor, data, typeId);
1253+
if (uniform.type == Type::Struct)
1254+
uniform.name = processor.structs[uniform.structIndex].name;
1255+
else
1256+
{
1257+
auto foundName = data.names.find(storageBufferIndices.first);
1258+
assert(foundName != data.names.end());
1259+
uniform.name = foundName->second;
1260+
}
1261+
1262+
1263+
uniform.uniformType = UniformType::BlockBuffer;
1264+
1265+
auto foundDescriptorSet = data.descriptorSets.find(storageBufferIndices.first);
1266+
if (foundDescriptorSet == data.descriptorSets.end())
1267+
uniform.descriptorSet = unknown;
1268+
else
1269+
uniform.descriptorSet = foundDescriptorSet->second;
1270+
1271+
auto foundBinding = data.bindings.find(storageBufferIndices.first);
1272+
if (foundBinding == data.bindings.end())
1273+
uniform.binding = unknown;
1274+
else
1275+
uniform.binding = foundBinding->second;
1276+
1277+
uniform.inputAttachmentIndex = unknown;
1278+
uniform.samplerIndex = unknown;
1279+
1280+
++i;
1281+
}
12421282
}
12431283

12441284
bool addInputsOutputs(Output& output, std::vector<SpirVProcessor::InputOutput>& inputOutputs,
@@ -1985,10 +2025,16 @@ bool SpirVProcessor::extract(Output& output, const std::string& fileName, std::s
19852025
this->column = column;
19862026
this->spirv = &spirv;
19872027

1988-
MSL_UNUSED(minVersion);
19892028
assert(spirv.size() > firstInstruction);
19902029
assert(spirv[0] == spv::MagicNumber);
1991-
assert(spirv[1] >= minVersion && spirv[1] <= spv::Version);
2030+
if (spirv[1] < minVersion || spirv[1] > spv::Version)
2031+
{
2032+
std::stringstream versionStr;
2033+
versionStr << std::hex << spirv[1];
2034+
output.addMessage(Output::Level::Error, fileName, line,
2035+
column, false, "linker error: invalid SPIR-V version 0x" + versionStr.str());
2036+
return false;
2037+
}
19922038
std::vector<char> tempBuffer;
19932039

19942040
IntermediateData data;
@@ -2257,6 +2303,7 @@ bool SpirVProcessor::extract(Output& output, const std::string& fileName, std::s
22572303
case spv::StorageClassImage:
22582304
case spv::StorageClassUniformConstant:
22592305
case spv::StorageClassPushConstant:
2306+
case spv::StorageClassStorageBuffer:
22602307
if (data.types.find(type) != data.types.end() ||
22612308
data.arrayTypes.find(type) != data.arrayTypes.end() ||
22622309
data.structTypes.find(type) != data.structTypes.end())
@@ -2326,6 +2373,13 @@ bool SpirVProcessor::extract(Output& output, const std::string& fileName, std::s
23262373
data.pushConstantPointer = std::make_pair(id, foundPointer->second);
23272374
break;
23282375
}
2376+
case spv::StorageClassStorageBuffer:
2377+
{
2378+
auto foundPointer = data.pointers.find(pointerType);
2379+
assert(foundPointer != data.pointers.end());
2380+
data.storageBufferVars[id] = foundPointer->second;
2381+
break;
2382+
}
23292383
default:
23302384
break;
23312385
}

0 commit comments

Comments
 (0)