Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[shaderc] Add MSL version and Apple platform configurations - iOS / macOS #3213

Merged
merged 2 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 42 additions & 9 deletions tools/shaderc/shaderc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
//
Expand All @@ -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" },
Expand Down Expand Up @@ -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") )
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down
113 changes: 102 additions & 11 deletions tools/shaderc/shaderc_metal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Loading