Commit: 9558fa5196033390111a2348caa66ab18b8a4f89 Author: Michael Jones Date: Tue Dec 7 15:11:35 2021 +0000 Branches: master https://developer.blender.org/rB9558fa5196033390111a2348caa66ab18b8a4f89
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 =================================================================== M intern/cycles/blender/CMakeLists.txt M intern/cycles/blender/addon/engine.py M intern/cycles/blender/addon/properties.py M intern/cycles/blender/addon/ui.py M intern/cycles/blender/device.cpp M intern/cycles/blender/python.cpp M intern/cycles/bvh/CMakeLists.txt M intern/cycles/bvh/bvh.cpp A intern/cycles/bvh/metal.h A intern/cycles/bvh/metal.mm M intern/cycles/cmake/external_libs.cmake M intern/cycles/device/CMakeLists.txt M intern/cycles/device/device.cpp M intern/cycles/device/device.h M intern/cycles/device/memory.h A intern/cycles/device/metal/bvh.h A intern/cycles/device/metal/bvh.mm A intern/cycles/device/metal/device.h A intern/cycles/device/metal/device.mm A intern/cycles/device/metal/device_impl.h A intern/cycles/device/metal/device_impl.mm A intern/cycles/device/metal/kernel.h A intern/cycles/device/metal/kernel.mm A intern/cycles/device/metal/queue.h A intern/cycles/device/metal/queue.mm A intern/cycles/device/metal/util.h A intern/cycles/device/metal/util.mm M intern/cycles/device/multi/device.cpp M intern/cycles/kernel/device/gpu/kernel.h M intern/cycles/kernel/device/metal/compat.h M intern/cycles/kernel/device/metal/kernel.metal M intern/cycles/util/math.h M intern/cycles/util/path.cpp M intern/cycles/util/path.h =================================================================== diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index f0540486656..b4a4d487355 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -101,6 +101,11 @@ add_definitions(${GL_DEFINITIONS}) if(WITH_CYCLES_DEVICE_HIP) add_definitions(-DWITH_HIP) endif() + +if(WITH_CYCLES_DEVICE_METAL) + add_definitions(-DWITH_METAL) +endif() + if(WITH_MOD_FLUID) add_definitions(-DWITH_FLUID) endif() diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index e5bb77a834a..910ac4a373e 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -28,7 +28,7 @@ def _configure_argument_parser(): action='store_true') parser.add_argument("--cycles-device", help="Set the device to use for Cycles, overriding user preferences and the scene setting." - "Valid options are 'CPU', 'CUDA', 'OPTIX', or 'HIP'" + "Valid options are 'CPU', 'CUDA', 'OPTIX', 'HIP' or 'METAL'." "Additionally, you can append '+CPU' to any GPU type for hybrid rendering.", default=None) return parser diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 0de936ddb11..8569cb7d946 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -111,7 +111,8 @@ enum_device_type = ( ('CPU', "CPU", "CPU", 0), ('CUDA', "CUDA", "CUDA", 1), ('OPTIX', "OptiX", "OptiX", 3), - ("HIP", "HIP", "HIP", 4) + ('HIP', "HIP", "HIP", 4), + ('METAL', "Metal", "Metal", 5) ) enum_texture_limit = ( @@ -1312,8 +1313,7 @@ class CyclesPreferences(bpy.types.AddonPreferences): def get_device_types(self, context): import _cycles - has_cuda, has_optix, has_hip = _cycles.get_device_types() - + has_cuda, has_optix, has_hip, has_metal = _cycles.get_device_types() list = [('NONE', "None", "Don't use compute device", 0)] if has_cuda: list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1)) @@ -1321,6 +1321,8 @@ class CyclesPreferences(bpy.types.AddonPreferences): list.append(('OPTIX', "OptiX", "Use OptiX for GPU acceleration", 3)) if has_hip: list.append(('HIP', "HIP", "Use HIP for GPU acceleration", 4)) + if has_metal: + list.append(('METAL', "Metal", "Use Metal for GPU acceleration", 5)) return list @@ -1346,7 +1348,7 @@ class CyclesPreferences(bpy.types.AddonPreferences): def update_device_entries(self, device_list): for device in device_list: - if not device[1] in {'CUDA', 'OPTIX', 'CPU', 'HIP'}: + if not device[1] in {'CUDA', 'OPTIX', 'CPU', 'HIP', 'METAL'}: continue # Try to find existing Device entry entry = self.find_existing_device_entry(device) @@ -1390,7 +1392,7 @@ class CyclesPreferences(bpy.types.AddonPreferences): import _cycles # Ensure `self.devices` is not re-allocated when the second call to # get_devices_for_type is made, freeing items from the first list. - for device_type in ('CUDA', 'OPTIX', 'HIP'): + for device_type in ('CUDA', 'OPTIX', 'HIP', 'METAL'): self.update_device_entries(_cycles.available_devices(device_type)) # Deprecated: use refresh_devices instead. diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 6fd21db38ae..fd86d75a301 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -97,6 +97,11 @@ def use_cpu(context): return (get_device_type(context) == 'NONE' or cscene.device == 'CPU') +def use_metal(context): + cscene = context.scene.cycles + + return (get_device_type(context) == 'METAL' and cscene.device == 'GPU') + def use_cuda(context): cscene = context.scene.cycles diff --git a/intern/cycles/blender/device.cpp b/intern/cycles/blender/device.cpp index 9fabc33a96b..d39381ac6f1 100644 --- a/intern/cycles/blender/device.cpp +++ b/intern/cycles/blender/device.cpp @@ -27,6 +27,7 @@ enum ComputeDevice { COMPUTE_DEVICE_CUDA = 1, COMPUTE_DEVICE_OPTIX = 3, COMPUTE_DEVICE_HIP = 4, + COMPUTE_DEVICE_METAL = 5, COMPUTE_DEVICE_NUM }; @@ -85,6 +86,9 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen else if (compute_device == COMPUTE_DEVICE_HIP) { mask |= DEVICE_MASK_HIP; } + else if (compute_device == COMPUTE_DEVICE_METAL) { + mask |= DEVICE_MASK_METAL; + } vector<DeviceInfo> devices = Device::available_devices(mask); /* Match device preferences and available devices. */ diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp index 012122cf9e3..024dae306b0 100644 --- a/intern/cycles/blender/python.cpp +++ b/intern/cycles/blender/python.cpp @@ -906,16 +906,18 @@ static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args* static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/) { vector<DeviceType> device_types = Device::available_types(); - bool has_cuda = false, has_optix = false, has_hip = false; + bool has_cuda = false, has_optix = false, has_hip = false, has_metal = false; foreach (DeviceType device_type, device_types) { has_cuda |= (device_type == DEVICE_CUDA); has_optix |= (device_type == DEVICE_OPTIX); has_hip |= (device_type == DEVICE_HIP); + has_metal |= (device_type == DEVICE_METAL); } - PyObject *list = PyTuple_New(3); + PyObject *list = PyTuple_New(4); PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda)); PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_optix)); PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_hip)); + PyTuple_SET_ITEM(list, 3, PyBool_FromLong(has_metal)); return list; } @@ -944,6 +946,9 @@ static PyObject *set_device_override_func(PyObject * /*self*/, PyObject *arg) else if (override == "HIP") { BlenderSession::device_override = DEVICE_MASK_HIP; } + else if (override == "METAL") { + BlenderSession::device_override = DEVICE_MASK_METAL; + } else { printf("\nError: %s is not a valid Cycles device.\n", override.c_str()); Py_RETURN_FALSE; diff --git a/intern/cycles/bvh/CMakeLists.txt b/intern/cycles/bvh/CMakeLists.txt index 9edc30cf9c4..cdaa6628be2 100644 --- a/intern/cycles/bvh/CMakeLists.txt +++ b/intern/cycles/bvh/CMakeLists.txt @@ -31,6 +31,7 @@ set(SRC sort.cpp split.cpp unaligned.cpp + metal.mm ) set(SRC_HEADERS @@ -46,6 +47,7 @@ set(SRC_HEADERS sort.h split.h unaligned.h + metal.h ) set(LIB diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index d3c8e4db6d0..540bf52f7ac 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -19,6 +19,7 @@ #include "bvh/bvh2.h" #include "bvh/embree.h" +#include "bvh/metal.h" #include "bvh/multi.h" #include "bvh/optix.h" @@ -105,13 +106,18 @@ BVH *BVH::create(const BVHParams ¶ms, #else (void)device; break; +#endif + case BVH_LAYOUT_METAL: +#ifdef WITH_METAL + return bvh_metal_create(params, geometry, objects, device); +#else + (void)device; + break; #endif case BVH_LAYOUT_MULTI_OPTIX: case BVH_LAYOUT_MULTI_OPTIX_EMBREE: case BVH_LAYOUT_MULTI_METAL_EMBREE: return new BVHMulti(params, geometry, objects); - case BVH_LAYOUT_METAL: - /* host-side changes for BVH_LAYOUT_METAL are imminent */ case BVH_LAYOUT_NONE: case BVH_LAYOUT_ALL: break; diff --git a/intern/cycles/bvh/metal.h b/intern/cycles/bvh/metal.h new file mode 100644 index 00000000000..8de07927e61 --- /dev/null +++ b/intern/cycles/bvh/metal.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +#ifndef __BVH_METAL_H__ +#define __BVH_METAL_H__ + +#ifdef WITH_METAL + +# include "bvh/bvh.h" + +CCL_NAMESPACE_BEGIN + +BVH *bvh_metal_create(const BVHParams ¶ms, + const vector<Geometry *> &geometry, + const vector<Object *> &objects, + Device *device); + +CCL_NAMESPACE_END + +#endif /* WITH_METAL */ + +#endif /* __BVH_METAL_H__ */ diff --git a/intern/cycles/bvh/metal.mm b/intern/cycles/bvh/metal.mm new file mode 100644 index 00000000000..90a52012f12 --- /dev/null +++ b/intern/cycles/bvh/metal.mm @@ -0,0 +1,33 @@ +/* + * 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/bvh.h" + +CCL_NAMESPACE_BEGIN + +BVH *bvh_metal_create(const BVHParams ¶ms, + const vector<Geometry *> &geometry, + const vector<Object *> &objects, + Device *device) +{ + return new BVHMetal(params, geometry, objects, device); +} + +CCL_NAMESPACE_END + +#endif /* WITH_METAL */ diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs