mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user