[Bf-blender-cvs] [9558fa51960] master: Cycles: Metal host-side code

Michael Jones noreply at git.blender.org
Tue Dec 7 16:52:28 CET 2021


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 &params,
 #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 &params,
+                      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 &params,
+                      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. @@



More information about the Bf-blender-cvs mailing list