19 #include <Cocoa/Cocoa.h>
20 #include <Metal/Metal.h>
21 #include <QuartzCore/QuartzCore.h>
159 void MTLBackend::platform_init(
MTLContext *ctx)
171 id<MTLDevice> mtl_device = nil;
174 NSString *gpu_name = [mtl_device name];
175 const char *vendor = [gpu_name UTF8String];
176 const char *renderer =
"Metal API";
177 const char *version =
"1.2";
178 printf(
"METAL API - DETECTED GPU: %s\n", vendor);
184 #elif defined(__APPLE__)
193 if (strstr(vendor,
"ATI") || strstr(vendor,
"AMD")) {
197 else if (strstr(vendor,
"NVIDIA")) {
201 else if (strstr(vendor,
"Intel")) {
205 else if (strstr(vendor,
"Apple") || strstr(vendor,
"APPLE")) {
210 else if (strstr(renderer,
"Apple Software Renderer")) {
214 else if (strstr(renderer,
"llvmpipe") || strstr(renderer,
"softpipe")) {
219 printf(
"Warning: Could not find a matching GPU name. Things may not behave as expected.\n");
220 printf(
"Detected configuration:\n");
221 printf(
"Vendor: %s\n", vendor);
222 printf(
"Renderer: %s\n", renderer);
228 void MTLBackend::platform_exit()
248 NSString *gpu_name = [device name];
250 const char *vendor = [gpu_name UTF8String];
253 bool supported_gpu = [device supportsFamily:MTLGPUFamilyMac2];
254 bool should_support_barycentrics =
false;
257 if (strstr(vendor,
"AMD") || strstr(vendor,
"Apple") || strstr(vendor,
"APPLE")) {
258 should_support_barycentrics =
true;
262 if ((strstr(vendor,
"Intel") || strstr(vendor,
"INTEL"))) {
263 should_support_barycentrics =
true;
265 return supported_gpu && should_support_barycentrics;
273 NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
276 bool supported_os_version = version.majorVersion >= 11 ||
277 (version.majorVersion == 10 ? version.minorVersion >= 15 :
false);
278 if (!supported_os_version) {
280 "OS Version too low to run minimum required metal version. Required at least 10.15, got "
282 (
long)version.majorVersion,
283 (
long)version.minorVersion);
287 if (@available(macOS 10.15, *)) {
288 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
291 static const char *forceIntelStr = getenv(
"METAL_FORCE_INTEL");
292 bool forceIntel = forceIntelStr ? (atoi(forceIntelStr) != 0) :
false;
295 NSArray<id<MTLDevice>> *allDevices = MTLCopyAllDevices();
296 for (id<MTLDevice> _device in allDevices) {
297 if (_device.lowPower) {
305 bool supports_argument_buffers_tier2 = ([device argumentBuffersSupport] ==
306 MTLArgumentBuffersTier2);
307 bool supports_barycentrics = [device supportsShaderBarycentricCoordinates] ||
309 bool supported_metal_version = [device supportsFamily:MTLGPUFamilyMac2];
311 bool result = supports_argument_buffers_tier2 && supports_barycentrics &&
312 supported_os_version && supported_metal_version;
314 if (!supports_argument_buffers_tier2) {
315 printf(
"[Metal] Device does not support argument buffers tier 2\n");
317 if (!supports_barycentrics) {
318 printf(
"[Metal] Device does not support barycentrics coordinates\n");
320 if (!supported_metal_version) {
321 printf(
"[Metal] Device does not support metal 2.2 or higher\n");
325 printf(
"Device with name %s supports metal minimum requirements\n",
326 [[device name] UTF8String]);
334 void MTLBackend::capabilities_init(
MTLContext *ctx)
337 id<MTLDevice> device = nil;
342 MTLArgumentBuffersTier2);
346 supportsFamily:MTLGPUFamilyMacCatalyst1];
348 supportsFamily:MTLGPUFamilyMacCatalyst2];
359 (([device supportsFamily:MTLGPUFamilyApple4]) ? 96 : 31);
399 uint max_threads_per_threadgroup_per_dim = ([device supportsFamily:MTLGPUFamilyApple4] ||
GPUContext * GPU_context_active_get(void)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
UniformBuf * uniformbuf_alloc(int size, const char *name) override
void render_step() override
void render_begin() override
QueryPool * querypool_alloc() override
bool is_inside_render_boundary()
Context * context_alloc(void *ghost_window) override
FrameBuffer * framebuffer_alloc(const char *name) override
StorageBuf * storagebuf_alloc(int size, GPUUsageType usage, const char *name) override
static bool metal_is_supported()
IndexBuf * indexbuf_alloc() override
void render_end() override
void samplers_update() override
Batch * batch_alloc() override
static MTLCapabilities capabilities
VertBuf * vertbuf_alloc() override
Texture * texture_alloc(const char *name) override
DrawList * drawlist_alloc(int list_length) override
Shader * shader_alloc(const char *name) override
MTLSafeFreeList * get_current_safe_list()
void update_memory_pools()
void begin_new_safe_list()
static MTLBufferPool & get_global_memory_manager()
void decrement_reference()
bool supports_barycentric_whitelist(id< MTLDevice > device)
static const char * mtl_extensions_get_null(int i)
thread_local int g_autoreleasepool_depth
thread_local NSAutoreleasePool * g_autoreleasepool
T length(const vec_base< T, Size > &a)
bool mip_render_workaround
int max_shader_storage_buffer_bindings
int max_work_group_size[3]
bool shader_image_load_store_support
const char *(* extension_get)(int)
bool use_main_context_workaround
bool depth_blitting_workaround
int minimum_per_vertex_stride
int max_work_group_count[3]
bool shader_storage_buffer_objects_support
bool transform_feedback_support
bool compute_shader_support
bool supports_argument_buffers_tier2
bool supports_family_mac2
bool supports_family_mac1
bool supports_family_mac_catalyst2
bool supports_family_mac_catalyst1