WIP: Draw: Replace GPU_material_recalc_flag with depsgraph updates #115760

Draft
Miguel Pozo wants to merge 1 commits from pragma37/blender:pull-replace-material-recalc into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 33 additions and 25 deletions
Showing only changes of commit ec72fab717 - Show all commits

View File

@ -199,10 +199,6 @@ MaterialPass MaterialModule::material_pass_get(Object *ob,
inst_.manager->register_layer_attributes(matpass.gpumat);
if (GPU_material_recalc_flag_get(matpass.gpumat)) {
inst_.sampling.reset();
}
const bool is_transparent = GPU_material_flag_get(matpass.gpumat, GPU_MATFLAG_TRANSPARENT);
if (is_volume || (is_forward && is_transparent)) {
/* Sub pass is generated later. */

View File

@ -56,6 +56,9 @@ struct DRWShaderCompiler {
ListBase queue; /* GPUMaterial */
SpinLock list_lock;
/** Compiled materials to be released and tagged by the update callback. */
blender::Vector<GPUMaterial *> compiled_materials;
/** Optimization queue. */
ListBase optimize_queue; /* GPUMaterial */
@ -105,7 +108,9 @@ static void drw_deferred_shader_compilation_exec(void *custom_data,
if (mat) {
/* Do the compilation. */
GPU_material_compile(mat);
GPU_material_release(mat);
BLI_spin_lock(&comp->list_lock);
comp->compiled_materials.append(mat);
BLI_spin_unlock(&comp->list_lock);
MEM_freeN(link);
}
else {
@ -147,6 +152,24 @@ static void drw_deferred_shader_compilation_exec(void *custom_data,
GPU_render_end();
}
static void drw_deferred_shader_compilation_update(void *custom_data)
{
DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data;
BLI_spin_lock(&comp->list_lock);
for (GPUMaterial *mat : comp->compiled_materials) {
if (Material *bl_mat = GPU_material_get_material(mat)) {
DEG_id_tag_update(&bl_mat->id, ID_RECALC_SHADING);
}
GPU_material_release(mat);
}
comp->compiled_materials.clear();
BLI_spin_unlock(&comp->list_lock);
}
static void drw_deferred_shader_compilation_free(void *custom_data)
{
DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data;
@ -166,7 +189,7 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
wm_window_reset_drawable();
}
MEM_freeN(comp);
MEM_delete(comp);
}
/**
@ -190,8 +213,7 @@ static void drw_deferred_queue_append(GPUMaterial *mat, bool is_optimization_job
DRWShaderCompiler *old_comp = (DRWShaderCompiler *)WM_jobs_customdata_get(wm_job);
DRWShaderCompiler *comp = static_cast<DRWShaderCompiler *>(
MEM_callocN(sizeof(DRWShaderCompiler), "DRWShaderCompiler"));
DRWShaderCompiler *comp = MEM_new<DRWShaderCompiler>("DRWShaderCompiler");
BLI_spin_init(&comp->list_lock);
if (old_comp) {
@ -241,7 +263,11 @@ static void drw_deferred_queue_append(GPUMaterial *mat, bool is_optimization_job
WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free);
WM_jobs_timer(wm_job, 0.1, NC_MATERIAL | ND_SHADING_DRAW, 0);
WM_jobs_delay_start(wm_job, 0.1);
WM_jobs_callbacks(wm_job, drw_deferred_shader_compilation_exec, nullptr, nullptr, nullptr);
WM_jobs_callbacks(wm_job,
drw_deferred_shader_compilation_exec,
nullptr,
is_optimization_job ? nullptr : drw_deferred_shader_compilation_update,
nullptr);
G.is_break = false;

View File

@ -69,6 +69,7 @@ typedef enum eGPUType {
} eGPUType;
typedef enum eGPUMaterialFlag {
GPU_MATFLAG_NONE = 0,
GPU_MATFLAG_DIFFUSE = (1 << 0),
GPU_MATFLAG_SUBSURFACE = (1 << 1),
GPU_MATFLAG_GLOSSY = (1 << 2),
@ -95,9 +96,6 @@ typedef enum eGPUMaterialFlag {
GPU_MATFLAG_PRINCIPLED_GLASS = (1 << 24),
GPU_MATFLAG_PRINCIPLED_ANY = (1 << 25),
/* Tells the render engine the material was just compiled or updated. */
GPU_MATFLAG_UPDATED = (1 << 29),
/* HACK(fclem) Tells the environment texture node to not bail out if empty. */
GPU_MATFLAG_LOOKDEV_HACK = (1 << 30),
} eGPUMaterialFlag;
@ -328,7 +326,6 @@ bool GPU_material_has_displacement_output(GPUMaterial *mat);
void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag);
bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag);
eGPUMaterialFlag GPU_material_flag(const GPUMaterial *mat);
bool GPU_material_recalc_flag_get(GPUMaterial *mat);
uint64_t GPU_material_uuid_get(GPUMaterial *mat);
void GPU_pass_cache_init(void);

View File

@ -802,15 +802,6 @@ eGPUMaterialFlag GPU_material_flag(const GPUMaterial *mat)
return mat->flag;
}
bool GPU_material_recalc_flag_get(GPUMaterial *mat)
{
/* NOTE: Consumes the flags. */
bool updated = (mat->flag & GPU_MATFLAG_UPDATED) != 0;
mat->flag &= ~GPU_MATFLAG_UPDATED;
return updated;
}
uint64_t GPU_material_uuid_get(GPUMaterial *mat)
{
return mat->uuid;
@ -839,7 +830,7 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
mat->ma = ma;
mat->scene = scene;
mat->uuid = shader_uuid;
mat->flag = GPU_MATFLAG_UPDATED;
mat->flag = GPU_MATFLAG_NONE;
mat->status = GPU_MAT_CREATED;
mat->default_mat = nullptr;
mat->is_volume_shader = is_volume_shader;
@ -950,8 +941,6 @@ void GPU_material_compile(GPUMaterial *mat)
success = GPU_pass_compile(mat->pass, __func__);
#endif
mat->flag |= GPU_MATFLAG_UPDATED;
if (success) {
GPUShader *sh = GPU_pass_shader_get(mat->pass);
if (sh != nullptr) {