[Bf-blender-cvs] [1b2ee3cf207] blender-v3.0-release: Fix T92090: Eevee crash with Intel HD 4000 and macOS 10.15.7

Brecht Van Lommel noreply at git.blender.org
Sat Nov 20 17:55:59 CET 2021


Commit: 1b2ee3cf20777c737a116c44227b3193ae69cc74
Author: Brecht Van Lommel
Date:   Sat Nov 20 15:09:01 2021 +0100
Branches: blender-v3.0-release
https://developer.blender.org/rB1b2ee3cf20777c737a116c44227b3193ae69cc74

Fix T92090: Eevee crash with Intel HD 4000 and macOS 10.15.7

A recent security update to macOS 10.15.7 causes crashes when using Eevee and
various other 3D viewport features. It appears that glGenerateMipmap is
broken, causing a crash whenever its commands are flushed/submitted to the GPU.

Ideally this would be fixed in a driver update, however it's unlikely this will
happen. Earlier macOS versions have been receiving security updates for 2 years,
and that window has just passed for 10.15. Further, computers with these GPUs
can't upgrade to a newer macOS version.

As a workaround, disable mipmaps on these GPUs, by setting the mipmap max level
to 0 and not calling glGenerateMipmaps. Effects like depth of field also use
mipmaps, but fill in the mip levels by other means. In those cases we keep the
mipmap level.

Differential Revision: https://developer.blender.org/D13295

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

M	source/blender/gpu/opengl/gl_backend.cc
M	source/blender/gpu/opengl/gl_context.hh
M	source/blender/gpu/opengl/gl_texture.cc
M	source/blender/gpu/opengl/gl_texture.hh

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

diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 2855d5078ff..27ef75df328 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -412,6 +412,12 @@ static void detect_workarounds()
   if (GLContext::debug_layer_support == false) {
     GLContext::debug_layer_workaround = true;
   }
+
+  /* Broken glGenerateMipmap on macOS 10.15.7 security update. */
+  if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_ANY) &&
+      strstr(renderer, "HD Graphics 4000")) {
+    GLContext::generate_mipmap_workaround = true;
+  }
 }  // namespace blender::gpu
 
 /** Internal capabilities. */
@@ -436,6 +442,7 @@ bool GLContext::vertex_attrib_binding_support = false;
 /** Workarounds. */
 bool GLContext::debug_layer_workaround = false;
 bool GLContext::unused_fb_slot_workaround = false;
+bool GLContext::generate_mipmap_workaround = false;
 float GLContext::derivative_signs[2] = {1.0f, 1.0f};
 
 void GLBackend::capabilities_init()
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index 0222adaba25..9273bfb9911 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -77,6 +77,7 @@ class GLContext : public Context {
   /** Workarounds. */
   static bool debug_layer_workaround;
   static bool unused_fb_slot_workaround;
+  static bool generate_mipmap_workaround;
   static float derivative_signs[2];
 
   /** VBO for missing vertex attrib binding. Avoid undefined behavior on some implementation. */
diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc
index db1fda63c28..f9c5a97a0bb 100644
--- a/source/blender/gpu/opengl/gl_texture.cc
+++ b/source/blender/gpu/opengl/gl_texture.cc
@@ -225,6 +225,8 @@ void GLTexture::update_sub_direct_state_access(
         break;
     }
   }
+
+  has_pixels_ = true;
 }
 
 void GLTexture::update_sub(
@@ -288,6 +290,8 @@ void GLTexture::update_sub(
         break;
     }
   }
+
+  has_pixels_ = true;
 }
 
 /**
@@ -307,6 +311,16 @@ void GLTexture::generate_mipmap()
     return;
   }
 
+  if (GLContext::generate_mipmap_workaround) {
+    /* Broken glGenerateMipmap, don't call it and render without mipmaps.
+     * If no top level pixels have been filled in, the levels will get filled by
+     * other means and there is no need to disable mipmapping. */
+    if (has_pixels_) {
+      this->mip_range_set(0, 0);
+    }
+    return;
+  }
+
   /* Down-sample from mip 0 using implementation. */
   if (GLContext::direct_state_access_support) {
     glGenerateTextureMipmap(tex_id_);
@@ -337,6 +351,8 @@ void GLTexture::clear(eGPUDataFormat data_format, const void *data)
 
     GPU_framebuffer_bind(prev_fb);
   }
+
+  has_pixels_ = true;
 }
 
 void GLTexture::copy_to(Texture *dst_)
@@ -363,6 +379,8 @@ void GLTexture::copy_to(Texture *dst_)
     GPU_framebuffer_blit(
         src->framebuffer_get(), 0, dst->framebuffer_get(), 0, to_framebuffer_bits(format_));
   }
+
+  has_pixels_ = true;
 }
 
 void *GLTexture::read(int mip, eGPUDataFormat type)
@@ -452,6 +470,7 @@ struct GPUFrameBuffer *GLTexture::framebuffer_get()
   GPUTexture *gputex = reinterpret_cast<GPUTexture *>(static_cast<Texture *>(this));
   framebuffer_ = GPU_framebuffer_create(name_);
   GPU_framebuffer_texture_attach(framebuffer_, gputex, 0, 0);
+  has_pixels_ = true;
   return framebuffer_;
 }
 
diff --git a/source/blender/gpu/opengl/gl_texture.hh b/source/blender/gpu/opengl/gl_texture.hh
index 2a480e71017..93c6b8d8af0 100644
--- a/source/blender/gpu/opengl/gl_texture.hh
+++ b/source/blender/gpu/opengl/gl_texture.hh
@@ -53,6 +53,8 @@ class GLTexture : public Texture {
   /** True if this texture is bound to at least one texture unit. */
   /* TODO(fclem): How do we ensure thread safety here? */
   bool is_bound_ = false;
+  /** True if pixels in the texture have been initialized. */
+  bool has_pixels_ = false;
 
  public:
   GLTexture(const char *name);



More information about the Bf-blender-cvs mailing list