diff options
author | Michael Jones <michael_p_jones@apple.com> | 2021-12-07 18:11:35 +0300 |
---|---|---|
committer | Michael Jones <michael_p_jones@apple.com> | 2021-12-07 18:52:21 +0300 |
commit | 9558fa5196033390111a2348caa66ab18b8a4f89 (patch) | |
tree | acc3ed446f709390abfef5f97f82c1ed9abe0100 /intern/cycles/device/metal/device.mm | |
parent | 565b33c0ad31966b860123837d2c4b5a8cbedad2 (diff) |
Cycles: Metal host-side code
This patch adds the Metal host-side code:
- Add all core host-side Metal backend files (device_impl, queue, etc)
- Add MetalRT BVH setup files
- Integrate with Cycles device enumeration code
- Revive `path_source_replace_includes` in util/path (required for MSL compilation)
This patch also includes a couple of small kernel-side fixes:
- Add an implementation of `lgammaf` for Metal [Nemes, Gergő (2010), "New asymptotic expansion for the Gamma function", Archiv der Mathematik](https://users.renyi.hu/~gergonemes/)
- include "work_stealing.h" inside the Metal context class because it accesses state now
Ref T92212
Reviewed By: brecht
Maniphest Tasks: T92212
Differential Revision: https://developer.blender.org/D13423
Diffstat (limited to 'intern/cycles/device/metal/device.mm')
-rw-r--r-- | intern/cycles/device/metal/device.mm | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/intern/cycles/device/metal/device.mm b/intern/cycles/device/metal/device.mm new file mode 100644 index 00000000000..bc893adea17 --- /dev/null +++ b/intern/cycles/device/metal/device.mm @@ -0,0 +1,136 @@ +/* + * Copyright 2021 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WITH_METAL + +# include "device/metal/device.h" +# include "device/metal/device_impl.h" + +#endif + +#include "util/debug.h" +#include "util/set.h" +#include "util/system.h" + +CCL_NAMESPACE_BEGIN + +#ifdef WITH_METAL + +Device *device_metal_create(const DeviceInfo &info, Stats &stats, Profiler &profiler) +{ + return new MetalDevice(info, stats, profiler); +} + +bool device_metal_init() +{ + return true; +} + +static int device_metal_get_num_devices_safe(uint32_t *num_devices) +{ + *num_devices = MTLCopyAllDevices().count; + return 0; +} + +void device_metal_info(vector<DeviceInfo> &devices) +{ + uint32_t num_devices = 0; + device_metal_get_num_devices_safe(&num_devices); + if (num_devices == 0) { + return; + } + + vector<MetalPlatformDevice> usable_devices; + MetalInfo::get_usable_devices(&usable_devices); + /* Devices are numbered consecutively across platforms. */ + set<string> unique_ids; + int device_index = 0; + for (MetalPlatformDevice &device : usable_devices) { + /* Compute unique ID for persistent user preferences. */ + const string &device_name = device.device_name; + string id = string("METAL_") + device_name; + + /* Hardware ID might not be unique, add device number in that case. */ + if (unique_ids.find(id) != unique_ids.end()) { + id += string_printf("_ID_%d", num_devices); + } + unique_ids.insert(id); + + /* Create DeviceInfo. */ + DeviceInfo info; + info.type = DEVICE_METAL; + info.description = string_remove_trademark(string(device_name)); + + /* Ensure unique naming on Apple Silicon / SoC devices which return the same string for CPU and + * GPU */ + if (info.description == system_cpu_brand_string()) { + info.description += " (GPU)"; + } + + info.num = device_index; + /* We don't know if it's used for display, but assume it is. */ + info.display_device = true; + info.denoisers = DENOISER_NONE; + info.id = id; + + devices.push_back(info); + device_index++; + } +} + +string device_metal_capabilities() +{ + string result = ""; + string error_msg = ""; + uint32_t num_devices = 0; + assert(device_metal_get_num_devices_safe(&num_devices)); + if (num_devices == 0) { + return "No Metal devices found\n"; + } + result += string_printf("Number of devices: %u\n", num_devices); + + NSArray<id<MTLDevice>> *allDevices = MTLCopyAllDevices(); + for (id<MTLDevice> device in allDevices) { + result += string_printf("\t\tDevice: %s\n", [device.name UTF8String]); + } + + return result; +} + +#else + +Device *device_metal_create(const DeviceInfo &info, Stats &stats, Profiler &profiler) +{ + return nullptr; +} + +bool device_metal_init() +{ + return false; +} + +void device_metal_info(vector<DeviceInfo> &devices) +{ +} + +string device_metal_capabilities() +{ + return ""; +} + +#endif + +CCL_NAMESPACE_END |