Add Metal Shading Language version options to shaderc. Reference version options from: https://developer.apple.com/documentation/metal/mtllanguageversion?language=objc (#3213)

Add configuration options for MSL compiler based on MSL version and Platform
Configure MSL->SPIR-V version configuration based on when ray tracing types become available
Set default metal compiler option to be metal 1.2, which is the default version assigned in the current SPIRV-Cross being used
This commit is contained in:
pheonix
2024-02-26 23:08:51 -08:00
committed by GitHub
parent a59c3addd6
commit c00e4395b0
2 changed files with 144 additions and 20 deletions

View File

@@ -77,6 +77,25 @@ namespace bgfx
// 4.3 430 vhdgf+c
// 4.4 440
//
// Metal Shading Language (MSL) profile naming convention:
// metal<MSL version>-<SPIR-V version>
//
// See section "Compiler Options Controlling the Language Version" from the
// MSL spec for the correlation between MSL version and platform OS version:
// https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
//
// MSL version | SPIR-V version | shaderc encoding
// 1.0 | 1.0 | 1000 (deprecated)
// 1.1 | 1.0 | 1110
// 1.2 | 1.0 | 1210
// 2.0 | 1.1 | 2011
// 2.1 | 1.1 | 2111
// 2.2 | 1.1 | 2211
// 2.3 | 1.4 | 2314
// 2.4 | 1.4 | 2414
// 3.0 | 1.4 | 3014
// 3.1 | 1.4 | 3114
//
// SPIR-V profile naming convention:
// spirv<SPIR-V version>-<Vulkan version>
//
@@ -102,7 +121,17 @@ namespace bgfx
{ ShadingLang::ESSL, 320, "320_es" },
{ ShadingLang::HLSL, 400, "s_4_0" },
{ ShadingLang::HLSL, 500, "s_5_0" },
{ ShadingLang::Metal, 1000, "metal" },
{ ShadingLang::Metal, 1210, "metal" },
{ ShadingLang::Metal, 1000, "metal10-10" },
{ ShadingLang::Metal, 1110, "metal11-10" },
{ ShadingLang::Metal, 1210, "metal12-10" },
{ ShadingLang::Metal, 2011, "metal20-11" },
{ ShadingLang::Metal, 2111, "metal21-11" },
{ ShadingLang::Metal, 2211, "metal22-11" },
{ ShadingLang::Metal, 2314, "metal23-14" },
{ ShadingLang::Metal, 2414, "metal24-14" },
{ ShadingLang::Metal, 3014, "metal30-14" },
{ ShadingLang::Metal, 3114, "metal31-14" },
{ ShadingLang::PSSL, 1000, "pssl" },
{ ShadingLang::SpirV, 1010, "spirv" },
{ ShadingLang::SpirV, 1010, "spirv10-10" },
@@ -1187,14 +1216,18 @@ namespace bgfx
else if (0 == bx::strCmpI(platform, "ios") )
{
preprocessor.setDefine("BX_PLATFORM_IOS=1");
if (profile->lang == ShadingLang::Metal)
{
preprocessor.setDefine("BGFX_SHADER_LANGUAGE_METAL=1");
}
else
if (profile->lang != ShadingLang::Metal)
{
preprocessor.setDefine(glslDefine);
}
char temp[32];
bx::snprintf(
temp
, sizeof(temp)
, "BGFX_SHADER_LANGUAGE_METAL=%d"
, (profile->lang == ShadingLang::Metal) ? profile->id : 0
);
preprocessor.setDefine(temp);
}
else if (0 == bx::strCmpI(platform, "linux") )
{
@@ -1517,7 +1550,7 @@ namespace bgfx
}
else if (profile->lang == ShadingLang::Metal)
{
compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), input, _shaderWriter, _messageWriter);
compiled = compileMetalShader(_options, profile->id, input, _shaderWriter, _messageWriter);
}
else if (profile->lang == ShadingLang::SpirV)
{
@@ -1674,7 +1707,7 @@ namespace bgfx
if (profile->lang == ShadingLang::Metal)
{
compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), code, _shaderWriter, _messageWriter);
compiled = compileMetalShader(_options, profile->id, code, _shaderWriter, _messageWriter);
}
else if (profile->lang == ShadingLang::SpirV)
{
@@ -2580,7 +2613,7 @@ namespace bgfx
if (profile->lang == ShadingLang::Metal)
{
compiled = compileMetalShader(_options, BX_MAKEFOURCC('M', 'T', 'L', 0), code, _shaderWriter, _messageWriter);
compiled = compileMetalShader(_options, profile->id, code, _shaderWriter, _messageWriter);
}
else if (profile->lang == ShadingLang::SpirV)
{

View File

@@ -266,6 +266,90 @@ namespace bgfx { namespace metal
return size;
}
static spv_target_env getSpirvTargetVersion(uint32_t _version, bx::WriterI* _messageWriter)
{
bx::ErrorAssert err;
switch (_version)
{
case 1000:
case 1110:
case 1210:
return SPV_ENV_VULKAN_1_0;
case 2011:
case 2111:
case 2211:
return SPV_ENV_VULKAN_1_1;
case 2314:
case 2414:
case 3014:
case 3114:
return SPV_ENV_VULKAN_1_1_SPIRV_1_4;
default:
bx::write(_messageWriter, &err, "Warning: Unknown SPIR-V version requested. Returning SPV_ENV_VULKAN_1_0 as default.\n");
return SPV_ENV_VULKAN_1_0;
}
}
static glslang::EShTargetLanguageVersion getGlslangTargetSpirvVersion(uint32_t _version, bx::WriterI* _messageWriter)
{
bx::ErrorAssert err;
switch (_version)
{
case 1000:
case 1110:
case 1210:
return glslang::EShTargetSpv_1_0;
case 2011:
case 2111:
case 2211:
return glslang::EShTargetSpv_1_1;
case 2314:
case 2414:
case 3014:
case 3114:
return glslang::EShTargetSpv_1_4;
default:
bx::write(_messageWriter, &err, "Warning: Unknown SPIR-V version requested. Returning EShTargetSpv_1_0 as default.\n");
return glslang::EShTargetSpv_1_0;
}
}
static spirv_cross::CompilerMSL::Options::Platform getMslPlatform(const std::string& _platform)
{
return "ios" == _platform
? spirv_cross::CompilerMSL::Options::Platform::iOS
: spirv_cross::CompilerMSL::Options::Platform::macOS;
}
static void getMSLVersion(const uint32_t _version, uint32_t& _major, uint32_t& _minor, bx::WriterI* _messageWriter)
{
bx::ErrorAssert err;
_major = _version / 1000;
_minor = (_version / 100) % 10;
switch (_version)
{
case 1000:
case 1110:
case 1210:
case 2011:
case 2111:
case 2211:
case 2314:
case 2414:
case 3014:
case 3114:
return;
default:
bx::write(_messageWriter, &err, "Warning: Unknown MSL version requested. Returning 1.0 as default.\n");
_major = 1;
_minor = 0;
}
}
static bool compile(const Options& _options, uint32_t _version, const std::string& _code, bx::WriterI* _shaderWriter, bx::WriterI* _messageWriter, bool _firstPass)
{
BX_UNUSED(_version);
@@ -294,6 +378,7 @@ namespace bgfx { namespace metal
shader->setEntryPoint("main");
shader->setAutoMapBindings(true);
shader->setEnvTarget(glslang::EShTargetSpv, getGlslangTargetSpirvVersion(_version, _messageWriter));
const int textureBindingOffset = 16;
shader->setShiftBinding(glslang::EResTexture, textureBindingOffset);
shader->setShiftBinding(glslang::EResSampler, textureBindingOffset);
@@ -503,7 +588,7 @@ namespace bgfx { namespace metal
glslang::GlslangToSpv(*intermediate, spirv, &options);
spvtools::Optimizer opt(SPV_ENV_VULKAN_1_0);
spvtools::Optimizer opt(getSpirvTargetVersion(_version, _messageWriter));
auto print_msg_to_stderr = [_messageWriter, &messageErr](
spv_message_level_t
@@ -536,7 +621,7 @@ namespace bgfx { namespace metal
{
if (g_verbose)
{
glslang::SpirvToolsDisassemble(std::cout, spirv, SPV_ENV_VULKAN_1_0);
glslang::SpirvToolsDisassemble(std::cout, spirv, getSpirvTargetVersion(_version, _messageWriter));
}
spirv_cross::CompilerReflection refl(spirv);
@@ -566,10 +651,23 @@ namespace bgfx { namespace metal
bx::Error err;
if (_version == BX_MAKEFOURCC('M', 'T', 'L', 0) )
{
spirv_cross::CompilerMSL msl(std::move(spirv) );
// Configure MSL cross compiler
spirv_cross::CompilerMSL::Options mslOptions = msl.get_msl_options();
{
// - Platform
mslOptions.platform = getMslPlatform(_options.platform);
// - MSL Version
uint32_t major, minor;
getMSLVersion(_version, major, minor, _messageWriter);
mslOptions.set_msl_version(major, minor);
}
msl.set_msl_options(mslOptions);
auto executionModel = msl.get_execution_model();
spirv_cross::MSLResourceBinding newBinding;
newBinding.stage = executionModel;
@@ -683,14 +781,7 @@ namespace bgfx { namespace metal
uint8_t nul = 0;
bx::write(_shaderWriter, nul, &err);
}
else
{
uint32_t shaderSize = (uint32_t)spirv.size() * sizeof(uint32_t);
bx::write(_shaderWriter, shaderSize, &err);
bx::write(_shaderWriter, spirv.data(), shaderSize, &err);
uint8_t nul = 0;
bx::write(_shaderWriter, nul, &err);
}
//
const uint8_t numAttr = (uint8_t)program->getNumLiveAttributes();
bx::write(_shaderWriter, numAttr, &err);