diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-03-13 05:58:00 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-03-13 05:58:00 +0300 |
commit | 0f1d7a5796e530e8843dfae7f8e0dfd41fa9465d (patch) | |
tree | e2ff66a1f45c8364089e3346a9ee7f323b529238 /source/blender/draw/intern/draw_manager_shader.c | |
parent | 0acccda4a4146dfa0f2d9d848adc83d21a83c0b7 (diff) |
Eevee: Render: Fix softlock if rendering before lazy shader compil ends.
Calling the rendering operator seems to kill any other WM_job running, leaving
uncompiled materials into a GPU_MAT_QUEUED state. This then made the probe update
looping indefinitely (all_materials_updated remaining to false).
To fix this, we resume compilation for materials that are in this state.
Cancelling Render before all material compilation could make certain material
remain uncompiled. Fortunately, this is not allowed as of now.
Diffstat (limited to 'source/blender/draw/intern/draw_manager_shader.c')
-rw-r--r-- | source/blender/draw/intern/draw_manager_shader.c | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 69c13bb61c2..d150bcc8d56 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -162,8 +162,11 @@ static void drw_deferred_shader_compilation_free(void *custom_data) static void drw_deferred_shader_add( GPUMaterial *mat, const char *vert, const char *geom, const char *frag_lib, const char *defines) { + /* Do not deferre the compilation if we are rendering for image. */ if (DRW_state_is_image_render()) { - /* Do not deferre the compilation if we are rendering for image. */ + /* Double checking that this GPUMaterial is not going to be + * compiled by another thread. */ + DRW_deferred_shader_remove(mat); GPU_material_generate_pass(mat, vert, geom, frag_lib, defines); return; } @@ -302,13 +305,46 @@ GPUShader *DRW_shader_create_3D_depth_only(void) return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY); } +GPUMaterial *DRW_shader_find_from_world(World *wo, const void *engine_type, int options) +{ + GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options); + if (DRW_state_is_image_render()) { + if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) { + /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX + * with the shader code and we will resume the compilation from there. */ + return NULL; + } + } + return mat; +} + +GPUMaterial *DRW_shader_find_from_material(Material *ma, const void *engine_type, int options) +{ + GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options); + if (DRW_state_is_image_render()) { + if (mat != NULL && GPU_material_status(mat) == GPU_MAT_QUEUED) { + /* XXX Hack : we return NULL so that the engine will call DRW_shader_create_from_XXX + * with the shader code and we will resume the compilation from there. */ + return NULL; + } + } + return mat; +} + GPUMaterial *DRW_shader_create_from_world( struct Scene *scene, World *wo, const void *engine_type, int options, const char *vert, const char *geom, const char *frag_lib, const char *defines) { - GPUMaterial *mat = GPU_material_from_nodetree( - scene, wo->nodetree, &wo->gpumaterial, engine_type, options, - vert, geom, frag_lib, defines, true); + GPUMaterial *mat = NULL; + if (DRW_state_is_image_render()) { + mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine_type, options); + } + + if (mat == NULL) { + mat = GPU_material_from_nodetree( + scene, wo->nodetree, &wo->gpumaterial, engine_type, options, + vert, geom, frag_lib, defines, true); + } drw_deferred_shader_add(mat, vert, geom, frag_lib, defines); @@ -319,9 +355,16 @@ GPUMaterial *DRW_shader_create_from_material( struct Scene *scene, Material *ma, const void *engine_type, int options, const char *vert, const char *geom, const char *frag_lib, const char *defines) { - GPUMaterial *mat = GPU_material_from_nodetree( - scene, ma->nodetree, &ma->gpumaterial, engine_type, options, - vert, geom, frag_lib, defines, true); + GPUMaterial *mat = NULL; + if (DRW_state_is_image_render()) { + mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine_type, options); + } + + if (mat == NULL) { + mat = GPU_material_from_nodetree( + scene, ma->nodetree, &ma->gpumaterial, engine_type, options, + vert, geom, frag_lib, defines, true); + } drw_deferred_shader_add(mat, vert, geom, frag_lib, defines); |