diff --git a/drivers/metal/metal_device_properties.cpp b/drivers/metal/metal_device_properties.cpp index e4a348629d..2fb2011789 100644 --- a/drivers/metal/metal_device_properties.cpp +++ b/drivers/metal/metal_device_properties.cpp @@ -149,6 +149,7 @@ void MetalDeviceProperties::init_features(MTL::Device *p_device) { features.quadPermute = p_device->supportsFamily(MTL::GPUFamilyApple4); features.simdPermute = p_device->supportsFamily(MTL::GPUFamilyApple6); features.simdReduction = p_device->supportsFamily(MTL::GPUFamilyApple7); + features.supports_border_color = p_device->supportsFamily(MTL::GPUFamilyApple7); features.argument_buffers_tier = p_device->argumentBuffersSupport(); features.supports_image_atomic_32_bit = p_device->supportsFamily(MTL::GPUFamilyApple6); features.supports_image_atomic_64_bit = p_device->supportsFamily(GPUFamilyApple9) || (p_device->supportsFamily(MTL::GPUFamilyApple8) && p_device->supportsFamily(MTL::GPUFamilyMac2)); diff --git a/drivers/metal/metal_device_properties.h b/drivers/metal/metal_device_properties.h index 444d5d773d..7372286aa3 100644 --- a/drivers/metal/metal_device_properties.h +++ b/drivers/metal/metal_device_properties.h @@ -118,6 +118,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) MetalFeatures { bool supports_image_atomic_32_bit = false; /**< If true, 32-bit atomic operations on images are supported by the GPU. */ bool supports_image_atomic_64_bit = false; /**< If true, 64-bit atomic operations on images are supported by the GPU. */ bool supports_native_image_atomics = false; /**< If true, native image atomic operations are supported by the OS. */ + bool supports_border_color = false; /**< If true, sampler border color (clamp-to-border) is supported. Requires Apple7+. */ bool supports_residency_sets = false; /**< If true, residency sets (MTLResidencySet) are supported by the OS. */ /*! diff --git a/drivers/metal/metal_objects_shared.cpp b/drivers/metal/metal_objects_shared.cpp index 43c42d8009..5cd831c03a 100644 --- a/drivers/metal/metal_objects_shared.cpp +++ b/drivers/metal/metal_objects_shared.cpp @@ -748,14 +748,19 @@ class MDImmediateLibrary final : public MDLibrary { NS::Error *_error = nullptr; std::mutex _cv_mutex; std::condition_variable _cv; - std::atomic _complete{ false }; - bool _ready = false; + bool _complete = false; + + void _check_and_wait() { + std::unique_lock lock(_cv_mutex); + _cv.wait(lock, [this] { return _complete; }); + } public: MDImmediateLibrary(ShaderCacheEntry *p_entry, MTL::Device *p_device, NS::String *p_source, MTL::CompileOptions *p_options); + ~MDImmediateLibrary() override; MTL::Library *get_library() override; NS::Error *get_error() override; @@ -787,28 +792,24 @@ MDImmediateLibrary::MDImmediateLibrary(ShaderCacheEntry *p_entry, ERR_PRINT(vformat(U"Error compiling shader %s: %s", p_entry->name.get_data(), error->localizedDescription()->utf8String())); } - { - std::lock_guard lock(_cv_mutex); - _ready = true; - } - _cv.notify_all(); + std::lock_guard lock(_cv_mutex); _complete = true; + _cv.notify_all(); }); } +MDImmediateLibrary::~MDImmediateLibrary() { + // Wait for the async compilation callback to complete before destroying to avoid segfault. + _check_and_wait(); +} + MTL::Library *MDImmediateLibrary::get_library() { - if (!_complete) { - std::unique_lock lock(_cv_mutex); - _cv.wait(lock, [this] { return _ready; }); - } + _check_and_wait(); return _library.get(); } NS::Error *MDImmediateLibrary::get_error() { - if (!_complete) { - std::unique_lock lock(_cv_mutex); - _cv.wait(lock, [this] { return _ready; }); - } + _check_and_wait(); return _error; } diff --git a/drivers/metal/rendering_context_driver_metal.cpp b/drivers/metal/rendering_context_driver_metal.cpp index 464f8df6f3..610fd4c45a 100644 --- a/drivers/metal/rendering_context_driver_metal.cpp +++ b/drivers/metal/rendering_context_driver_metal.cpp @@ -41,23 +41,6 @@ #include -// Selector helper for calling ObjC methods from C++ -#define _APPLE_PRIVATE_DEF_SEL(accessor, symbol) static SEL s_k##accessor = sel_registerName(symbol) -#define _APPLE_PRIVATE_SEL(accessor) (Private::Selector::s_k##accessor) - -namespace Private::Selector { - -_APPLE_PRIVATE_DEF_SEL(setOpaque_, "setOpaque:"); - -template -_NS_INLINE _Ret sendMessage(const void *pObj, SEL selector, _Args... args) { - using SendMessageProc = _Ret (*)(const void *, SEL, _Args...); - const SendMessageProc pProc = reinterpret_cast(&objc_msgSend); - return (*pProc)(pObj, selector, args...); -} - -} // namespace Private::Selector - #pragma mark - Logging os_log_t LOG_DRIVER; @@ -127,7 +110,7 @@ public: Surface(p_device), layer(p_layer) { layer->setAllowsNextDrawableTimeout(true); layer->setFramebufferOnly(true); - Private::Selector::sendMessage(layer, _APPLE_PRIVATE_SEL(setOpaque_), !OS::get_singleton()->is_layered_allowed()); + layer->setOpaque(!OS::get_singleton()->is_layered_allowed()); layer->setPixelFormat(get_pixel_format()); layer->setDevice(p_device); } @@ -252,7 +235,7 @@ public: Surface(p_device), layer(p_layer) { layer->setAllowsNextDrawableTimeout(true); layer->setFramebufferOnly(true); - Private::Selector::sendMessage(layer, _APPLE_PRIVATE_SEL(setOpaque_), !OS::get_singleton()->is_layered_allowed()); + layer->setOpaque(!OS::get_singleton()->is_layered_allowed()); layer->setPixelFormat(get_pixel_format()); layer->setDevice(p_device); #if TARGET_OS_OSX diff --git a/drivers/metal/rendering_device_driver_metal.cpp b/drivers/metal/rendering_device_driver_metal.cpp index 19b81b31b2..2943c15b07 100644 --- a/drivers/metal/rendering_device_driver_metal.cpp +++ b/drivers/metal/rendering_device_driver_metal.cpp @@ -530,7 +530,7 @@ void RenderingDeviceDriverMetal::texture_free(TextureID p_texture) { uint64_t RenderingDeviceDriverMetal::texture_get_allocation_size(TextureID p_texture) { MTL::Texture *obj = reinterpret_cast(p_texture.id); - return obj->allocatedSize(); + return NS::Object::sendMessageSafe(obj, _MTL_PRIVATE_SEL(allocatedSize)); } void RenderingDeviceDriverMetal::texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) { @@ -721,9 +721,26 @@ RDD::SamplerID RenderingDeviceDriverMetal::sampler_create(const SamplerState &p_ desc->setMinFilter(p_state.min_filter == SAMPLER_FILTER_LINEAR ? MTL::SamplerMinMagFilterLinear : MTL::SamplerMinMagFilterNearest); desc->setMipFilter(p_state.mip_filter == SAMPLER_FILTER_LINEAR ? MTL::SamplerMipFilterLinear : MTL::SamplerMipFilterNearest); - desc->setSAddressMode(ADDRESS_MODES[p_state.repeat_u]); - desc->setTAddressMode(ADDRESS_MODES[p_state.repeat_v]); - desc->setRAddressMode(ADDRESS_MODES[p_state.repeat_w]); + MTL::SamplerAddressMode address_u = ADDRESS_MODES[p_state.repeat_u]; + MTL::SamplerAddressMode address_v = ADDRESS_MODES[p_state.repeat_v]; + MTL::SamplerAddressMode address_w = ADDRESS_MODES[p_state.repeat_w]; + + if (!device_properties->features.supports_border_color) { + // Default to clamp to edge if border color is not supported. + if (address_u == MTL::SamplerAddressModeClampToBorderColor) { + address_u = MTL::SamplerAddressModeClampToEdge; + } + if (address_v == MTL::SamplerAddressModeClampToBorderColor) { + address_v = MTL::SamplerAddressModeClampToEdge; + } + if (address_w == MTL::SamplerAddressModeClampToBorderColor) { + address_w = MTL::SamplerAddressModeClampToEdge; + } + } + + desc->setSAddressMode(address_u); + desc->setTAddressMode(address_v); + desc->setRAddressMode(address_w); if (p_state.use_anisotropy) { desc->setMaxAnisotropy(p_state.anisotropy_max); @@ -734,7 +751,9 @@ RDD::SamplerID RenderingDeviceDriverMetal::sampler_create(const SamplerState &p_ desc->setLodMinClamp(p_state.min_lod); desc->setLodMaxClamp(p_state.max_lod); - desc->setBorderColor(SAMPLER_BORDER_COLORS[p_state.border_color]); + if (device_properties->features.supports_border_color) { + desc->setBorderColor(SAMPLER_BORDER_COLORS[p_state.border_color]); + } desc->setNormalizedCoordinates(!p_state.unnormalized_uvw); diff --git a/drivers/metal/rendering_device_driver_metal3.cpp b/drivers/metal/rendering_device_driver_metal3.cpp index e2a1e4020f..2aec81478d 100644 --- a/drivers/metal/rendering_device_driver_metal3.cpp +++ b/drivers/metal/rendering_device_driver_metal3.cpp @@ -151,7 +151,12 @@ void RenderingDeviceDriverMetal::remove_residency_set_to_main_queue(MTL::Residen #pragma mark - Fences RDD::FenceID RenderingDeviceDriverMetal::fence_create() { - Fence *fence = memnew(FenceEvent(NS::TransferPtr(device->newSharedEvent()))); + Fence *fence = nullptr; + if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, visionOS 1.0, *)) { + fence = memnew(FenceEvent(NS::TransferPtr(device->newSharedEvent()))); + } else { + fence = memnew(FenceSemaphore()); + } return FenceID(fence); } diff --git a/thirdparty/metal-cpp/Foundation/NSData.hpp b/thirdparty/metal-cpp/Foundation/NSData.hpp index fbf3f20343..03576df538 100644 --- a/thirdparty/metal-cpp/Foundation/NSData.hpp +++ b/thirdparty/metal-cpp/Foundation/NSData.hpp @@ -33,8 +33,8 @@ class Data : public Copying { public: void* mutableBytes() const; - void* bytes() const; UInteger length() const; + const void * bytes() const; }; } @@ -45,11 +45,6 @@ _NS_INLINE void* NS::Data::mutableBytes() const return Object::sendMessage(this, _NS_PRIVATE_SEL(mutableBytes)); } -_NS_INLINE void* NS::Data::bytes() const -{ - return Object::sendMessage(this, _NS_PRIVATE_SEL(bytes)); -} - //------------------------------------------------------------------------------------------------------------------------------------------------------------- _NS_INLINE NS::UInteger NS::Data::length() const @@ -57,4 +52,9 @@ _NS_INLINE NS::UInteger NS::Data::length() const return Object::sendMessage(this, _NS_PRIVATE_SEL(length)); } +_NS_INLINE const void * NS::Data::bytes() const +{ + return Object::sendMessage(this, _NS_PRIVATE_SEL(bytes)); +} + //------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/thirdparty/metal-cpp/Foundation/NSObject.hpp b/thirdparty/metal-cpp/Foundation/NSObject.hpp index 4633ac66e1..828c18cd4f 100644 --- a/thirdparty/metal-cpp/Foundation/NSObject.hpp +++ b/thirdparty/metal-cpp/Foundation/NSObject.hpp @@ -35,8 +35,6 @@ namespace NS { -class String; - template class _NS_EXPORT Referencing : public _Base { @@ -70,6 +68,12 @@ public: class String* description() const; class String* debugDescription() const; + template + static _Ret sendMessage(const void* pObj, SEL selector, _Args... args); + + template + static _Ret sendMessageSafe(const void* pObj, SEL selector, _Args... args); + protected: friend class Referencing; @@ -86,10 +90,6 @@ protected: static bool respondsToSelector(const void* pObj, SEL selector); template static constexpr bool doesRequireMsgSendStret(); - template - static _Ret sendMessage(const void* pObj, SEL selector, _Args... args); - template - static _Ret sendMessageSafe(const void* pObj, SEL selector, _Args... args); private: Object() = delete; diff --git a/thirdparty/metal-cpp/Foundation/NSPrivate.hpp b/thirdparty/metal-cpp/Foundation/NSPrivate.hpp index 17909fbd2a..12a14636f7 100644 --- a/thirdparty/metal-cpp/Foundation/NSPrivate.hpp +++ b/thirdparty/metal-cpp/Foundation/NSPrivate.hpp @@ -184,6 +184,8 @@ namespace Private "bundleWithPath:"); _NS_PRIVATE_DEF_SEL(bundleWithURL_, "bundleWithURL:"); + _NS_PRIVATE_DEF_SEL(bytes, + "bytes"); _NS_PRIVATE_DEF_SEL(caseInsensitiveCompare_, "caseInsensitiveCompare:"); _NS_PRIVATE_DEF_SEL(characterAtIndex_, @@ -268,12 +270,12 @@ namespace Private "initFileURLWithPath:"); _NS_PRIVATE_DEF_SEL(initWithBool_, "initWithBool:"); + _NS_PRIVATE_DEF_SEL(initWithBytes_length_encoding_, + "initWithBytes:length:encoding:"); _NS_PRIVATE_DEF_SEL(initWithBytes_objCType_, "initWithBytes:objCType:"); _NS_PRIVATE_DEF_SEL(initWithBytesNoCopy_length_encoding_freeWhenDone_, "initWithBytesNoCopy:length:encoding:freeWhenDone:"); - _NS_PRIVATE_DEF_SEL(initWithBytes_length_encoding_, - "initWithBytes:length:encoding:"); _NS_PRIVATE_DEF_SEL(initWithChar_, "initWithChar:"); _NS_PRIVATE_DEF_SEL(initWithCoder_, @@ -374,8 +376,6 @@ namespace Private "methodSignatureForSelector:"); _NS_PRIVATE_DEF_SEL(mutableBytes, "mutableBytes"); - _NS_PRIVATE_DEF_SEL(bytes, - "bytes"); _NS_PRIVATE_DEF_SEL(name, "name"); _NS_PRIVATE_DEF_SEL(nextObject, diff --git a/thirdparty/metal-cpp/Foundation/NSString.hpp b/thirdparty/metal-cpp/Foundation/NSString.hpp index d4d0c52ec2..654584e29c 100644 --- a/thirdparty/metal-cpp/Foundation/NSString.hpp +++ b/thirdparty/metal-cpp/Foundation/NSString.hpp @@ -87,7 +87,6 @@ public: String* init(); String* init(const String* pString); String* init(const char* pString, StringEncoding encoding); - String* init(void* pBytes, UInteger len, StringEncoding encoding); String* init(void* pBytes, UInteger len, StringEncoding encoding, bool freeBuffer); unichar character(UInteger index) const; @@ -105,6 +104,7 @@ public: String* stringByAppendingString(const String* pString) const; ComparisonResult caseInsensitiveCompare(const String* pString) const; + NS::String* init(const void * bytes, NS::UInteger len, NS::StringEncoding encoding); }; /// Create an NS::String* from a string literal. @@ -122,7 +122,7 @@ template _NS_INLINE NS::String* NS::String::string() { - return sendMessage(_NS_PRIVATE_CLS(NSString), _NS_PRIVATE_SEL(string)); + return Object::sendMessage(_NS_PRIVATE_CLS(NSString), _NS_PRIVATE_SEL(string)); } //------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -169,12 +169,6 @@ _NS_INLINE NS::String* NS::String::init(const char* pString, StringEncoding enco //------------------------------------------------------------------------------------------------------------------------------------------------------------- -_NS_INLINE NS::String* NS::String::init(void* pBytes, UInteger len, StringEncoding encoding) -{ - return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithBytes_length_encoding_), pBytes, len, encoding); -} -//------------------------------------------------------------------------------------------------------------------------------------------------------------- - _NS_INLINE NS::String* NS::String::init(void* pBytes, UInteger len, StringEncoding encoding, bool freeBuffer) { return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithBytesNoCopy_length_encoding_freeWhenDone_), pBytes, len, encoding, freeBuffer); @@ -259,4 +253,9 @@ _NS_INLINE NS::ComparisonResult NS::String::caseInsensitiveCompare(const String* return Object::sendMessage(this, _NS_PRIVATE_SEL(caseInsensitiveCompare_), pString); } +_NS_INLINE NS::String* NS::String::init(const void * bytes, NS::UInteger len, NS::StringEncoding encoding) +{ + return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithBytes_length_encoding_), bytes, len, encoding); +} + //------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/thirdparty/metal-cpp/QuartzCore/CALayer.hpp b/thirdparty/metal-cpp/QuartzCore/CALayer.hpp new file mode 100644 index 0000000000..9e0e720043 --- /dev/null +++ b/thirdparty/metal-cpp/QuartzCore/CALayer.hpp @@ -0,0 +1,79 @@ +#pragma once + +#include "CADefines.hpp" +#include "CAPrivate.hpp" +#include "../Foundation/NSObject.hpp" +#include + +namespace CA +{ +using DynamicRange = NS::String*; + +_CA_CONST(DynamicRange, DynamicRangeAutomatic); +_CA_CONST(DynamicRange, DynamicRangeStandard); +_CA_CONST(DynamicRange, DynamicRangeConstrainedHigh); +_CA_CONST(DynamicRange, DynamicRangeHigh); + + +class Layer : public NS::Referencing +{ +public: + bool wantsExtendedDynamicRangeContent() const; + void setWantsExtendedDynamicRangeContent(bool wantsExtendedDynamicRangeContent); + CA::DynamicRange preferredDynamicRange() const; + void setPreferredDynamicRange(CA::DynamicRange preferredDynamicRange); + CGFloat contentsHeadroom() const; + void setContentsHeadroom(CGFloat contentsHeadroom); + bool opaque() const; + void setOpaque(bool opaque); + +}; + +} // namespace CA + +// --- Inline implementations --- + +_CA_INLINE bool CA::Layer::wantsExtendedDynamicRangeContent() const +{ + return Object::sendMessage(this, _CA_PRIVATE_SEL(wantsExtendedDynamicRangeContent)); +} + +_CA_INLINE void CA::Layer::setWantsExtendedDynamicRangeContent(bool wantsExtendedDynamicRangeContent) +{ + Object::sendMessage(this, _CA_PRIVATE_SEL(setWantsExtendedDynamicRangeContent_), wantsExtendedDynamicRangeContent); +} + +_CA_INLINE CA::DynamicRange CA::Layer::preferredDynamicRange() const +{ + return Object::sendMessage(this, _CA_PRIVATE_SEL(preferredDynamicRange)); +} + +_CA_INLINE void CA::Layer::setPreferredDynamicRange(CA::DynamicRange preferredDynamicRange) +{ + Object::sendMessage(this, _CA_PRIVATE_SEL(setPreferredDynamicRange_), preferredDynamicRange); +} + +_CA_INLINE CGFloat CA::Layer::contentsHeadroom() const +{ + return Object::sendMessage(this, _CA_PRIVATE_SEL(contentsHeadroom)); +} + +_CA_INLINE void CA::Layer::setContentsHeadroom(CGFloat contentsHeadroom) +{ + Object::sendMessage(this, _CA_PRIVATE_SEL(setContentsHeadroom_), contentsHeadroom); +} + +_CA_INLINE bool CA::Layer::opaque() const +{ + return Object::sendMessage(this, _CA_PRIVATE_SEL(opaque)); +} + +_CA_INLINE void CA::Layer::setOpaque(bool opaque) +{ + Object::sendMessage(this, _CA_PRIVATE_SEL(setOpaque_), opaque); +} + +_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeAutomatic); +_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeStandard); +_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeConstrainedHigh); +_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeHigh); diff --git a/thirdparty/metal-cpp/QuartzCore/CAMetalLayer.hpp b/thirdparty/metal-cpp/QuartzCore/CAMetalLayer.hpp index 53f6857d2a..8dfb0ae33b 100644 --- a/thirdparty/metal-cpp/QuartzCore/CAMetalLayer.hpp +++ b/thirdparty/metal-cpp/QuartzCore/CAMetalLayer.hpp @@ -32,13 +32,14 @@ #include "CADefines.hpp" #include "CAMetalDrawable.hpp" #include "CAPrivate.hpp" +#include "CALayer.hpp" //------------------------------------------------------------------------------------------------------------------------------------------------------------- namespace CA { -class MetalLayer : public NS::Referencing +class MetalLayer : public NS::Referencing { public: static class MetalLayer* layer(); diff --git a/thirdparty/metal-cpp/QuartzCore/CAPrivate.hpp b/thirdparty/metal-cpp/QuartzCore/CAPrivate.hpp index 0b7486a751..3d612a2607 100644 --- a/thirdparty/metal-cpp/QuartzCore/CAPrivate.hpp +++ b/thirdparty/metal-cpp/QuartzCore/CAPrivate.hpp @@ -76,6 +76,7 @@ namespace Private namespace Class { _CA_PRIVATE_DEF_CLS(CAMetalLayer); + _CA_PRIVATE_DEF_CLS(CALayer); } // Class } // Private } // CA @@ -107,6 +108,8 @@ namespace Private "allowsNextDrawableTimeout"); _CA_PRIVATE_DEF_SEL(colorspace, "colorspace"); + _CA_PRIVATE_DEF_SEL(contentsHeadroom, + "contentsHeadroom"); _CA_PRIVATE_DEF_SEL(device, "device"); _CA_PRIVATE_DEF_SEL(displaySyncEnabled, @@ -121,14 +124,20 @@ namespace Private "maximumDrawableCount"); _CA_PRIVATE_DEF_SEL(nextDrawable, "nextDrawable"); + _CA_PRIVATE_DEF_SEL(opaque, + "opaque"); _CA_PRIVATE_DEF_SEL(pixelFormat, "pixelFormat"); + _CA_PRIVATE_DEF_SEL(preferredDynamicRange, + "preferredDynamicRange"); _CA_PRIVATE_DEF_SEL(residencySet, "residencySet"); _CA_PRIVATE_DEF_SEL(setAllowsNextDrawableTimeout_, "setAllowsNextDrawableTimeout:"); _CA_PRIVATE_DEF_SEL(setColorspace_, "setColorspace:"); + _CA_PRIVATE_DEF_SEL(setContentsHeadroom_, + "setContentsHeadroom:"); _CA_PRIVATE_DEF_SEL(setDevice_, "setDevice:"); _CA_PRIVATE_DEF_SEL(setDisplaySyncEnabled_, @@ -139,10 +148,19 @@ namespace Private "setFramebufferOnly:"); _CA_PRIVATE_DEF_SEL(setMaximumDrawableCount_, "setMaximumDrawableCount:"); + _CA_PRIVATE_DEF_SEL(setOpaque_, + "setOpaque:"); _CA_PRIVATE_DEF_SEL(setPixelFormat_, "setPixelFormat:"); + _CA_PRIVATE_DEF_SEL(setPreferredDynamicRange_, + "setPreferredDynamicRange:"); + _CA_PRIVATE_DEF_SEL(setWantsExtendedDynamicRangeContent_, + "setWantsExtendedDynamicRangeContent:"); _CA_PRIVATE_DEF_SEL(texture, "texture"); + _CA_PRIVATE_DEF_SEL(wantsExtendedDynamicRangeContent, + "wantsExtendedDynamicRangeContent"); + } // Class } // Private } // CA diff --git a/thirdparty/metal-cpp/QuartzCore/QuartzCore.hpp b/thirdparty/metal-cpp/QuartzCore/QuartzCore.hpp index 681003ad60..01418e0c15 100644 --- a/thirdparty/metal-cpp/QuartzCore/QuartzCore.hpp +++ b/thirdparty/metal-cpp/QuartzCore/QuartzCore.hpp @@ -22,6 +22,7 @@ //------------------------------------------------------------------------------------------------------------------------------------------------------------- +#include "CALayer.hpp" #include "CAMetalDrawable.hpp" #include "CAMetalLayer.hpp" diff --git a/thirdparty/metal-cpp/patches/0001-add-missing-apis.patch b/thirdparty/metal-cpp/patches/0001-add-missing-apis.patch index 0afcbaed09..ec471ef53b 100644 --- a/thirdparty/metal-cpp/patches/0001-add-missing-apis.patch +++ b/thirdparty/metal-cpp/patches/0001-add-missing-apis.patch @@ -1,76 +1,288 @@ - thirdparty/metal-cpp/Foundation/NSData.hpp | 6 ++++++ - thirdparty/metal-cpp/Foundation/NSPrivate.hpp | 4 ++++ - thirdparty/metal-cpp/Foundation/NSString.hpp | 7 +++++++ - 3 files changed, 17 insertions(+) - -diff --git a/thirdparty/metal-cpp/Foundation/NSData.hpp b/thirdparty/metal-cpp/Foundation/NSData.hpp -index 3ad360609f..fbf3f20343 100644 ---- a/thirdparty/metal-cpp/Foundation/NSData.hpp -+++ b/thirdparty/metal-cpp/Foundation/NSData.hpp -@@ -33,6 +33,7 @@ class Data : public Copying - { +diff -ruN original/Foundation/NSData.hpp patched/Foundation/NSData.hpp +--- original/Foundation/NSData.hpp 2026-02-16 15:06:52 ++++ patched/Foundation/NSData.hpp 2026-02-16 15:06:52 +@@ -34,6 +34,7 @@ public: void* mutableBytes() const; -+ void* bytes() const; UInteger length() const; ++ const void * bytes() const; }; } -@@ -44,6 +45,11 @@ _NS_INLINE void* NS::Data::mutableBytes() const - return Object::sendMessage(this, _NS_PRIVATE_SEL(mutableBytes)); + +@@ -49,6 +50,11 @@ + _NS_INLINE NS::UInteger NS::Data::length() const + { + return Object::sendMessage(this, _NS_PRIVATE_SEL(length)); ++} ++ ++_NS_INLINE const void * NS::Data::bytes() const ++{ ++ return Object::sendMessage(this, _NS_PRIVATE_SEL(bytes)); } -+_NS_INLINE void* NS::Data::bytes() const -+{ -+ return Object::sendMessage(this, _NS_PRIVATE_SEL(bytes)); -+} -+ + //------------------------------------------------------------------------------------------------------------------------------------------------------------- +diff -ruN original/Foundation/NSDefines.hpp patched/Foundation/NSDefines.hpp +--- original/Foundation/NSDefines.hpp 2026-02-16 15:06:52 ++++ patched/Foundation/NSDefines.hpp 2026-02-16 15:06:52 +@@ -22,6 +22,16 @@ + //------------------------------------------------------------------------------------------------------------------------------------------------------------- - _NS_INLINE NS::UInteger NS::Data::length() const -diff --git a/thirdparty/metal-cpp/Foundation/NSPrivate.hpp b/thirdparty/metal-cpp/Foundation/NSPrivate.hpp -index f8d87004f3..17909fbd2a 100644 ---- a/thirdparty/metal-cpp/Foundation/NSPrivate.hpp -+++ b/thirdparty/metal-cpp/Foundation/NSPrivate.hpp -@@ -272,6 +272,8 @@ namespace Private - "initWithBytes:objCType:"); - _NS_PRIVATE_DEF_SEL(initWithBytesNoCopy_length_encoding_freeWhenDone_, - "initWithBytesNoCopy:length:encoding:freeWhenDone:"); -+ _NS_PRIVATE_DEF_SEL(initWithBytes_length_encoding_, -+ "initWithBytes:length:encoding:"); - _NS_PRIVATE_DEF_SEL(initWithChar_, - "initWithChar:"); - _NS_PRIVATE_DEF_SEL(initWithCoder_, -@@ -372,6 +374,8 @@ namespace Private - "methodSignatureForSelector:"); - _NS_PRIVATE_DEF_SEL(mutableBytes, - "mutableBytes"); ++// Forward declarations to avoid conflicts with Godot types (String, Object, Error) ++namespace NS { ++class Array; ++class Dictionary; ++class Error; ++class Object; ++class String; ++class URL; ++} // namespace NS ++ + #define _NS_WEAK_IMPORT __attribute__((weak_import)) + #ifdef METALCPP_SYMBOL_VISIBILITY_HIDDEN + #define _NS_EXPORT __attribute__((visibility("hidden"))) +diff -ruN original/Foundation/NSObject.hpp patched/Foundation/NSObject.hpp +--- original/Foundation/NSObject.hpp 2026-02-16 15:06:52 ++++ patched/Foundation/NSObject.hpp 2026-02-16 15:06:52 +@@ -68,6 +68,12 @@ + class String* description() const; + class String* debugDescription() const; + ++ template ++ static _Ret sendMessage(const void* pObj, SEL selector, _Args... args); ++ ++ template ++ static _Ret sendMessageSafe(const void* pObj, SEL selector, _Args... args); ++ + protected: + friend class Referencing; + +@@ -84,10 +90,6 @@ + static bool respondsToSelector(const void* pObj, SEL selector); + template + static constexpr bool doesRequireMsgSendStret(); +- template +- static _Ret sendMessage(const void* pObj, SEL selector, _Args... args); +- template +- static _Ret sendMessageSafe(const void* pObj, SEL selector, _Args... args); + + private: + Object() = delete; +diff -ruN original/Foundation/NSPrivate.hpp patched/Foundation/NSPrivate.hpp +--- original/Foundation/NSPrivate.hpp 2026-02-16 15:06:52 ++++ patched/Foundation/NSPrivate.hpp 2026-02-16 15:06:52 +@@ -184,6 +184,8 @@ + "bundleWithPath:"); + _NS_PRIVATE_DEF_SEL(bundleWithURL_, + "bundleWithURL:"); + _NS_PRIVATE_DEF_SEL(bytes, + "bytes"); - _NS_PRIVATE_DEF_SEL(name, - "name"); - _NS_PRIVATE_DEF_SEL(nextObject, -diff --git a/thirdparty/metal-cpp/Foundation/NSString.hpp b/thirdparty/metal-cpp/Foundation/NSString.hpp -index 07ba3f8d39..d4d0c52ec2 100644 ---- a/thirdparty/metal-cpp/Foundation/NSString.hpp -+++ b/thirdparty/metal-cpp/Foundation/NSString.hpp -@@ -87,6 +87,7 @@ public: - String* init(); - String* init(const String* pString); - String* init(const char* pString, StringEncoding encoding); -+ String* init(void* pBytes, UInteger len, StringEncoding encoding); - String* init(void* pBytes, UInteger len, StringEncoding encoding, bool freeBuffer); + _NS_PRIVATE_DEF_SEL(caseInsensitiveCompare_, + "caseInsensitiveCompare:"); + _NS_PRIVATE_DEF_SEL(characterAtIndex_, +@@ -268,6 +270,8 @@ + "initFileURLWithPath:"); + _NS_PRIVATE_DEF_SEL(initWithBool_, + "initWithBool:"); ++ _NS_PRIVATE_DEF_SEL(initWithBytes_length_encoding_, ++ "initWithBytes:length:encoding:"); + _NS_PRIVATE_DEF_SEL(initWithBytes_objCType_, + "initWithBytes:objCType:"); + _NS_PRIVATE_DEF_SEL(initWithBytesNoCopy_length_encoding_freeWhenDone_, +diff -ruN original/Foundation/NSString.hpp patched/Foundation/NSString.hpp +--- original/Foundation/NSString.hpp 2026-02-16 15:06:52 ++++ patched/Foundation/NSString.hpp 2026-02-16 15:06:52 +@@ -104,6 +104,7 @@ - unichar character(UInteger index) const; -@@ -168,6 +169,12 @@ _NS_INLINE NS::String* NS::String::init(const char* pString, StringEncoding enco + String* stringByAppendingString(const String* pString) const; + ComparisonResult caseInsensitiveCompare(const String* pString) const; ++ NS::String* init(const void * bytes, NS::UInteger len, NS::StringEncoding encoding); + }; + + /// Create an NS::String* from a string literal. +@@ -250,6 +251,11 @@ + _NS_INLINE NS::ComparisonResult NS::String::caseInsensitiveCompare(const String* pString) const + { + return Object::sendMessage(this, _NS_PRIVATE_SEL(caseInsensitiveCompare_), pString); ++} ++ ++_NS_INLINE NS::String* NS::String::init(const void * bytes, NS::UInteger len, NS::StringEncoding encoding) ++{ ++ return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithBytes_length_encoding_), bytes, len, encoding); + } + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- +diff -ruN original/QuartzCore/CALayer.hpp patched/QuartzCore/CALayer.hpp +--- original/QuartzCore/CALayer.hpp 1970-01-01 11:00:00 ++++ patched/QuartzCore/CALayer.hpp 2026-02-16 15:06:52 +@@ -0,0 +1,79 @@ ++#pragma once ++ ++#include "CADefines.hpp" ++#include "CAPrivate.hpp" ++#include "../Foundation/NSObject.hpp" ++#include ++ ++namespace CA ++{ ++using DynamicRange = NS::String*; ++ ++_CA_CONST(DynamicRange, DynamicRangeAutomatic); ++_CA_CONST(DynamicRange, DynamicRangeStandard); ++_CA_CONST(DynamicRange, DynamicRangeConstrainedHigh); ++_CA_CONST(DynamicRange, DynamicRangeHigh); ++ ++ ++class Layer : public NS::Referencing ++{ ++public: ++ bool wantsExtendedDynamicRangeContent() const; ++ void setWantsExtendedDynamicRangeContent(bool wantsExtendedDynamicRangeContent); ++ CA::DynamicRange preferredDynamicRange() const; ++ void setPreferredDynamicRange(CA::DynamicRange preferredDynamicRange); ++ CGFloat contentsHeadroom() const; ++ void setContentsHeadroom(CGFloat contentsHeadroom); ++ bool opaque() const; ++ void setOpaque(bool opaque); ++ ++}; ++ ++} // namespace CA ++ ++// --- Inline implementations --- ++ ++_CA_INLINE bool CA::Layer::wantsExtendedDynamicRangeContent() const ++{ ++ return Object::sendMessage(this, _CA_PRIVATE_SEL(wantsExtendedDynamicRangeContent)); ++} ++ ++_CA_INLINE void CA::Layer::setWantsExtendedDynamicRangeContent(bool wantsExtendedDynamicRangeContent) ++{ ++ Object::sendMessage(this, _CA_PRIVATE_SEL(setWantsExtendedDynamicRangeContent_), wantsExtendedDynamicRangeContent); ++} ++ ++_CA_INLINE CA::DynamicRange CA::Layer::preferredDynamicRange() const ++{ ++ return Object::sendMessage(this, _CA_PRIVATE_SEL(preferredDynamicRange)); ++} ++ ++_CA_INLINE void CA::Layer::setPreferredDynamicRange(CA::DynamicRange preferredDynamicRange) ++{ ++ Object::sendMessage(this, _CA_PRIVATE_SEL(setPreferredDynamicRange_), preferredDynamicRange); ++} ++ ++_CA_INLINE CGFloat CA::Layer::contentsHeadroom() const ++{ ++ return Object::sendMessage(this, _CA_PRIVATE_SEL(contentsHeadroom)); ++} ++ ++_CA_INLINE void CA::Layer::setContentsHeadroom(CGFloat contentsHeadroom) ++{ ++ Object::sendMessage(this, _CA_PRIVATE_SEL(setContentsHeadroom_), contentsHeadroom); ++} ++ ++_CA_INLINE bool CA::Layer::opaque() const ++{ ++ return Object::sendMessage(this, _CA_PRIVATE_SEL(opaque)); ++} ++ ++_CA_INLINE void CA::Layer::setOpaque(bool opaque) ++{ ++ Object::sendMessage(this, _CA_PRIVATE_SEL(setOpaque_), opaque); ++} ++ ++_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeAutomatic); ++_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeStandard); ++_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeConstrainedHigh); ++_CA_PRIVATE_DEF_STR(CA::DynamicRange, DynamicRangeHigh); +diff -ruN original/QuartzCore/CAMetalLayer.hpp patched/QuartzCore/CAMetalLayer.hpp +--- original/QuartzCore/CAMetalLayer.hpp 2026-02-16 15:06:52 ++++ patched/QuartzCore/CAMetalLayer.hpp 2026-02-16 15:06:52 +@@ -32,13 +32,14 @@ + #include "CADefines.hpp" + #include "CAMetalDrawable.hpp" + #include "CAPrivate.hpp" ++#include "CALayer.hpp" //------------------------------------------------------------------------------------------------------------------------------------------------------------- -+_NS_INLINE NS::String* NS::String::init(void* pBytes, UInteger len, StringEncoding encoding) -+{ -+ return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithBytes_length_encoding_), pBytes, len, encoding); -+} -+//------------------------------------------------------------------------------------------------------------------------------------------------------------- -+ - _NS_INLINE NS::String* NS::String::init(void* pBytes, UInteger len, StringEncoding encoding, bool freeBuffer) + namespace CA { - return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithBytesNoCopy_length_encoding_freeWhenDone_), pBytes, len, encoding, freeBuffer); + +-class MetalLayer : public NS::Referencing ++class MetalLayer : public NS::Referencing + { + public: + static class MetalLayer* layer(); +diff -ruN original/QuartzCore/CAPrivate.hpp patched/QuartzCore/CAPrivate.hpp +--- original/QuartzCore/CAPrivate.hpp 2026-02-16 15:06:52 ++++ patched/QuartzCore/CAPrivate.hpp 2026-02-16 15:06:52 +@@ -76,6 +76,7 @@ + namespace Class + { + _CA_PRIVATE_DEF_CLS(CAMetalLayer); ++ _CA_PRIVATE_DEF_CLS(CALayer); + } // Class + } // Private + } // CA +@@ -107,6 +108,8 @@ + "allowsNextDrawableTimeout"); + _CA_PRIVATE_DEF_SEL(colorspace, + "colorspace"); ++ _CA_PRIVATE_DEF_SEL(contentsHeadroom, ++ "contentsHeadroom"); + _CA_PRIVATE_DEF_SEL(device, + "device"); + _CA_PRIVATE_DEF_SEL(displaySyncEnabled, +@@ -121,14 +124,20 @@ + "maximumDrawableCount"); + _CA_PRIVATE_DEF_SEL(nextDrawable, + "nextDrawable"); ++ _CA_PRIVATE_DEF_SEL(opaque, ++ "opaque"); + _CA_PRIVATE_DEF_SEL(pixelFormat, + "pixelFormat"); ++ _CA_PRIVATE_DEF_SEL(preferredDynamicRange, ++ "preferredDynamicRange"); + _CA_PRIVATE_DEF_SEL(residencySet, + "residencySet"); + _CA_PRIVATE_DEF_SEL(setAllowsNextDrawableTimeout_, + "setAllowsNextDrawableTimeout:"); + _CA_PRIVATE_DEF_SEL(setColorspace_, + "setColorspace:"); ++ _CA_PRIVATE_DEF_SEL(setContentsHeadroom_, ++ "setContentsHeadroom:"); + _CA_PRIVATE_DEF_SEL(setDevice_, + "setDevice:"); + _CA_PRIVATE_DEF_SEL(setDisplaySyncEnabled_, +@@ -139,10 +148,19 @@ + "setFramebufferOnly:"); + _CA_PRIVATE_DEF_SEL(setMaximumDrawableCount_, + "setMaximumDrawableCount:"); ++ _CA_PRIVATE_DEF_SEL(setOpaque_, ++ "setOpaque:"); + _CA_PRIVATE_DEF_SEL(setPixelFormat_, + "setPixelFormat:"); ++ _CA_PRIVATE_DEF_SEL(setPreferredDynamicRange_, ++ "setPreferredDynamicRange:"); ++ _CA_PRIVATE_DEF_SEL(setWantsExtendedDynamicRangeContent_, ++ "setWantsExtendedDynamicRangeContent:"); + _CA_PRIVATE_DEF_SEL(texture, + "texture"); ++ _CA_PRIVATE_DEF_SEL(wantsExtendedDynamicRangeContent, ++ "wantsExtendedDynamicRangeContent"); ++ + } // Class + } // Private + } // CA +diff -ruN original/QuartzCore/QuartzCore.hpp patched/QuartzCore/QuartzCore.hpp +--- original/QuartzCore/QuartzCore.hpp 2026-02-16 15:06:52 ++++ patched/QuartzCore/QuartzCore.hpp 2026-02-16 15:06:52 +@@ -22,6 +22,7 @@ + + //------------------------------------------------------------------------------------------------------------------------------------------------------------- + ++#include "CALayer.hpp" + #include "CAMetalDrawable.hpp" + #include "CAMetalLayer.hpp" + diff --git a/thirdparty/metal-cpp/update-metal-cpp.sh b/thirdparty/metal-cpp/update-metal-cpp.sh index ba3453052c..19e42b8c81 100755 --- a/thirdparty/metal-cpp/update-metal-cpp.sh +++ b/thirdparty/metal-cpp/update-metal-cpp.sh @@ -58,39 +58,4 @@ else echo " Warning: $PATCH_DIR not found" fi -# Patch 1: Add forward declarations to NSDefines.hpp to avoid conflicts with -# Godot's global types (String, Object, Error). -# -# Without this patch, metal-cpp's "class String*" forward declarations conflict -# with Godot's ::String, ::Object, and ::Error types. - -NSDEFINES="$SCRIPT_DIR/Foundation/NSDefines.hpp" - -if [ -f "$NSDEFINES" ]; then - # Check if patch already applied - if grep -q "Forward declarations to avoid conflicts with Godot" "$NSDEFINES"; then - echo " NSDefines.hpp: already patched" - else - # Find the line with #pragma once and insert after the next separator - sed -i '' '/^#pragma once$/,/^\/\/---/{ - /^\/\/---/ { - a\ -\ -// Forward declarations to avoid conflicts with Godot types (String, Object, Error)\ -namespace NS {\ -class Array;\ -class Dictionary;\ -class Error;\ -class Object;\ -class String;\ -class URL;\ -} // namespace NS - } - }' "$NSDEFINES" - echo " NSDefines.hpp: patched" - fi -else - echo " Warning: $NSDEFINES not found" -fi - echo "Done."