diff options
-rw-r--r-- | source/blender/gpu/opengl/gl_backend.cc | 7 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_context.hh | 1 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.cc | 19 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_texture.hh | 2 |
4 files changed, 29 insertions, 0 deletions
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); |