MTLPrivate.hpp
1 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 // 3 // Metal/MTLPrivate.hpp 4 // 5 // Copyright 2020-2024 Apple Inc. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 21 #pragma once 22 23 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 25 #include "MTLDefines.hpp" 26 27 #include <objc/runtime.h> 28 29 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 30 31 #define _MTL_PRIVATE_CLS(symbol) (Private::Class::s_k##symbol) 32 #define _MTL_PRIVATE_SEL(accessor) (Private::Selector::s_k##accessor) 33 34 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 35 36 #if defined(MTL_PRIVATE_IMPLEMENTATION) 37 38 #ifdef METALCPP_SYMBOL_VISIBILITY_HIDDEN 39 #define _MTL_PRIVATE_VISIBILITY __attribute__((visibility("hidden"))) 40 #else 41 #define _MTL_PRIVATE_VISIBILITY __attribute__((visibility("default"))) 42 #endif // METALCPP_SYMBOL_VISIBILITY_HIDDEN 43 44 #define _MTL_PRIVATE_IMPORT __attribute__((weak_import)) 45 46 #ifdef __OBJC__ 47 #define _MTL_PRIVATE_OBJC_LOOKUP_CLASS(symbol) ((__bridge void*)objc_lookUpClass(#symbol)) 48 #define _MTL_PRIVATE_OBJC_GET_PROTOCOL(symbol) ((__bridge void*)objc_getProtocol(#symbol)) 49 #else 50 #define _MTL_PRIVATE_OBJC_LOOKUP_CLASS(symbol) objc_lookUpClass(#symbol) 51 #define _MTL_PRIVATE_OBJC_GET_PROTOCOL(symbol) objc_getProtocol(#symbol) 52 #endif // __OBJC__ 53 54 #define _MTL_PRIVATE_DEF_CLS(symbol) void* s_k##symbol _MTL_PRIVATE_VISIBILITY = _MTL_PRIVATE_OBJC_LOOKUP_CLASS(symbol) 55 #define _MTL_PRIVATE_DEF_PRO(symbol) void* s_k##symbol _MTL_PRIVATE_VISIBILITY = _MTL_PRIVATE_OBJC_GET_PROTOCOL(symbol) 56 #define _MTL_PRIVATE_DEF_SEL(accessor, symbol) SEL s_k##accessor _MTL_PRIVATE_VISIBILITY = sel_registerName(symbol) 57 58 #include <dlfcn.h> 59 #define MTL_DEF_FUNC( name, signature ) \ 60 using Fn##name = signature; \ 61 Fn##name name = reinterpret_cast< Fn##name >( dlsym( RTLD_DEFAULT, #name ) ) 62 63 namespace MTL::Private 64 { 65 template <typename _Type> 66 inline _Type const LoadSymbol(const char* pSymbol) 67 { 68 const _Type* pAddress = static_cast<_Type*>(dlsym(RTLD_DEFAULT, pSymbol)); 69 70 return pAddress ? *pAddress : nullptr; 71 } 72 } // MTL::Private 73 74 #if defined(__MAC_15_0) || defined(__IPHONE_18_0) || defined(__TVOS_18_0) 75 76 #define _MTL_PRIVATE_DEF_STR(type, symbol) \ 77 _MTL_EXTERN type const MTL##symbol _MTL_PRIVATE_IMPORT; \ 78 type const MTL::symbol = (nullptr != &MTL##symbol) ? MTL##symbol : nullptr 79 80 #define _MTL_PRIVATE_DEF_CONST(type, symbol) \ 81 _MTL_EXTERN type const MTL##symbol _MTL_PRIVATE_IMPORT; \ 82 type const MTL::symbol = (nullptr != &MTL##symbol) ? MTL##symbol : nullptr 83 84 #define _MTL_PRIVATE_DEF_WEAK_CONST(type, symbol) \ 85 _MTL_EXTERN type const MTL##symbol; \ 86 type const MTL::symbol = Private::LoadSymbol<type>("MTL" #symbol) 87 88 #else 89 90 #define _MTL_PRIVATE_DEF_STR(type, symbol) \ 91 _MTL_EXTERN type const MTL##symbol; \ 92 type const MTL::symbol = Private::LoadSymbol<type>("MTL" #symbol) 93 94 #define _MTL_PRIVATE_DEF_CONST(type, symbol) \ 95 _MTL_EXTERN type const MTL##symbol; \ 96 type const MTL::symbol = Private::LoadSymbol<type>("MTL" #symbol) 97 98 #define _MTL_PRIVATE_DEF_WEAK_CONST(type, symbol) _MTL_PRIVATE_DEF_CONST(type, symbol) 99 100 #endif // defined(__MAC_15_0) || defined(__IPHONE_18_0) || defined(__TVOS_18_0) 101 102 #else 103 104 #define _MTL_PRIVATE_DEF_CLS(symbol) extern void* s_k##symbol 105 #define _MTL_PRIVATE_DEF_PRO(symbol) extern void* s_k##symbol 106 #define _MTL_PRIVATE_DEF_SEL(accessor, symbol) extern SEL s_k##accessor 107 #define _MTL_PRIVATE_DEF_STR(type, symbol) extern type const MTL::symbol 108 #define _MTL_PRIVATE_DEF_CONST(type, symbol) extern type const MTL::symbol 109 #define _MTL_PRIVATE_DEF_WEAK_CONST(type, symbol) extern type const MTL::symbol 110 111 #endif // MTL_PRIVATE_IMPLEMENTATION 112 113 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 114 115 namespace MTL 116 { 117 namespace Private 118 { 119 namespace Class 120 { 121 122 } // Class 123 } // Private 124 } // MTL 125 126 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 127 128 namespace MTL 129 { 130 namespace Private 131 { 132 namespace Protocol 133 { 134 135 } // Protocol 136 } // Private 137 } // MTL 138 139 //------------------------------------------------------------------------------------------------------------------------------------------------------------- 140 141 namespace MTL 142 { 143 namespace Private 144 { 145 namespace Selector 146 { 147 148 _MTL_PRIVATE_DEF_SEL(beginScope, 149 "beginScope"); 150 _MTL_PRIVATE_DEF_SEL(endScope, 151 "endScope"); 152 } // Class 153 } // Private 154 } // MTL 155 156 //-------------------------------------------------------------------------------------------------------------------------------------------------------------