[Bf-blender-cvs] [f4b03031e84] master: GPU: Select GPU Backend from Preferences.

Jeroen Bakker noreply at git.blender.org
Wed Dec 21 21:12:03 CET 2022


Commit: f4b03031e84f727df6eb21c28125b3a4ef98f1c0
Author: Jeroen Bakker
Date:   Wed Dec 21 20:54:36 2022 +0100
Branches: master
https://developer.blender.org/rBf4b03031e84f727df6eb21c28125b3a4ef98f1c0

GPU: Select GPU Backend from Preferences.

(MacOS) only: In the System tab of the user preferences the user has the
ability to select a GPU backend that Blender will use. After changing
the GPU backend setting, the user has to restart Blender before the
setting is used.

It was added to start collecting feedback on the Metal backend without
using the command lines.

By default Blender will select OpenGL as backend. When Metal is selected
(via `--gpu-backend metal` or via user preferences) OpenGL will be used as
fallback when the platform isn't capable of running Metal.

===================================================================

M	release/datafiles/userdef/userdef_default.c
M	release/scripts/startup/bl_ui/space_userpref.py
M	source/blender/blenkernel/BKE_blender_version.h
M	source/blender/blenloader/CMakeLists.txt
M	source/blender/blenloader/intern/versioning_userdef.c
M	source/blender/gpu/GPU_context.h
M	source/blender/gpu/intern/gpu_context.cc
M	source/blender/makesdna/DNA_userdef_types.h
M	source/blender/makesrna/intern/rna_userdef.c
M	source/blender/windowmanager/intern/wm_files.c
M	source/creator/creator_args.c

===================================================================

diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c
index b4a1ab6d5f8..24e093833c4 100644
--- a/release/datafiles/userdef/userdef_default.c
+++ b/release/datafiles/userdef/userdef_default.c
@@ -14,6 +14,8 @@
 
 #include "BKE_blender_version.h"
 
+#include "GPU_platform.h"
+
 #include "BLO_readfile.h" /* own include */
 
 const UserDef U_default = {
@@ -99,6 +101,7 @@ const UserDef U_default = {
     .gp_euclideandist = 2,
     .gp_eraser = 25,
     .gp_settings = 0,
+    .gpu_backend = GPU_BACKEND_OPENGL,
 
     /** Initialized by: #BKE_studiolight_default. */
     .light_param = {{0}},
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 759b222c562..44bc807c7dd 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -604,6 +604,27 @@ class USERPREF_PT_system_cycles_devices(SystemPanel, CenterAlignMixIn, Panel):
             del addon
 
 
+class USERPREF_PT_system_gpu_backend(SystemPanel, CenterAlignMixIn, Panel):
+    bl_label = "GPU Backend"
+
+    @classmethod
+    def poll(cls, _context):
+        # Only for Apple so far
+        import sys
+        return sys.platform == "darwin"
+
+    def draw_centered(self, context, layout):
+        import gpu
+        prefs = context.preferences
+        system = prefs.system
+
+        col = layout.column()
+        col.prop(system, "gpu_backend")
+
+        if system.gpu_backend != gpu.platform.backend_type_get():
+            layout.label(text="Requires a restart of Blender to take effect.", icon='INFO')
+
+
 class USERPREF_PT_system_os_settings(SystemPanel, CenterAlignMixIn, Panel):
     bl_label = "Operating System Settings"
 
@@ -2406,6 +2427,7 @@ classes = (
     USERPREF_PT_animation_fcurves,
 
     USERPREF_PT_system_cycles_devices,
+    USERPREF_PT_system_gpu_backend,
     USERPREF_PT_system_os_settings,
     USERPREF_PT_system_memory,
     USERPREF_PT_system_video_sequencer,
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 91a458e347f..7c241a4fa12 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -25,7 +25,7 @@ extern "C" {
 
 /* Blender file format version. */
 #define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 4
+#define BLENDER_FILE_SUBVERSION 5
 
 /* Minimum Blender version that supports reading file written with the current
  * version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index 86793d38b0b..a7e99e7df2e 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -10,6 +10,7 @@ set(INC
   ../depsgraph
   ../draw
   ../editors/include
+  ../gpu
   ../imbuf
   ../makesdna
   ../makesrna
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index b4890131861..10a21356c8f 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -31,6 +31,8 @@
 
 #include "BLO_readfile.h"
 
+#include "GPU_platform.h"
+
 #include "readfile.h" /* Own include. */
 
 #include "WM_types.h"
@@ -766,6 +768,11 @@ void blo_do_versions_userdef(UserDef *userdef)
     userdef->dupflag |= USER_DUP_CURVES | USER_DUP_POINTCLOUD;
   }
 
+  /* Set GPU backend to OpenGL. */
+  if (!USER_VERSION_ATLEAST(305, 5)) {
+    userdef->gpu_backend = GPU_BACKEND_OPENGL;
+  }
+
   /**
    * Versioning code until next subversion bump goes here.
    *
diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h
index ac82774039a..fd20283380f 100644
--- a/source/blender/gpu/GPU_context.h
+++ b/source/blender/gpu/GPU_context.h
@@ -25,6 +25,30 @@ void GPU_backend_type_selection_set(const eGPUBackendType backend);
 eGPUBackendType GPU_backend_type_selection_get(void);
 eGPUBackendType GPU_backend_get_type(void);
 
+/**
+ * Detect the most suited eGPUBackendType.
+ *
+ * - The detected backend will be set in `GPU_backend_type_selection_set`.
+ * - When GPU_backend_type_selection_is_overridden it checks the overridden backend.
+ *   When not overridden it checks a default list.
+ * - OpenGL backend will be checked as fallback for Metal.
+ *
+ * Returns true when detection found a supported backend, otherwise returns false.
+ * When no supported backend is found GPU_backend_type_selection_set is called with
+ * GPU_BACKEND_NONE.
+ */
+bool GPU_backend_type_selection_detect(void);
+
+/**
+ * Alter the GPU_backend_type_selection_detect to only test a specific backend
+ */
+void GPU_backend_type_selection_set_override(eGPUBackendType backend_type);
+
+/**
+ * Check if the GPU_backend_type_selection_detect is overridden to only test a specific backend.
+ */
+bool GPU_backend_type_selection_is_overridden(void);
+
 /** Opaque type hiding blender::gpu::Context. */
 typedef struct GPUContext GPUContext;
 
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index 0443417a32a..101542802e6 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -227,11 +227,14 @@ void GPU_render_step()
  * Until a global switch is added, Metal also needs to be enabled in GHOST_ContextCGL:
  * `m_useMetalForRendering = true`. */
 static eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL;
+static std::optional<eGPUBackendType> g_backend_type_override = std::nullopt;
+static std::optional<bool> g_backend_type_supported = std::nullopt;
 static GPUBackend *g_backend = nullptr;
 
 void GPU_backend_type_selection_set(const eGPUBackendType backend)
 {
   g_backend_type = backend;
+  g_backend_type_supported = std::nullopt;
 }
 
 eGPUBackendType GPU_backend_type_selection_get()
@@ -239,7 +242,44 @@ eGPUBackendType GPU_backend_type_selection_get()
   return g_backend_type;
 }
 
-bool GPU_backend_supported(void)
+void GPU_backend_type_selection_set_override(const eGPUBackendType backend_type)
+{
+  g_backend_type_override = backend_type;
+}
+
+bool GPU_backend_type_selection_is_overridden(void)
+{
+  return g_backend_type_override.has_value();
+}
+
+bool GPU_backend_type_selection_detect(void)
+{
+  blender::Vector<eGPUBackendType> backends_to_check;
+  if (GPU_backend_type_selection_is_overridden()) {
+    backends_to_check.append(*g_backend_type_override);
+  }
+  else {
+    backends_to_check.append(GPU_BACKEND_OPENGL);
+  }
+
+  /* Add fallback to OpenGL when Metal backend is requested on a platform that doens't support
+   * metal. */
+  if (backends_to_check[0] == GPU_BACKEND_METAL) {
+    backends_to_check.append(GPU_BACKEND_OPENGL);
+  }
+
+  for (const eGPUBackendType backend_type : backends_to_check) {
+    GPU_backend_type_selection_set(backend_type);
+    if (GPU_backend_supported()) {
+      return true;
+    }
+  }
+
+  GPU_backend_type_selection_set(GPU_BACKEND_NONE);
+  return false;
+}
+
+static bool gpu_backend_supported()
 {
   switch (g_backend_type) {
     case GPU_BACKEND_OPENGL:
@@ -266,6 +306,14 @@ bool GPU_backend_supported(void)
   }
 }
 
+bool GPU_backend_supported()
+{
+  if (!g_backend_type_supported.has_value()) {
+    g_backend_type_supported = gpu_backend_supported();
+  }
+  return *g_backend_type_supported;
+}
+
 static void gpu_backend_create()
 {
   BLI_assert(g_backend == nullptr);
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 8a644803fd7..18c4508efae 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -828,7 +828,10 @@ typedef struct UserDef {
   /** Seconds to zoom around current frame. */
   float view_frame_seconds;
 
-  char _pad7[6];
+  /** #eGPUBackendType */
+  short gpu_backend;
+
+  char _pad7[4];
 
   /** Private, defaults to 20 for 72 DPI setting. */
   short widget_unit;
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index b93983d0a87..db12ac82f38 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -29,6 +29,8 @@
 #include "RNA_define.h"
 #include "RNA_enum_types.h"
 
+#include "GPU_platform.h"
+
 #include "UI_interface_icons.h"
 
 #include "rna_internal.h"
@@ -138,6 +140,13 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
     {0, NULL, 0, NULL, NULL},
 };
 
+const EnumPropertyItem rna_enum_preference_gpu_backend_items[] = {
+    {GPU_BACKEND_OPENGL, "OPENGL", 0, "OpenGL", "Use OpenGL backend"},
+    {GPU_BACKEND_METAL, "METAL", 0, "Metal", "Use Metal backend"},
+    {GPU_BACKEND_VULKAN, "VULKAN", 0, "Vulkan", "Use Vulkan backend"},
+    {0, NULL, 0, NULL, NULL},
+};
+
 #ifdef RNA_RUNTIME
 
 #  include "BLI_math_vector.h"
@@ -1031,6 +1040,33 @@ int rna_show_statusbar_vram_editable(struct PointerRNA *UNUSED(ptr), const char
   return GPU_mem_stats_supported() ? PROP_EDITABLE : 0;
 }
 
+static const EnumPropertyItem *rna_preference_gpu_backend_itemf(struct bContext *UNUSED(C),
+                                                                PointerRNA *UNUSED(ptr),
+                                                                PropertyRNA *UNUSED(prop),
+                                                                bool *r_free)
+{
+  int totitem = 0;
+  EnumPropertyItem *result = NULL;
+  for (int i = 0; rna_enum_preference_gpu_backend_items[i].identifier != NULL; i++) {
+    const EnumPropertyItem *item = &rna_enum_preference_gpu_backend_items[i];
+#  ifndef WITH_METAL_BACKEND
+    if (item->value == GPU_BACKEND_METAL) {
+      continue;
+    }
+#  endif
+#  ifndef WITH_VULKAN_BACKEND
+    if (item->value == GPU_BACKEND_VULKAN) {
+      continue;
+    }
+#  endif
+    RNA_enum_item_add(&result, &totitem, item);
+  }
+
+  RNA_enum_item_end(&result, &totitem);
+  *r_free = true;
+  return result;
+}
+
 #else
 
 #  define USERDEF_TAG_DIRTY_PROPERTY_UPDATE_ENABLE \
@@ -5604,6 +5640,16 @@ static void rna_def_userdef_syst

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list