diff options
author | Jeroen Bakker <jbakker> | 2020-08-05 16:26:49 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2020-08-05 16:45:42 +0300 |
commit | f7d38e2e6426a21f4b91bedc0fe635aba4692ff2 (patch) | |
tree | c3d240bcb10b992b41826d876dc1a3016dabe632 /source/blender/gpu/intern | |
parent | 56d7e39b92997768b3db8ce2dbc262f869994145 (diff) |
Fix T77346: GPU Workaround Always Render Using Main Context
In Blender 2.90 EEVEE materials were refactored that introduced crashes on Intel
GPUs on Windows. The crash happened in the `local_context_workaround` that temporary
stored compiled materials in a binary form to reload it in the main GL context.
It has been tested that the workaround isn't needed anymore for HD6xx GPUs, but it
is still needed for HD4000.
After several unsuccesfull fixes we came to the conclusion that we could not support
the local context workaround and needed to come with a different workaround. The idea
of this patch is that in these cases there is only a single context that is used for
rendering. Threads that uses these contextes are guarded by a mutex and will block.
Impact on User Level:
* Due to main mutex lock the UI freezes when rendering or baking or feel less snappy
Reviewed By: Clément Foucault, Brecht van Lommel
Differential Revision: https://developer.blender.org/D8410
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 15 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.h | 5 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_context.cpp | 11 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_extensions.c | 10 |
4 files changed, 16 insertions, 25 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 0a1d6f560b6..155179205c5 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -1228,21 +1228,9 @@ bool GPU_pass_compile(GPUPass *pass, const char *shname) shader = NULL; } } - else if (!BLI_thread_is_main() && GPU_context_local_shaders_workaround()) { - pass->binary.content = GPU_shader_get_binary( - shader, &pass->binary.format, &pass->binary.len); - GPU_shader_free(shader); - shader = NULL; - } - pass->shader = shader; pass->compiled = true; } - else if (pass->binary.content && BLI_thread_is_main()) { - pass->shader = GPU_shader_load_from_binary( - pass->binary.content, pass->binary.format, pass->binary.len, shname); - MEM_SAFE_FREE(pass->binary.content); - } return success; } @@ -1263,9 +1251,6 @@ static void gpu_pass_free(GPUPass *pass) MEM_SAFE_FREE(pass->geometrycode); MEM_SAFE_FREE(pass->vertexcode); MEM_SAFE_FREE(pass->defines); - if (pass->binary.content) { - MEM_freeN(pass->binary.content); - } MEM_freeN(pass); } diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h index ce20f495ba3..e12e0c0ba08 100644 --- a/source/blender/gpu/intern/gpu_codegen.h +++ b/source/blender/gpu/intern/gpu_codegen.h @@ -43,11 +43,6 @@ typedef struct GPUPass { char *defines; uint refcount; /* Orphaned GPUPasses gets freed by the garbage collector. */ uint32_t hash; /* Identity hash generated from all GLSL code. */ - struct { - char *content; - uint format; - int len; - } binary; bool compiled; /* Did we already tried to compile the attached GPUShader. */ } GPUPass; diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp index 0b9104e5349..e6356580ea3 100644 --- a/source/blender/gpu/intern/gpu_context.cpp +++ b/source/blender/gpu/intern/gpu_context.cpp @@ -62,6 +62,7 @@ static std::vector<GLuint> orphaned_buffer_ids; static std::vector<GLuint> orphaned_texture_ids; static std::mutex orphans_mutex; +static std::mutex main_context_mutex; struct GPUContext { GLuint default_vao; @@ -345,3 +346,13 @@ struct GPUMatrixState *gpu_context_active_matrix_state_get() BLI_assert(active_ctx); return active_ctx->matrix_state; } + +void GPU_context_main_lock(void) +{ + main_context_mutex.lock(); +} + +void GPU_context_main_unlock(void) +{ + main_context_mutex.unlock(); +} diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 9aa3becef1d..9c37cc32e1d 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -95,7 +95,7 @@ static struct GPUGlobal { bool broken_amd_driver; /* Some crappy Intel drivers don't work well with shaders created in different * rendering contexts. */ - bool context_local_shaders_workaround; + bool use_main_context_workaround; /* Intel drivers exhibit artifacts when using #glCopyImageSubData & workbench anti-aliasing. * (see T76273) */ bool texture_copy_workaround; @@ -222,9 +222,9 @@ bool GPU_unused_fb_slot_workaround(void) return GG.unused_fb_slot_workaround; } -bool GPU_context_local_shaders_workaround(void) +bool GPU_use_main_context_workaround(void) { - return GG.context_local_shaders_workaround; + return GG.use_main_context_workaround; } bool GPU_texture_copy_workaround(void) @@ -381,12 +381,12 @@ void gpu_extensions_init(void) /* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`. * But it's hard to test each case. */ GG.glew_arb_base_instance_is_supported = false; - GG.context_local_shaders_workaround = true; + GG.use_main_context_workaround = true; } if (strstr(version, "Build 20.19.15.4285")) { /* Somehow fixes armature display issues (see T69743). */ - GG.context_local_shaders_workaround = true; + GG.use_main_context_workaround = true; } } else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && |