From e23b54a59f0428399bbf4de5ba007ad764fa80be Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Wed, 8 Dec 2021 15:07:11 +0000 Subject: Cycles: Fix OS version warnings This patch suppresses OS version warnings and hides currently unsupported Metal GPUs when enumerating devices. Reviewed By: brecht Differential Revision: https://developer.blender.org/D13506 --- intern/cycles/device/metal/device_impl.mm | 22 ++++----- intern/cycles/device/metal/kernel.mm | 4 +- intern/cycles/device/metal/queue.h | 2 + intern/cycles/device/metal/queue.mm | 78 +++++++++++++++++-------------- intern/cycles/device/metal/util.mm | 31 ++---------- 5 files changed, 63 insertions(+), 74 deletions(-) diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index fd249204646..4ad5a3caebc 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -308,14 +308,12 @@ bool MetalDevice::load_kernels(const uint _kernel_features) MTLCompileOptions *options = [[MTLCompileOptions alloc] init]; options.fastMathEnabled = YES; - options.languageVersion = MTLLanguageVersion2_1; - - if (@available(macOS 11.0, *)) { - options.languageVersion = MTLLanguageVersion2_3; - } if (@available(macOS 12.0, *)) { options.languageVersion = MTLLanguageVersion2_4; } + else { + return false; + } string metalsrc; @@ -925,12 +923,14 @@ void MetalDevice::tex_alloc(device_texture &mem) } } - /* Optimize the texture for GPU access. */ - id commandBuffer = [mtlGeneralCommandQueue commandBuffer]; - id blitCommandEncoder = [commandBuffer blitCommandEncoder]; - [blitCommandEncoder optimizeContentsForGPUAccess:mtlTexture]; - [blitCommandEncoder endEncoding]; - [commandBuffer commit]; + if (@available(macos 10.14, *)) { + /* Optimize the texture for GPU access. */ + id commandBuffer = [mtlGeneralCommandQueue commandBuffer]; + id blitCommandEncoder = [commandBuffer blitCommandEncoder]; + [blitCommandEncoder optimizeContentsForGPUAccess:mtlTexture]; + [blitCommandEncoder endEncoding]; + [commandBuffer commit]; + } /* Set Mapping and tag that we need to (re-)upload to device */ texture_slot_map[slot] = mtlTexture; diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index f5c3adbce25..f948a8a0a0f 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -118,7 +118,9 @@ bool MetalDeviceKernel::load(MetalDevice *device, computePipelineStateDescriptor.buffers[1].mutability = MTLMutabilityImmutable; computePipelineStateDescriptor.buffers[2].mutability = MTLMutabilityImmutable; - computePipelineStateDescriptor.maxTotalThreadsPerThreadgroup = desc.threads_per_threadgroup; + if (@available(macos 10.14, *)) { + computePipelineStateDescriptor.maxTotalThreadsPerThreadgroup = desc.threads_per_threadgroup; + } computePipelineStateDescriptor.threadGroupSizeIsMultipleOfThreadExecutionWidth = true; computePipelineStateDescriptor.computeFunction = pso[desc.pso_index].function; diff --git a/intern/cycles/device/metal/queue.h b/intern/cycles/device/metal/queue.h index 7aafcb2efe4..64c8bb79c49 100644 --- a/intern/cycles/device/metal/queue.h +++ b/intern/cycles/device/metal/queue.h @@ -70,7 +70,9 @@ class MetalDeviceQueue : public DeviceQueue { id mtlCommandBuffer = nil; id mtlComputeEncoder = nil; id mtlBlitEncoder = nil; + API_AVAILABLE(macos(10.14), ios(14.0)) id shared_event = nil; + API_AVAILABLE(macos(10.14), ios(14.0)) MTLSharedEventListener *shared_event_listener = nil; dispatch_queue_t event_queue; diff --git a/intern/cycles/device/metal/queue.mm b/intern/cycles/device/metal/queue.mm index ced01e7b9b6..d04df09f49a 100644 --- a/intern/cycles/device/metal/queue.mm +++ b/intern/cycles/device/metal/queue.mm @@ -40,12 +40,14 @@ MetalDeviceQueue::MetalDeviceQueue(MetalDevice *device) mtlDevice = device->mtlDevice; mtlCommandQueue = [mtlDevice newCommandQueue]; - shared_event = [mtlDevice newSharedEvent]; - shared_event_id = 1; + if (@available(macos 10.14, *)) { + shared_event = [mtlDevice newSharedEvent]; + shared_event_id = 1; - /* Shareable event listener */ - event_queue = dispatch_queue_create("com.cycles.metal.event_queue", NULL); - shared_event_listener = [[MTLSharedEventListener alloc] initWithDispatchQueue:event_queue]; + /* Shareable event listener */ + event_queue = dispatch_queue_create("com.cycles.metal.event_queue", NULL); + shared_event_listener = [[MTLSharedEventListener alloc] initWithDispatchQueue:event_queue]; + } wait_semaphore = dispatch_semaphore_create(0); } @@ -57,8 +59,10 @@ MetalDeviceQueue::~MetalDeviceQueue() assert(mtlCommandBuffer == nil); assert(command_buffers_submitted == command_buffers_completed); - [shared_event_listener release]; - [shared_event release]; + if (@available(macos 10.14, *)) { + [shared_event_listener release]; + [shared_event release]; + } if (@available(macos 11.0, *)) { [command_buffer_desc release]; @@ -364,16 +368,18 @@ bool MetalDeviceQueue::synchronize() if (mtlCommandBuffer) { uint64_t shared_event_id = this->shared_event_id++; - __block dispatch_semaphore_t block_sema = wait_semaphore; - [shared_event notifyListener:shared_event_listener - atValue:shared_event_id - block:^(id sharedEvent, uint64_t value) { - dispatch_semaphore_signal(block_sema); - }]; - - [mtlCommandBuffer encodeSignalEvent:shared_event value:shared_event_id]; - [mtlCommandBuffer commit]; - dispatch_semaphore_wait(wait_semaphore, DISPATCH_TIME_FOREVER); + if (@available(macos 10.14, *)) { + __block dispatch_semaphore_t block_sema = wait_semaphore; + [shared_event notifyListener:shared_event_listener + atValue:shared_event_id + block:^(id sharedEvent, uint64_t value) { + dispatch_semaphore_signal(block_sema); + }]; + + [mtlCommandBuffer encodeSignalEvent:shared_event value:shared_event_id]; + [mtlCommandBuffer commit]; + dispatch_semaphore_wait(wait_semaphore, DISPATCH_TIME_FOREVER); + } [mtlCommandBuffer release]; @@ -536,30 +542,32 @@ id MetalDeviceQueue::get_compute_encoder(DeviceKernel { bool concurrent = (kernel < DEVICE_KERNEL_INTEGRATOR_NUM); - if (mtlComputeEncoder) { - if (mtlComputeEncoder.dispatchType == concurrent ? MTLDispatchTypeConcurrent : - MTLDispatchTypeSerial) { - /* declare usage of MTLBuffers etc */ - prepare_resources(kernel); + if (@available(macos 10.14, *)) { + if (mtlComputeEncoder) { + if (mtlComputeEncoder.dispatchType == concurrent ? MTLDispatchTypeConcurrent : + MTLDispatchTypeSerial) { + /* declare usage of MTLBuffers etc */ + prepare_resources(kernel); - return mtlComputeEncoder; + return mtlComputeEncoder; + } + close_compute_encoder(); } - close_compute_encoder(); - } - close_blit_encoder(); + close_blit_encoder(); - if (!mtlCommandBuffer) { - mtlCommandBuffer = [mtlCommandQueue commandBuffer]; - [mtlCommandBuffer retain]; - } + if (!mtlCommandBuffer) { + mtlCommandBuffer = [mtlCommandQueue commandBuffer]; + [mtlCommandBuffer retain]; + } - mtlComputeEncoder = [mtlCommandBuffer - computeCommandEncoderWithDispatchType:concurrent ? MTLDispatchTypeConcurrent : - MTLDispatchTypeSerial]; + mtlComputeEncoder = [mtlCommandBuffer + computeCommandEncoderWithDispatchType:concurrent ? MTLDispatchTypeConcurrent : + MTLDispatchTypeSerial]; - /* declare usage of MTLBuffers etc */ - prepare_resources(kernel); + /* declare usage of MTLBuffers etc */ + prepare_resources(kernel); + } return mtlComputeEncoder; } diff --git a/intern/cycles/device/metal/util.mm b/intern/cycles/device/metal/util.mm index d2143c389dc..0a8b0ee6f10 100644 --- a/intern/cycles/device/metal/util.mm +++ b/intern/cycles/device/metal/util.mm @@ -45,35 +45,12 @@ MetalGPUVendor MetalInfo::get_vendor_from_device_name(string const &device_name) bool MetalInfo::device_version_check(id device) { + /* Metal Cycles doesn't work correctly on macOS versions older than 12.0 */ if (@available(macos 12.0, *)) { MetalGPUVendor vendor = get_vendor_from_device_name([[device name] UTF8String]); - - static const char *forceIntelStr = getenv("CYCLES_METAL_FORCE_INTEL"); - bool forceIntel = forceIntelStr ? (atoi(forceIntelStr) != 0) : false; - - if (forceIntel) { - /* return false for non-Intel GPUs to force selection of Intel */ - if (vendor == METAL_GPU_INTEL) { - return true; - } - } - else { - switch (vendor) { - case METAL_GPU_INTEL: - /* isLowPower only returns true on machines that have an AMD GPU also - * For Intel only machines - isLowPower will return false - */ - if (getenv("CYCLES_METAL_ALLOW_LOW_POWER_GPUS") || !device.isLowPower) { - return true; - } - return false; - case METAL_GPU_APPLE: - case METAL_GPU_AMD: - return true; - default: - return false; - } - } + + /* Metal Cycles works on Apple Silicon GPUs at present */ + return (vendor == METAL_GPU_APPLE); } return false; -- cgit v1.2.3