mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 07:53:26 +00:00
Merge pull request #110264 from stuartcarnie/109846/metal_version
Metal: Ensure baked Metal binaries can be loaded on the minimum target OS
This commit is contained in:
commit
0e8df80231
14 changed files with 250 additions and 44 deletions
|
@ -143,11 +143,15 @@ class API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) MetalDeviceProperties {
|
|||
private:
|
||||
void init_features(id<MTLDevice> p_device);
|
||||
void init_limits(id<MTLDevice> p_device);
|
||||
void init_os_props();
|
||||
|
||||
public:
|
||||
MetalFeatures features;
|
||||
MetalLimits limits;
|
||||
|
||||
// maj * 10000 + min * 100 + patch
|
||||
uint32_t os_version;
|
||||
|
||||
SampleCount find_nearest_supported_sample_count(RenderingDevice::TextureSamples p_samples) const;
|
||||
|
||||
MetalDeviceProperties(id<MTLDevice> p_device);
|
||||
|
|
|
@ -311,9 +311,15 @@ void MetalDeviceProperties::init_limits(id<MTLDevice> p_device) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void MetalDeviceProperties::init_os_props() {
|
||||
NSOperatingSystemVersion ver = NSProcessInfo.processInfo.operatingSystemVersion;
|
||||
os_version = (uint32_t)ver.majorVersion * 10000 + (uint32_t)ver.minorVersion * 100 + (uint32_t)ver.patchVersion;
|
||||
}
|
||||
|
||||
MetalDeviceProperties::MetalDeviceProperties(id<MTLDevice> p_device) {
|
||||
init_features(p_device);
|
||||
init_limits(p_device);
|
||||
init_os_props();
|
||||
}
|
||||
|
||||
MetalDeviceProperties::~MetalDeviceProperties() {
|
||||
|
|
|
@ -103,6 +103,11 @@ extern os_log_t LOG_DRIVER;
|
|||
// Used for dynamic tracing.
|
||||
extern os_log_t LOG_INTERVALS;
|
||||
|
||||
_FORCE_INLINE_ static uint32_t make_msl_version(uint32_t major, uint32_t minor = 0, uint32_t patch = 0) {
|
||||
return (major * 10000) + (minor * 100) + patch;
|
||||
_FORCE_INLINE_ static uint32_t make_msl_version(uint32_t p_major, uint32_t p_minor = 0, uint32_t p_patch = 0) {
|
||||
return (p_major * 10000) + (p_minor * 100) + p_patch;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ static void parse_msl_version(uint32_t p_version, uint32_t &r_major, uint32_t &r_minor) {
|
||||
r_major = p_version / 10000;
|
||||
r_minor = (p_version % 10000) / 100;
|
||||
}
|
||||
|
|
|
@ -1135,12 +1135,17 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_container(const Ref
|
|||
// We need to regenerate the shader if the cache is moved to an incompatible device.
|
||||
ERR_FAIL_COND_V_MSG(device_properties->features.argument_buffers_tier < MTLArgumentBuffersTier2 && mtl_reflection_data.uses_argument_buffers(),
|
||||
RDD::ShaderID(),
|
||||
"Shader was generated with argument buffers, but device has limited support");
|
||||
"Shader was compiled with argument buffers enabled, but this device does not support them");
|
||||
|
||||
uint32_t msl_version = make_msl_version(device_properties->features.mslVersionMajor, device_properties->features.mslVersionMinor);
|
||||
ERR_FAIL_COND_V_MSG(msl_version < mtl_reflection_data.msl_version,
|
||||
RDD::ShaderID(),
|
||||
"Shader was compiled with a newer version of Metal than is available on the device.");
|
||||
"Shader was compiled for a newer version of Metal");
|
||||
|
||||
MTLGPUFamily compiled_gpu_family = static_cast<MTLGPUFamily>(mtl_reflection_data.profile.gpu);
|
||||
ERR_FAIL_COND_V_MSG(device_properties->features.highestFamily < compiled_gpu_family,
|
||||
RDD::ShaderID(),
|
||||
"Shader was generated for a newer Apple GPU");
|
||||
|
||||
MTLCompileOptions *options = [MTLCompileOptions new];
|
||||
uint32_t major = mtl_reflection_data.msl_version / 10000;
|
||||
|
@ -1181,6 +1186,9 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_container(const Ref
|
|||
|
||||
MDLibrary *library = nil;
|
||||
if (shader_data.library_size > 0) {
|
||||
ERR_FAIL_COND_V_MSG(mtl_reflection_data.os_min_version > device_properties->os_version,
|
||||
RDD::ShaderID(),
|
||||
"Metal shader binary was generated for a newer target OS");
|
||||
dispatch_data_t binary = dispatch_data_create(decompressed_code.ptr() + shader_data.source_size, shader_data.library_size, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
||||
library = [MDLibrary newLibraryWithCacheEntry:cd
|
||||
device:device
|
||||
|
|
|
@ -41,6 +41,25 @@ const uint32_t VIEW_MASK_BUFFER_INDEX = 24;
|
|||
|
||||
class RenderingShaderContainerFormatMetal;
|
||||
|
||||
class MinOsVersion {
|
||||
uint32_t version;
|
||||
|
||||
public:
|
||||
String to_compiler_os_version() const;
|
||||
bool is_null() const { return version == UINT32_MAX; }
|
||||
bool is_valid() const { return version != UINT32_MAX; }
|
||||
|
||||
MinOsVersion(const String &p_version);
|
||||
explicit MinOsVersion(uint32_t p_version) :
|
||||
version(p_version) {}
|
||||
MinOsVersion() :
|
||||
version(UINT32_MAX) {}
|
||||
|
||||
bool operator>(uint32_t p_other) {
|
||||
return version > p_other;
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief A minimal structure that defines a device profile for Metal.
|
||||
///
|
||||
/// This structure is used by the `RenderingShaderContainerMetal` class to
|
||||
|
@ -53,17 +72,20 @@ struct MetalDeviceProfile {
|
|||
iOS = 1,
|
||||
};
|
||||
|
||||
/// @brief The GPU family.
|
||||
/*! @brief The GPU family.
|
||||
*
|
||||
* NOTE: These values match Apple's MTLGPUFamily
|
||||
*/
|
||||
enum class GPU : uint32_t {
|
||||
Apple1,
|
||||
Apple2,
|
||||
Apple3,
|
||||
Apple4,
|
||||
Apple5,
|
||||
Apple6,
|
||||
Apple7,
|
||||
Apple8,
|
||||
Apple9,
|
||||
Apple1 = 1001,
|
||||
Apple2 = 1002,
|
||||
Apple3 = 1003,
|
||||
Apple4 = 1004,
|
||||
Apple5 = 1005,
|
||||
Apple6 = 1006,
|
||||
Apple7 = 1007,
|
||||
Apple8 = 1008,
|
||||
Apple9 = 1009,
|
||||
};
|
||||
|
||||
enum class ArgumentBuffersTier : uint32_t {
|
||||
|
@ -108,6 +130,13 @@ public:
|
|||
/// The Metal language version specified when compiling SPIR-V to MSL.
|
||||
/// Format is major * 10000 + minor * 100 + patch.
|
||||
uint32_t msl_version = UINT32_MAX;
|
||||
/*! @brief The minimum supported OS version for shaders baked to a `.metallib`.
|
||||
*
|
||||
* NOTE: This property is only valid when shaders are baked to a .metalllib
|
||||
*
|
||||
* Format is major * 10000 + minor * 100 + patch.
|
||||
*/
|
||||
MinOsVersion os_min_version;
|
||||
uint32_t flags = NONE;
|
||||
|
||||
/// @brief Returns `true` if the shader is compiled with multi-view support.
|
||||
|
@ -210,9 +239,23 @@ public:
|
|||
HeaderData mtl_reflection_data; // compliment to reflection_data
|
||||
Vector<StageData> mtl_shaders; // compliment to shaders
|
||||
|
||||
private:
|
||||
struct ToolchainProperties {
|
||||
MinOsVersion os_version_min_required;
|
||||
uint32_t metal_version = UINT32_MAX;
|
||||
|
||||
_FORCE_INLINE_ bool is_null() const { return os_version_min_required.is_null() || metal_version == UINT32_MAX; }
|
||||
_FORCE_INLINE_ bool is_valid() const { return !is_null(); }
|
||||
};
|
||||
|
||||
ToolchainProperties compiler_props;
|
||||
|
||||
void _initialize_toolchain_properties();
|
||||
|
||||
private:
|
||||
const MetalDeviceProfile *device_profile = nullptr;
|
||||
bool export_mode = false;
|
||||
MinOsVersion min_os_version;
|
||||
|
||||
Vector<UniformData> mtl_reflection_binding_set_uniforms_data; // compliment to reflection_binding_set_uniforms_data
|
||||
Vector<SpecializationData> mtl_reflection_specialization_data; // compliment to reflection_specialization_data
|
||||
|
@ -224,6 +267,7 @@ public:
|
|||
|
||||
void set_export_mode(bool p_export_mode) { export_mode = p_export_mode; }
|
||||
void set_device_profile(const MetalDeviceProfile *p_device_profile) { device_profile = p_device_profile; }
|
||||
void set_min_os_version(const MinOsVersion p_min_os_version) { min_os_version = p_min_os_version; }
|
||||
|
||||
struct MetalShaderReflection {
|
||||
Vector<Vector<UniformData>> uniform_sets;
|
||||
|
@ -253,6 +297,7 @@ protected:
|
|||
|
||||
class RenderingShaderContainerFormatMetal : public RenderingShaderContainerFormat {
|
||||
bool export_mode = false;
|
||||
MinOsVersion min_os_version;
|
||||
|
||||
const MetalDeviceProfile *device_profile = nullptr;
|
||||
|
||||
|
@ -260,6 +305,6 @@ public:
|
|||
virtual Ref<RenderingShaderContainer> create_container() const override;
|
||||
virtual ShaderLanguageVersion get_shader_language_version() const override;
|
||||
virtual ShaderSpirvVersion get_shader_spirv_version() const override;
|
||||
RenderingShaderContainerFormatMetal(const MetalDeviceProfile *p_device_profile, bool p_export = false);
|
||||
RenderingShaderContainerFormatMetal(const MetalDeviceProfile *p_device_profile, bool p_export = false, const MinOsVersion p_min_os_version = MinOsVersion());
|
||||
virtual ~RenderingShaderContainerFormatMetal() = default;
|
||||
};
|
||||
|
|
|
@ -28,11 +28,12 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "rendering_shader_container_metal.h"
|
||||
#import "rendering_shader_container_metal.h"
|
||||
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#import "metal_utils.h"
|
||||
|
||||
#import "core/io/marshalls.h"
|
||||
#import "servers/rendering/rendering_device.h"
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
#import <spirv.hpp>
|
||||
|
@ -85,6 +86,71 @@ const MetalDeviceProfile *MetalDeviceProfile::get_profile(MetalDeviceProfile::Pl
|
|||
return &profiles.insert(key, res)->value;
|
||||
}
|
||||
|
||||
void RenderingShaderContainerMetal::_initialize_toolchain_properties() {
|
||||
if (compiler_props.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String sdk;
|
||||
switch (device_profile->platform) {
|
||||
case MetalDeviceProfile::Platform::macOS:
|
||||
sdk = "macosx";
|
||||
break;
|
||||
case MetalDeviceProfile::Platform::iOS:
|
||||
sdk = "iphoneos";
|
||||
break;
|
||||
}
|
||||
|
||||
Vector<String> parts{ "echo", R"("")", "|", "/usr/bin/xcrun", "-sdk", sdk, "metal", "-E", "-dM", "-x", "metal", "-", "|", "grep", "-E", R"(\"__METAL_VERSION__|__ENVIRONMENT_OS\")" };
|
||||
|
||||
// Compile metal shaders for the minimum supported target instead of the host machine
|
||||
if (min_os_version.is_valid()) {
|
||||
switch (device_profile->platform) {
|
||||
case MetalDeviceProfile::Platform::macOS: {
|
||||
parts.push_back("-mmacosx-version-min=" + min_os_version.to_compiler_os_version());
|
||||
break;
|
||||
}
|
||||
case MetalDeviceProfile::Platform::iOS: {
|
||||
parts.push_back("-mios-version-min=" + min_os_version.to_compiler_os_version());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String s = " ";
|
||||
List<String> args = { "-c", String(" ").join(parts) };
|
||||
|
||||
String r_pipe;
|
||||
int exit_code;
|
||||
Error err = OS::get_singleton()->execute("sh", args, &r_pipe, &exit_code, true);
|
||||
ERR_FAIL_COND_MSG(err != OK, "Failed to determine Metal toolchain properties");
|
||||
|
||||
// Parse the lines, which are in the form:
|
||||
//
|
||||
// #define VARNAME VALUE
|
||||
Vector<String> lines = r_pipe.split("\n", false);
|
||||
for (String &line : lines) {
|
||||
Vector<String> name_val = line.trim_prefix("#define ").split(" ");
|
||||
if (name_val.size() != 2) {
|
||||
continue;
|
||||
}
|
||||
if (name_val[0] == "__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__") {
|
||||
compiler_props.os_version_min_required = MinOsVersion((uint32_t)name_val[1].to_int());
|
||||
} else if (name_val[0] == "__METAL_VERSION__") {
|
||||
uint32_t ver = (uint32_t)name_val[1].to_int();
|
||||
uint32_t maj = ver / 100;
|
||||
uint32_t min = (ver % 100) / 10;
|
||||
compiler_props.metal_version = make_msl_version(maj, min);
|
||||
}
|
||||
|
||||
if (compiler_props.is_valid()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Error RenderingShaderContainerMetal::compile_metal_source(const char *p_source, const StageData &p_stage_data, Vector<uint8_t> &r_binary_data) {
|
||||
String name(shader_name.ptr());
|
||||
if (name.contains_char(':')) {
|
||||
|
@ -115,9 +181,26 @@ Error RenderingShaderContainerMetal::compile_metal_source(const char *p_source,
|
|||
break;
|
||||
}
|
||||
|
||||
// Build the metallib binary.
|
||||
// Build the .metallib binary.
|
||||
{
|
||||
List<String> args{ "-sdk", sdk, "metal", "-O3" };
|
||||
|
||||
// Compile metal shaders for the minimum supported target instead of the host machine.
|
||||
if (min_os_version.is_valid()) {
|
||||
switch (device_profile->platform) {
|
||||
case MetalDeviceProfile::Platform::macOS: {
|
||||
args.push_back("-mmacosx-version-min=" + min_os_version.to_compiler_os_version());
|
||||
break;
|
||||
}
|
||||
case MetalDeviceProfile::Platform::iOS: {
|
||||
args.push_back("-mios-version-min=" + min_os_version.to_compiler_os_version());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WARN_PRINT_ONCE(vformat("Minimum target OS version is not set, so baking shaders for Metal will target the default version of your toolchain: %s", compiler_props.os_version_min_required.to_compiler_os_version()));
|
||||
}
|
||||
|
||||
if (p_stage_data.is_position_invariant) {
|
||||
args.push_back("-fpreserve-invariance");
|
||||
}
|
||||
|
@ -175,6 +258,10 @@ bool RenderingShaderContainerMetal::_set_code_from_spirv(const Vector<RenderingD
|
|||
using spirv_cross::CompilerMSL;
|
||||
using spirv_cross::Resource;
|
||||
|
||||
if (export_mode) {
|
||||
_initialize_toolchain_properties();
|
||||
}
|
||||
|
||||
// initialize Metal-specific reflection data
|
||||
shaders.resize(p_spirv.size());
|
||||
mtl_shaders.resize(p_spirv.size());
|
||||
|
@ -182,6 +269,7 @@ bool RenderingShaderContainerMetal::_set_code_from_spirv(const Vector<RenderingD
|
|||
mtl_reflection_specialization_data.resize(reflection_specialization_data.size());
|
||||
|
||||
mtl_reflection_data.set_needs_view_mask_buffer(reflection_data.has_multiview);
|
||||
mtl_reflection_data.profile = *device_profile;
|
||||
|
||||
// set_indexes will contain the starting offsets of each descriptor set in the binding set uniforms data
|
||||
// including the last one, which is the size of reflection_binding_set_uniforms_count.
|
||||
|
@ -199,10 +287,25 @@ bool RenderingShaderContainerMetal::_set_code_from_spirv(const Vector<RenderingD
|
|||
set_indexes[set_indexes_size - 1] = offset;
|
||||
}
|
||||
CompilerMSL::Options msl_options{};
|
||||
// MAJOR * 10000 + MINOR * 100
|
||||
uint32_t msl_version = CompilerMSL::Options::make_msl_version(device_profile->features.mslVersionMajor, device_profile->features.mslVersionMinor);
|
||||
msl_options.set_msl_version(device_profile->features.mslVersionMajor, device_profile->features.mslVersionMinor);
|
||||
mtl_reflection_data.msl_version = msl_options.msl_version;
|
||||
|
||||
// Determine Metal language version.
|
||||
uint32_t msl_version = 0;
|
||||
{
|
||||
if (export_mode && compiler_props.is_valid()) {
|
||||
// Use the properties determined by the toolchain and minimum OS version.
|
||||
msl_version = compiler_props.metal_version;
|
||||
mtl_reflection_data.os_min_version = compiler_props.os_version_min_required;
|
||||
} else {
|
||||
msl_version = make_msl_version(device_profile->features.mslVersionMajor, device_profile->features.mslVersionMinor);
|
||||
mtl_reflection_data.os_min_version = MinOsVersion();
|
||||
}
|
||||
uint32_t msl_ver_maj = 0;
|
||||
uint32_t msl_ver_min = 0;
|
||||
parse_msl_version(msl_version, msl_ver_maj, msl_ver_min);
|
||||
msl_options.set_msl_version(msl_ver_maj, msl_ver_min);
|
||||
mtl_reflection_data.msl_version = msl_version;
|
||||
}
|
||||
|
||||
msl_options.platform = device_profile->platform == MetalDeviceProfile::Platform::macOS ? CompilerMSL::Options::macOS : CompilerMSL::Options::iOS;
|
||||
|
||||
if (device_profile->platform == MetalDeviceProfile::Platform::iOS) {
|
||||
|
@ -238,7 +341,7 @@ bool RenderingShaderContainerMetal::_set_code_from_spirv(const Vector<RenderingD
|
|||
msl_options.multiview_layered_rendering = true;
|
||||
msl_options.view_mask_buffer_index = VIEW_MASK_BUFFER_INDEX;
|
||||
}
|
||||
if (msl_version >= CompilerMSL::Options::make_msl_version(3, 2)) {
|
||||
if (msl_version >= make_msl_version(3, 2)) {
|
||||
// All 3.2+ versions support device coherence, so we can disable texture fences.
|
||||
msl_options.readwrite_texture_fences = false;
|
||||
}
|
||||
|
@ -571,14 +674,20 @@ bool RenderingShaderContainerMetal::_set_code_from_spirv(const Vector<RenderingD
|
|||
memcpy(binary_data.ptrw(), source.c_str(), stage_data.source_size);
|
||||
|
||||
if (export_mode) {
|
||||
// Try to compile the Metal source code
|
||||
if (compiler_props.is_valid()) {
|
||||
// Try to compile the Metal source code.
|
||||
::Vector<uint8_t> library_data;
|
||||
Error compile_err = compile_metal_source(source.c_str(), stage_data, library_data);
|
||||
if (compile_err == OK) {
|
||||
// If we successfully compiled to a `.metallib`, there are greater restrictions on target platforms,
|
||||
// so we must update the properties.
|
||||
stage_data.library_size = library_data.size();
|
||||
binary_data.resize(stage_data.source_size + stage_data.library_size);
|
||||
memcpy(binary_data.ptrw() + stage_data.source_size, library_data.ptr(), stage_data.library_size);
|
||||
}
|
||||
} else {
|
||||
WARN_PRINT_ONCE("Metal shader baking limited to SPIR-V: Unable to determine toolchain properties to compile .metallib");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t binary_data_size = binary_data.size();
|
||||
|
@ -693,6 +802,7 @@ Ref<RenderingShaderContainer> RenderingShaderContainerFormatMetal::create_contai
|
|||
result.instantiate();
|
||||
result->set_export_mode(export_mode);
|
||||
result->set_device_profile(device_profile);
|
||||
result->set_min_os_version(min_os_version);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -704,6 +814,30 @@ RenderingDeviceCommons::ShaderSpirvVersion RenderingShaderContainerFormatMetal::
|
|||
return SHADER_SPIRV_VERSION_1_6;
|
||||
}
|
||||
|
||||
RenderingShaderContainerFormatMetal::RenderingShaderContainerFormatMetal(const MetalDeviceProfile *p_device_profile, bool p_export) :
|
||||
export_mode(p_export), device_profile(p_device_profile) {
|
||||
RenderingShaderContainerFormatMetal::RenderingShaderContainerFormatMetal(const MetalDeviceProfile *p_device_profile, bool p_export, const MinOsVersion p_min_os_version) :
|
||||
export_mode(p_export), min_os_version(p_min_os_version), device_profile(p_device_profile) {
|
||||
}
|
||||
|
||||
String MinOsVersion::to_compiler_os_version() const {
|
||||
if (version == UINT32_MAX) {
|
||||
return "";
|
||||
}
|
||||
|
||||
uint32_t major = version / 10000;
|
||||
uint32_t minor = (version % 10000) / 100;
|
||||
return vformat("%d.%d", major, minor);
|
||||
}
|
||||
|
||||
MinOsVersion::MinOsVersion(const String &p_version) {
|
||||
int pos = p_version.find_char('.');
|
||||
if (pos > 0) {
|
||||
version = (uint32_t)(p_version.substr(0, pos).to_int() * 10000 +
|
||||
p_version.substr(pos + 1).to_int() * 100);
|
||||
} else {
|
||||
version = (uint32_t)(p_version.to_int() * 10000);
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
version = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ bool ShaderBakerExportPlugin::_is_active(const Vector<String> &p_features) const
|
|||
return RendererSceneRenderRD::get_singleton() != nullptr && RendererRD::MaterialStorage::get_singleton() != nullptr && p_features.has("shader_baker");
|
||||
}
|
||||
|
||||
bool ShaderBakerExportPlugin::_initialize_container_format(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) {
|
||||
bool ShaderBakerExportPlugin::_initialize_container_format(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features, const Ref<EditorExportPreset> &p_preset) {
|
||||
Variant driver_variant = GLOBAL_GET("rendering/rendering_device/driver." + p_platform->get_os_name().to_lower());
|
||||
if (!driver_variant.is_string()) {
|
||||
driver_variant = GLOBAL_GET("rendering/rendering_device/driver");
|
||||
|
@ -67,7 +67,7 @@ bool ShaderBakerExportPlugin::_initialize_container_format(const Ref<EditorExpor
|
|||
|
||||
for (Ref<ShaderBakerExportPluginPlatform> platform : platforms) {
|
||||
if (platform->matches_driver(shader_container_driver)) {
|
||||
shader_container_format = platform->create_shader_container_format(p_platform);
|
||||
shader_container_format = platform->create_shader_container_format(p_platform, get_export_preset());
|
||||
ERR_FAIL_NULL_V_MSG(shader_container_format, false, "Unable to create shader container format for the export platform.");
|
||||
return true;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ bool ShaderBakerExportPlugin::_begin_customize_resources(const Ref<EditorExportP
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!_initialize_container_format(p_platform, p_features)) {
|
||||
if (!_initialize_container_format(p_platform, p_features, get_export_preset())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class ShaderBakerExportPluginPlatform : public RefCounted {
|
|||
GDCLASS(ShaderBakerExportPluginPlatform, RefCounted);
|
||||
|
||||
public:
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform) = 0;
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform, const Ref<EditorExportPreset> &p_preset) = 0;
|
||||
virtual bool matches_driver(const String &p_driver) = 0;
|
||||
virtual ~ShaderBakerExportPluginPlatform() {}
|
||||
};
|
||||
|
@ -82,7 +82,7 @@ protected:
|
|||
|
||||
virtual String get_name() const override;
|
||||
virtual bool _is_active(const Vector<String> &p_features) const;
|
||||
virtual bool _initialize_container_format(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features);
|
||||
virtual bool _initialize_container_format(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features, const Ref<EditorExportPreset> &p_preset);
|
||||
virtual void _cleanup_container_format();
|
||||
virtual bool _initialize_cache_directory();
|
||||
virtual bool _begin_customize_resources(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) override;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
RenderingShaderContainerFormat *ShaderBakerExportPluginPlatformD3D12::create_shader_container_format(const Ref<EditorExportPlatform> &p_platform) {
|
||||
RenderingShaderContainerFormat *ShaderBakerExportPluginPlatformD3D12::create_shader_container_format(const Ref<EditorExportPlatform> &p_platform, const Ref<EditorExportPreset> &p_preset) {
|
||||
if (lib_d3d12 == nullptr) {
|
||||
lib_d3d12 = LoadLibraryW(L"D3D12.dll");
|
||||
ERR_FAIL_NULL_V_MSG(lib_d3d12, nullptr, "Unable to load D3D12.dll.");
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
void *lib_d3d12 = nullptr;
|
||||
|
||||
public:
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform) override;
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform, const Ref<EditorExportPreset> &p_preset) override;
|
||||
virtual bool matches_driver(const String &p_driver) override;
|
||||
virtual ~ShaderBakerExportPluginPlatformD3D12() override;
|
||||
};
|
||||
|
|
|
@ -32,18 +32,22 @@
|
|||
|
||||
#include "drivers/metal/rendering_shader_container_metal.h"
|
||||
|
||||
RenderingShaderContainerFormat *ShaderBakerExportPluginPlatformMetal::create_shader_container_format(const Ref<EditorExportPlatform> &p_platform) {
|
||||
RenderingShaderContainerFormat *ShaderBakerExportPluginPlatformMetal::create_shader_container_format(const Ref<EditorExportPlatform> &p_platform, const Ref<EditorExportPreset> &p_preset) {
|
||||
const String &os_name = p_platform->get_os_name();
|
||||
const MetalDeviceProfile *profile;
|
||||
String min_os_version;
|
||||
|
||||
if (os_name == U"macOS") {
|
||||
profile = MetalDeviceProfile::get_profile(MetalDeviceProfile::Platform::macOS, MetalDeviceProfile::GPU::Apple7);
|
||||
// Godot metal doesn't support x86_64 mac so no need to worry about that version
|
||||
min_os_version = p_preset->get("application/min_macos_version_arm64");
|
||||
} else if (os_name == U"iOS") {
|
||||
profile = MetalDeviceProfile::get_profile(MetalDeviceProfile::Platform::iOS, MetalDeviceProfile::GPU::Apple7);
|
||||
min_os_version = p_preset->get("application/min_ios_version");
|
||||
} else {
|
||||
ERR_FAIL_V_MSG(nullptr, vformat("Unsupported platform: %s", os_name));
|
||||
}
|
||||
return memnew(RenderingShaderContainerFormatMetal(profile, true));
|
||||
return memnew(RenderingShaderContainerFormatMetal(profile, true, min_os_version));
|
||||
}
|
||||
|
||||
bool ShaderBakerExportPluginPlatformMetal::matches_driver(const String &p_driver) {
|
||||
|
|
|
@ -34,6 +34,6 @@
|
|||
|
||||
class ShaderBakerExportPluginPlatformMetal : public ShaderBakerExportPluginPlatform {
|
||||
public:
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform) override;
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform, const Ref<EditorExportPreset> &p_preset) override;
|
||||
virtual bool matches_driver(const String &p_driver) override;
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "drivers/vulkan/rendering_shader_container_vulkan.h"
|
||||
|
||||
RenderingShaderContainerFormat *ShaderBakerExportPluginPlatformVulkan::create_shader_container_format(const Ref<EditorExportPlatform> &p_platform) {
|
||||
RenderingShaderContainerFormat *ShaderBakerExportPluginPlatformVulkan::create_shader_container_format(const Ref<EditorExportPlatform> &p_platform, const Ref<EditorExportPreset> &p_preset) {
|
||||
return memnew(RenderingShaderContainerFormatVulkan);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,6 @@ class ShaderBakerExportPluginPlatformVulkan : public ShaderBakerExportPluginPlat
|
|||
GDCLASS(ShaderBakerExportPluginPlatformVulkan, ShaderBakerExportPluginPlatform);
|
||||
|
||||
public:
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform) override;
|
||||
virtual RenderingShaderContainerFormat *create_shader_container_format(const Ref<EditorExportPlatform> &p_platform, const Ref<EditorExportPreset> &p_preset) override;
|
||||
virtual bool matches_driver(const String &p_driver) override;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue