diff options
Diffstat (limited to 'source/blender/draw/engines')
17 files changed, 487 insertions, 271 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index 58676caa6f9..253981d321b 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -27,25 +27,12 @@ static void eevee_motion_blur_mesh_data_free(void *val) { - EEVEE_GeometryMotionData *geom_mb = (EEVEE_GeometryMotionData *)val; - EEVEE_HairMotionData *hair_mb = (EEVEE_HairMotionData *)val; - switch (geom_mb->type) { - case EEVEE_MOTION_DATA_HAIR: - for (int j = 0; j < hair_mb->psys_len; j++) { - for (int i = 0; i < ARRAY_SIZE(hair_mb->psys[0].hair_pos); i++) { - GPU_VERTBUF_DISCARD_SAFE(hair_mb->psys[j].hair_pos[i]); - } - for (int i = 0; i < ARRAY_SIZE(hair_mb->psys[0].hair_pos); i++) { - DRW_TEXTURE_FREE_SAFE(hair_mb->psys[j].hair_pos_tx[i]); - } - } - break; - - case EEVEE_MOTION_DATA_MESH: - for (int i = 0; i < ARRAY_SIZE(geom_mb->vbo); i++) { - GPU_VERTBUF_DISCARD_SAFE(geom_mb->vbo[i]); - } - break; + EEVEE_ObjectMotionData *mb_data = (EEVEE_ObjectMotionData *)val; + if (mb_data->hair_data != NULL) { + MEM_freeN(mb_data->hair_data); + } + if (mb_data->geometry_data != NULL) { + MEM_freeN(mb_data->geometry_data); } MEM_freeN(val); } @@ -84,39 +71,57 @@ static bool eevee_object_key_cmp(const void *a, const void *b) return false; } +void EEVEE_motion_hair_step_free(EEVEE_HairMotionStepData *step_data) +{ + GPU_vertbuf_discard(step_data->hair_pos); + DRW_texture_free(step_data->hair_pos_tx); + MEM_freeN(step_data); +} + void EEVEE_motion_blur_data_init(EEVEE_MotionBlurData *mb) { if (mb->object == NULL) { mb->object = BLI_ghash_new(eevee_object_key_hash, eevee_object_key_cmp, "EEVEE Object Motion"); } - if (mb->geom == NULL) { - mb->geom = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE Mesh Motion"); + for (int i = 0; i < 2; i++) { + if (mb->position_vbo_cache[i] == NULL) { + mb->position_vbo_cache[i] = BLI_ghash_new( + BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE duplicate vbo cache"); + } + if (mb->hair_motion_step_cache[i] == NULL) { + mb->hair_motion_step_cache[i] = BLI_ghash_new( + BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE hair motion step cache"); + } } } void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb) { if (mb->object) { - BLI_ghash_free(mb->object, MEM_freeN, MEM_freeN); + BLI_ghash_free(mb->object, MEM_freeN, eevee_motion_blur_mesh_data_free); mb->object = NULL; } - if (mb->geom) { - BLI_ghash_free(mb->geom, NULL, eevee_motion_blur_mesh_data_free); - mb->geom = NULL; + for (int i = 0; i < 2; i++) { + if (mb->position_vbo_cache[i]) { + BLI_ghash_free(mb->position_vbo_cache[i], NULL, (GHashValFreeFP)GPU_vertbuf_discard); + } + if (mb->hair_motion_step_cache[i]) { + BLI_ghash_free( + mb->hair_motion_step_cache[i], NULL, (GHashValFreeFP)EEVEE_motion_hair_step_free); + } } } -EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, - Object *ob, - bool hair) +EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob) { if (mb->object == NULL) { return NULL; } EEVEE_ObjectKey key, *key_p; - /* Small hack to avoid another comparison. */ - key.ob = (Object *)((char *)ob + hair); + /* Assumes that all instances have the same object pointer. This is currently the case because + * instance objects are temporary objects on the stack. */ + key.ob = ob; DupliObject *dup = DRW_object_get_dupli(ob); if (dup) { key.parent = DRW_object_get_dupli_parent(ob); @@ -139,53 +144,28 @@ EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData * return ob_step; } -static void *motion_blur_deform_data_get(EEVEE_MotionBlurData *mb, Object *ob, bool hair) +EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data) { - if (mb->geom == NULL) { - return NULL; + if (mb_data->geometry_data == NULL) { + EEVEE_GeometryMotionData *geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__); + geom_step->type = EEVEE_MOTION_DATA_MESH; + mb_data->geometry_data = geom_step; } - DupliObject *dup = DRW_object_get_dupli(ob); - void *key; - if (dup) { - key = dup->ob; - } - else { - key = ob; - } - /* Only use data for object that have no modifiers. */ - if (!BKE_object_is_modified(DRW_context_state_get()->scene, ob)) { - key = ob->data; - } - key = (char *)key + (int)hair; - EEVEE_GeometryMotionData *geom_step = BLI_ghash_lookup(mb->geom, key); - if (geom_step == NULL) { - if (hair) { - EEVEE_HairMotionData *hair_step; - /* Ugly, we allocate for each modifiers and just fill based on modifier index in the list. */ - int psys_len = (ob->type != OB_CURVES) ? BLI_listbase_count(&ob->modifiers) : 1; - hair_step = MEM_callocN(sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]) * psys_len, - __func__); - hair_step->psys_len = psys_len; - geom_step = (EEVEE_GeometryMotionData *)hair_step; - geom_step->type = EEVEE_MOTION_DATA_HAIR; - } - else { - geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__); - geom_step->type = EEVEE_MOTION_DATA_MESH; - } - BLI_ghash_insert(mb->geom, key, geom_step); - } - return geom_step; + return mb_data->geometry_data; } -EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb, Object *ob) +EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob) { - return motion_blur_deform_data_get(mb, ob, false); -} - -EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData *mb, Object *ob) -{ - return motion_blur_deform_data_get(mb, ob, true); + if (mb_data->hair_data == NULL) { + /* Ugly, we allocate for each modifiers and just fill based on modifier index in the list. */ + int psys_len = (ob->type != OB_CURVES) ? BLI_listbase_count(&ob->modifiers) : 1; + EEVEE_HairMotionData *hair_step = MEM_callocN( + sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]) * psys_len, __func__); + hair_step->psys_len = psys_len; + hair_step->type = EEVEE_MOTION_DATA_HAIR; + mb_data->hair_data = hair_step; + } + return mb_data->hair_data; } /* View Layer data. */ diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c index 39cfbb40318..ef4d88bd521 100644 --- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c +++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c @@ -626,11 +626,6 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl, "dof_reduced_color", UNPACK2(res), mip_count, GPU_RGBA16F, NULL); txl->dof_reduced_coc = GPU_texture_create_2d( "dof_reduced_coc", UNPACK2(res), mip_count, GPU_R16F, NULL); - - /* TODO(@fclem): Remove once we have immutable storage or when mips are generated on creation. - */ - GPU_texture_generate_mipmap(txl->dof_reduced_color); - GPU_texture_generate_mipmap(txl->dof_reduced_coc); } GPU_framebuffer_ensure_config(&fbl->dof_reduce_fb, diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index 93ffa2be9f3..fbc19a01a8b 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -226,15 +226,14 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), } /* For now we assume hair objects are always moving. */ - EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get( - &effects->motion_blur, ob, true); + EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob); if (mb_data) { int mb_step = effects->motion_blur_step; /* Store transform. */ DRW_hair_duplimat_get(ob, psys, md, mb_data->obmat[mb_step]); - EEVEE_HairMotionData *mb_hair = EEVEE_motion_blur_hair_data_get(&effects->motion_blur, ob); + EEVEE_HairMotionData *mb_hair = EEVEE_motion_blur_hair_data_get(mb_data, ob); int psys_id = (md != NULL) ? BLI_findindex(&ob->modifiers, md) : 0; if (psys_id >= mb_hair->psys_len) { @@ -252,8 +251,8 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), copy_m4_m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR]); } - GPUTexture *tex_prev = mb_hair->psys[psys_id].hair_pos_tx[MB_PREV]; - GPUTexture *tex_next = mb_hair->psys[psys_id].hair_pos_tx[MB_NEXT]; + GPUTexture *tex_prev = mb_hair->psys[psys_id].step_data[MB_PREV].hair_pos_tx; + GPUTexture *tex_next = mb_hair->psys[psys_id].step_data[MB_NEXT].hair_pos_tx; grp = DRW_shgroup_hair_create_sub(ob, psys, md, effects->motion_blur.hair_grp, NULL); DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]); @@ -265,7 +264,7 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), } else { /* Store vertex position buffer. */ - mb_hair->psys[psys_id].hair_pos[mb_step] = DRW_hair_pos_buffer_get(ob, psys, md); + mb_hair->psys[psys_id].step_data[mb_step].hair_pos = DRW_hair_pos_buffer_get(ob, psys, md); mb_hair->use_deform = true; } } @@ -304,24 +303,14 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), return; } - const DupliObject *dup = DRW_object_get_dupli(ob); - if (dup != NULL && dup->ob->data != dup->ob_data) { - /* Geometry instances do not support motion blur correctly yet. The #key used in - * #motion_blur_deform_data_get has to take ids of instances (#DupliObject.persistent_id) into - * account. Otherwise it can't find matching geometry instances at different points in time. */ - return; - } - - EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get( - &effects->motion_blur, ob, false); + EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob); if (mb_data) { int mb_step = effects->motion_blur_step; /* Store transform. */ copy_m4_m4(mb_data->obmat[mb_step], ob->obmat); - EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(&effects->motion_blur, - ob); + EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(mb_data); if (mb_step == MB_CURR) { GPUBatch *batch = DRW_cache_object_surface_get(ob); @@ -407,86 +396,93 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata) DRW_cache_restart(); } - for (BLI_ghashIterator_init(&ghi, effects->motion_blur.geom); + for (BLI_ghashIterator_init(&ghi, effects->motion_blur.object); BLI_ghashIterator_done(&ghi) == false; BLI_ghashIterator_step(&ghi)) { - EEVEE_GeometryMotionData *mb_geom = BLI_ghashIterator_getValue(&ghi); - EEVEE_HairMotionData *mb_hair = (EEVEE_HairMotionData *)mb_geom; - - if (!mb_geom->use_deform) { - continue; - } - - switch (mb_geom->type) { - case EEVEE_MOTION_DATA_HAIR: - if (mb_step == MB_CURR) { - /* TODO(fclem): Check if vertex count mismatch. */ - mb_hair->use_deform = true; - } - else { - for (int i = 0; i < mb_hair->psys_len; i++) { - if (mb_hair->psys[i].hair_pos[mb_step] == NULL) { - continue; - } - mb_hair->psys[i].hair_pos[mb_step] = GPU_vertbuf_duplicate( - mb_hair->psys[i].hair_pos[mb_step]); - + EEVEE_ObjectMotionData *mb_data = BLI_ghashIterator_getValue(&ghi); + EEVEE_HairMotionData *mb_hair = mb_data->hair_data; + EEVEE_GeometryMotionData *mb_geom = mb_data->geometry_data; + if (mb_hair != NULL && mb_hair->use_deform) { + if (mb_step == MB_CURR) { + /* TODO(fclem): Check if vertex count mismatch. */ + mb_hair->use_deform = true; + } + else { + for (int i = 0; i < mb_hair->psys_len; i++) { + GPUVertBuf *vbo = mb_hair->psys[i].step_data[mb_step].hair_pos; + if (vbo == NULL) { + continue; + } + EEVEE_HairMotionStepData **step_data_cache_ptr; + if (!BLI_ghash_ensure_p(effects->motion_blur.hair_motion_step_cache[mb_step], + vbo, + (void ***)&step_data_cache_ptr)) { + EEVEE_HairMotionStepData *new_step_data = MEM_callocN(sizeof(EEVEE_HairMotionStepData), + __func__); + /* Duplicate the vbo, otherwise it would be lost when evaluating another frame. */ + new_step_data->hair_pos = GPU_vertbuf_duplicate(vbo); /* Create vbo immediately to bind to texture buffer. */ - GPU_vertbuf_use(mb_hair->psys[i].hair_pos[mb_step]); - - mb_hair->psys[i].hair_pos_tx[mb_step] = GPU_texture_create_from_vertbuf( - "hair_pos_motion_blur", mb_hair->psys[i].hair_pos[mb_step]); + GPU_vertbuf_use(new_step_data->hair_pos); + new_step_data->hair_pos_tx = GPU_texture_create_from_vertbuf("hair_pos_motion_blur", + new_step_data->hair_pos); + *step_data_cache_ptr = new_step_data; } + mb_hair->psys[i].step_data[mb_step] = **step_data_cache_ptr; } - break; - - case EEVEE_MOTION_DATA_MESH: - if (mb_step == MB_CURR) { - /* Modify batch to have data from adjacent frames. */ - GPUBatch *batch = mb_geom->batch; - for (int i = 0; i < MB_CURR; i++) { - GPUVertBuf *vbo = mb_geom->vbo[i]; - if (vbo && batch) { - if (GPU_vertbuf_get_vertex_len(vbo) != GPU_vertbuf_get_vertex_len(batch->verts[0])) { - /* Vertex count mismatch, disable deform motion blur. */ - mb_geom->use_deform = false; - } - - if (mb_geom->use_deform == false) { - motion_blur_remove_vbo_reference_from_batch( - batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]); - - GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_PREV]); - GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_NEXT]); - break; - } + } + } + if (mb_geom != NULL && mb_geom->use_deform) { + if (mb_step == MB_CURR) { + /* Modify batch to have data from adjacent frames. */ + GPUBatch *batch = mb_geom->batch; + for (int i = 0; i < MB_CURR; i++) { + GPUVertBuf *vbo = mb_geom->vbo[i]; + if (vbo && batch) { + if (GPU_vertbuf_get_vertex_len(vbo) != GPU_vertbuf_get_vertex_len(batch->verts[0])) { + /* Vertex count mismatch, disable deform motion blur. */ + mb_geom->use_deform = false; + } + if (mb_geom->use_deform == false) { + motion_blur_remove_vbo_reference_from_batch( + batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]); + break; + } + /* Avoid adding the same vbo more than once when the batch is used by multiple + * instances. */ + if (!GPU_batch_vertbuf_has(batch, vbo)) { + /* Currently, the code assumes that all objects that share the same mesh in the + * current frame also share the same mesh on other frames. */ GPU_batch_vertbuf_add_ex(batch, vbo, false); } } } - else { - GPUVertBuf *vbo = mb_geom->vbo[mb_step]; - if (vbo) { - /* Use the vbo to perform the copy on the GPU. */ - GPU_vertbuf_use(vbo); - /* Perform a copy to avoid losing it after RE_engine_frame_set(). */ - mb_geom->vbo[mb_step] = vbo = GPU_vertbuf_duplicate(vbo); + } + else { + GPUVertBuf *vbo = mb_geom->vbo[mb_step]; + if (vbo) { + /* Use the vbo to perform the copy on the GPU. */ + GPU_vertbuf_use(vbo); + /* Perform a copy to avoid losing it after RE_engine_frame_set(). */ + GPUVertBuf **vbo_cache_ptr; + if (!BLI_ghash_ensure_p(effects->motion_blur.position_vbo_cache[mb_step], + vbo, + (void ***)&vbo_cache_ptr)) { + /* Duplicate the vbo, otherwise it would be lost when evaluating another frame. */ + GPUVertBuf *duplicated_vbo = GPU_vertbuf_duplicate(vbo); + *vbo_cache_ptr = duplicated_vbo; /* Find and replace "pos" attrib name. */ - GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(vbo); + GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(duplicated_vbo); int attrib_id = GPU_vertformat_attr_id_get(format, "pos"); GPU_vertformat_attr_rename(format, attrib_id, (mb_step == MB_PREV) ? "prv" : "nxt"); } - else { - /* This might happen if the object visibility has been animated. */ - mb_geom->use_deform = false; - } + mb_geom->vbo[mb_step] = vbo = *vbo_cache_ptr; } - break; - - default: - BLI_assert(0); - break; + else { + /* This might happen if the object visibility has been animated. */ + mb_geom->use_deform = false; + } + } } } } @@ -503,54 +499,62 @@ void EEVEE_motion_blur_swap_data(EEVEE_Data *vedata) /* Camera Data. */ effects->motion_blur.camera[MB_PREV] = effects->motion_blur.camera[MB_NEXT]; - /* Object Data. */ - for (BLI_ghashIterator_init(&ghi, effects->motion_blur.object); - BLI_ghashIterator_done(&ghi) == false; - BLI_ghashIterator_step(&ghi)) { - EEVEE_ObjectMotionData *mb_data = BLI_ghashIterator_getValue(&ghi); - - copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_NEXT]); + /* Swap #position_vbo_cache pointers. */ + if (effects->motion_blur.position_vbo_cache[MB_PREV]) { + BLI_ghash_free(effects->motion_blur.position_vbo_cache[MB_PREV], + NULL, + (GHashValFreeFP)GPU_vertbuf_discard); + } + effects->motion_blur.position_vbo_cache[MB_PREV] = + effects->motion_blur.position_vbo_cache[MB_NEXT]; + effects->motion_blur.position_vbo_cache[MB_NEXT] = NULL; + + /* Swap #hair_motion_step_cache pointers. */ + if (effects->motion_blur.hair_motion_step_cache[MB_PREV]) { + BLI_ghash_free(effects->motion_blur.hair_motion_step_cache[MB_PREV], + NULL, + (GHashValFreeFP)EEVEE_motion_hair_step_free); } + effects->motion_blur.hair_motion_step_cache[MB_PREV] = + effects->motion_blur.hair_motion_step_cache[MB_NEXT]; + effects->motion_blur.hair_motion_step_cache[MB_NEXT] = NULL; - /* Deformation Data. */ - for (BLI_ghashIterator_init(&ghi, effects->motion_blur.geom); - BLI_ghashIterator_done(&ghi) == false; + /* Rename attributes in #position_vbo_cache. */ + for (BLI_ghashIterator_init(&ghi, effects->motion_blur.position_vbo_cache[MB_PREV]); + !BLI_ghashIterator_done(&ghi); BLI_ghashIterator_step(&ghi)) { - EEVEE_GeometryMotionData *mb_geom = BLI_ghashIterator_getValue(&ghi); - EEVEE_HairMotionData *mb_hair = (EEVEE_HairMotionData *)mb_geom; + GPUVertBuf *vbo = BLI_ghashIterator_getValue(&ghi); + GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(vbo); + int attrib_id = GPU_vertformat_attr_id_get(format, "nxt"); + GPU_vertformat_attr_rename(format, attrib_id, "prv"); + } - switch (mb_geom->type) { - case EEVEE_MOTION_DATA_HAIR: - for (int i = 0; i < mb_hair->psys_len; i++) { - GPU_VERTBUF_DISCARD_SAFE(mb_hair->psys[i].hair_pos[MB_PREV]); - DRW_TEXTURE_FREE_SAFE(mb_hair->psys[i].hair_pos_tx[MB_PREV]); - mb_hair->psys[i].hair_pos[MB_PREV] = mb_hair->psys[i].hair_pos[MB_NEXT]; - mb_hair->psys[i].hair_pos_tx[MB_PREV] = mb_hair->psys[i].hair_pos_tx[MB_NEXT]; - mb_hair->psys[i].hair_pos[MB_NEXT] = NULL; - mb_hair->psys[i].hair_pos_tx[MB_NEXT] = NULL; - } - break; + /* Object Data. */ + for (BLI_ghashIterator_init(&ghi, effects->motion_blur.object); !BLI_ghashIterator_done(&ghi); + BLI_ghashIterator_step(&ghi)) { + EEVEE_ObjectMotionData *mb_data = BLI_ghashIterator_getValue(&ghi); + EEVEE_GeometryMotionData *mb_geom = mb_data->geometry_data; + EEVEE_HairMotionData *mb_hair = mb_data->hair_data; - case EEVEE_MOTION_DATA_MESH: - if (mb_geom->batch != NULL) { - motion_blur_remove_vbo_reference_from_batch( - mb_geom->batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]); - } - GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_PREV]); - mb_geom->vbo[MB_PREV] = mb_geom->vbo[MB_NEXT]; - mb_geom->vbo[MB_NEXT] = NULL; - - if (mb_geom->vbo[MB_PREV]) { - GPUVertBuf *vbo = mb_geom->vbo[MB_PREV]; - GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(vbo); - int attrib_id = GPU_vertformat_attr_id_get(format, "nxt"); - GPU_vertformat_attr_rename(format, attrib_id, "prv"); - } - break; + copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_NEXT]); - default: - BLI_assert(0); - break; + if (mb_hair != NULL) { + for (int i = 0; i < mb_hair->psys_len; i++) { + mb_hair->psys[i].step_data[MB_PREV].hair_pos = + mb_hair->psys[i].step_data[MB_NEXT].hair_pos; + mb_hair->psys[i].step_data[MB_PREV].hair_pos_tx = + mb_hair->psys[i].step_data[MB_NEXT].hair_pos_tx; + mb_hair->psys[i].step_data[MB_NEXT].hair_pos = NULL; + mb_hair->psys[i].step_data[MB_NEXT].hair_pos_tx = NULL; + } + } + if (mb_geom != NULL) { + if (mb_geom->batch != NULL) { + motion_blur_remove_vbo_reference_from_batch( + mb_geom->batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]); + } + mb_geom->vbo[MB_PREV] = mb_geom->vbo[MB_NEXT]; + mb_geom->vbo[MB_NEXT] = NULL; } } } diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index e8828cc7494..2518ee53da3 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -618,8 +618,23 @@ enum { #define MB_CURR 2 typedef struct EEVEE_MotionBlurData { + /** + * Maps #EEVEE_ObjectKey to #EEVEE_ObjectMotionData. + */ struct GHash *object; - struct GHash *geom; + /** + * Maps original #GPUVertBuf to duplicated #GPUVertBuf. + * There are two maps for #MB_PREV and #MB_NEXT. + * Only the values are owned. + */ + struct GHash *position_vbo_cache[2]; + /** + * Maps original #GPUVertBuf to #EEVEE_HairMotionStepData. + * There are two maps for #MB_PREV and #MB_NEXT. + * Only the values are owned. + */ + struct GHash *hair_motion_step_cache[2]; + struct { float viewmat[4][4]; float persmat[4][4]; @@ -637,15 +652,16 @@ typedef struct EEVEE_ObjectKey { int id[8]; /* MAX_DUPLI_RECUR */ } EEVEE_ObjectKey; -typedef struct EEVEE_ObjectMotionData { - float obmat[3][4][4]; -} EEVEE_ObjectMotionData; - typedef enum eEEVEEMotionData { EEVEE_MOTION_DATA_MESH = 0, EEVEE_MOTION_DATA_HAIR, } eEEVEEMotionData; +typedef struct EEVEE_HairMotionStepData { + struct GPUVertBuf *hair_pos; + struct GPUTexture *hair_pos_tx; +} EEVEE_HairMotionStepData; + typedef struct EEVEE_HairMotionData { /** Needs to be first to ensure casting. */ eEEVEEMotionData type; @@ -653,8 +669,8 @@ typedef struct EEVEE_HairMotionData { /** Allocator will alloc enough slot for all particle systems. Or 1 if it's a hair object. */ int psys_len; struct { - struct GPUVertBuf *hair_pos[2]; /* Position buffer for time = t +/- step. */ - struct GPUTexture *hair_pos_tx[2]; /* Buffer Texture of the corresponding VBO. */ + /* The vbos and textures are not owned. */ + EEVEE_HairMotionStepData step_data[2]; /* Data for time = t +/- step. */ } psys[0]; } EEVEE_HairMotionData; @@ -664,10 +680,18 @@ typedef struct EEVEE_GeometryMotionData { /** To disable deform mb if vertcount mismatch. */ int use_deform; + /* The batch and vbos are not owned. */ struct GPUBatch *batch; /* Batch for time = t. */ struct GPUVertBuf *vbo[2]; /* VBO for time = t +/- step. */ } EEVEE_GeometryMotionData; +typedef struct EEVEE_ObjectMotionData { + float obmat[3][4][4]; + + EEVEE_GeometryMotionData *geometry_data; + EEVEE_HairMotionData *hair_data; +} EEVEE_ObjectMotionData; + /* ************ EFFECTS DATA ************* */ typedef enum EEVEE_EffectsFlag { @@ -1062,17 +1086,15 @@ typedef struct EEVEE_PrivateData { void EEVEE_motion_blur_data_init(EEVEE_MotionBlurData *mb); void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb); void EEVEE_view_layer_data_free(void *storage); +void EEVEE_motion_hair_step_free(EEVEE_HairMotionStepData *step_data); EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void); EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer); EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void); EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob); EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob); -EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, - Object *ob, - bool hair); -EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb, - Object *ob); -EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData *mb, Object *ob); +EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob); +EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data); +EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob); EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob); EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob); EEVEE_LightEngineData *EEVEE_light_data_get(Object *ob); diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c index b5e9a296c16..29d98f6795d 100644 --- a/source/blender/draw/engines/eevee/eevee_shadows.c +++ b/source/blender/draw/engines/eevee/eevee_shadows.c @@ -273,11 +273,9 @@ void EEVEE_shadows_update(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) /* Resize shcasters buffers if too big. */ if (frontbuffer->alloc_count - frontbuffer->count > SH_CASTER_ALLOC_CHUNK) { - frontbuffer->alloc_count = (frontbuffer->count / SH_CASTER_ALLOC_CHUNK) * + frontbuffer->alloc_count = divide_ceil_u(max_ii(1, frontbuffer->count), + SH_CASTER_ALLOC_CHUNK) * SH_CASTER_ALLOC_CHUNK; - frontbuffer->alloc_count += (frontbuffer->count % SH_CASTER_ALLOC_CHUNK != 0) ? - SH_CASTER_ALLOC_CHUNK : - 0; frontbuffer->bbox = MEM_reallocN(frontbuffer->bbox, sizeof(EEVEE_BoundBox) * frontbuffer->alloc_count); BLI_BITMAP_RESIZE(frontbuffer->update, frontbuffer->alloc_count); diff --git a/source/blender/draw/engines/image/image_buffer_cache.hh b/source/blender/draw/engines/image/image_buffer_cache.hh new file mode 100644 index 00000000000..ef11551c879 --- /dev/null +++ b/source/blender/draw/engines/image/image_buffer_cache.hh @@ -0,0 +1,131 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2022, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + */ + +#pragma once + +#include "BLI_vector.hh" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +struct FloatImageBuffer { + ImBuf *source_buffer = nullptr; + ImBuf *float_buffer = nullptr; + bool is_used = true; + + FloatImageBuffer(ImBuf *source_buffer, ImBuf *float_buffer) + : source_buffer(source_buffer), float_buffer(float_buffer) + { + } + + FloatImageBuffer(FloatImageBuffer &&other) noexcept + { + source_buffer = other.source_buffer; + float_buffer = other.float_buffer; + is_used = other.is_used; + other.source_buffer = nullptr; + other.float_buffer = nullptr; + } + + virtual ~FloatImageBuffer() + { + IMB_freeImBuf(float_buffer); + float_buffer = nullptr; + source_buffer = nullptr; + } + + FloatImageBuffer &operator=(FloatImageBuffer &&other) noexcept + { + this->source_buffer = other.source_buffer; + this->float_buffer = other.float_buffer; + is_used = other.is_used; + other.source_buffer = nullptr; + other.float_buffer = nullptr; + return *this; + } +}; + +struct FloatBufferCache { + private: + blender::Vector<FloatImageBuffer> cache_; + + public: + ImBuf *ensure_float_buffer(ImBuf *image_buffer) + { + /* Check if we can use the float buffer of the given image_buffer. */ + if (image_buffer->rect_float != nullptr) { + return image_buffer; + } + + /* Do we have a cached float buffer. */ + for (FloatImageBuffer &item : cache_) { + if (item.source_buffer == image_buffer) { + item.is_used = true; + return item.float_buffer; + } + } + + /* Generate a new float buffer. */ + IMB_float_from_rect(image_buffer); + ImBuf *new_imbuf = IMB_allocImBuf(image_buffer->x, image_buffer->y, image_buffer->planes, 0); + new_imbuf->rect_float = image_buffer->rect_float; + new_imbuf->flags |= IB_rectfloat; + new_imbuf->mall |= IB_rectfloat; + image_buffer->rect_float = nullptr; + image_buffer->flags &= ~IB_rectfloat; + image_buffer->mall &= ~IB_rectfloat; + + cache_.append(FloatImageBuffer(image_buffer, new_imbuf)); + return new_imbuf; + } + + void reset_usage_flags() + { + for (FloatImageBuffer &buffer : cache_) { + buffer.is_used = false; + } + } + + void mark_used(const ImBuf *image_buffer) + { + for (FloatImageBuffer &item : cache_) { + if (item.source_buffer == image_buffer) { + item.is_used = true; + return; + } + } + } + + void remove_unused_buffers() + { + for (int64_t i = cache_.size() - 1; i >= 0; i--) { + if (!cache_[i].is_used) { + cache_.remove_and_reorder(i); + } + } + } + + void clear() + { + cache_.clear(); + } +}; diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index b3d6c3abd18..c091f800d95 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -157,6 +157,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD if (tile_buffer == nullptr) { continue; } + instance_data.float_buffers.mark_used(tile_buffer); BKE_image_release_ibuf(image, tile_buffer, lock); DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp); @@ -184,12 +185,14 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD switch (changes.get_result_code()) { case ePartialUpdateCollectResult::FullUpdateNeeded: instance_data.mark_all_texture_slots_dirty(); + instance_data.float_buffers.clear(); break; case ePartialUpdateCollectResult::NoChangesDetected: break; case ePartialUpdateCollectResult::PartialChangesDetected: /* Partial update when wrap repeat is enabled is not supported. */ if (instance_data.flags.do_tile_drawing) { + instance_data.float_buffers.clear(); instance_data.mark_all_texture_slots_dirty(); } else { @@ -200,6 +203,34 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD do_full_update_for_dirty_textures(instance_data, image_user); } + /** + * Update the float buffer in the region given by the partial update checker. + */ + void do_partial_update_float_buffer( + ImBuf *float_buffer, PartialUpdateChecker<ImageTileData>::CollectResult &iterator) const + { + ImBuf *src = iterator.tile_data.tile_buffer; + BLI_assert(float_buffer->rect_float != nullptr); + BLI_assert(float_buffer->rect == nullptr); + BLI_assert(src->rect_float == nullptr); + BLI_assert(src->rect != nullptr); + + /* Calculate the overlap between the updated region and the buffer size. Partial Update Checker + * always returns a tile (256x256). Which could lay partially outside the buffer when using + * different resolutions. + */ + rcti buffer_rect; + BLI_rcti_init(&buffer_rect, 0, float_buffer->x, 0, float_buffer->y); + rcti clipped_update_region; + const bool has_overlap = BLI_rcti_isect( + &buffer_rect, &iterator.changed_region.region, &clipped_update_region); + if (!has_overlap) { + return; + } + + IMB_float_from_rect_ex(float_buffer, src, &clipped_update_region); + } + void do_partial_update(PartialUpdateChecker<ImageTileData>::CollectResult &iterator, IMAGE_InstanceData &instance_data) const { @@ -208,7 +239,11 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD if (iterator.tile_data.tile_buffer == nullptr) { continue; } - ensure_float_buffer(*iterator.tile_data.tile_buffer); + ImBuf *tile_buffer = ensure_float_buffer(instance_data, iterator.tile_data.tile_buffer); + if (tile_buffer != iterator.tile_data.tile_buffer) { + do_partial_update_float_buffer(tile_buffer, iterator); + } + const float tile_width = static_cast<float>(iterator.tile_data.tile_buffer->x); const float tile_height = static_cast<float>(iterator.tile_data.tile_buffer->y); @@ -283,7 +318,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD &extracted_buffer, texture_region_width, texture_region_height, 32, IB_rectfloat); int offset = 0; - ImBuf *tile_buffer = iterator.tile_data.tile_buffer; for (int y = gpu_texture_region_to_update.ymin; y < gpu_texture_region_to_update.ymax; y++) { float yf = y / (float)texture_height; @@ -372,16 +406,12 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD * rect_float as the reference-counter isn't 0. To work around this we destruct any created local * buffers ourself. */ - bool ensure_float_buffer(ImBuf &image_buffer) const + ImBuf *ensure_float_buffer(IMAGE_InstanceData &instance_data, ImBuf *image_buffer) const { - if (image_buffer.rect_float == nullptr) { - IMB_float_from_rect(&image_buffer); - return true; - } - return false; + return instance_data.float_buffers.ensure_float_buffer(image_buffer); } - void do_full_update_texture_slot(const IMAGE_InstanceData &instance_data, + void do_full_update_texture_slot(IMAGE_InstanceData &instance_data, const TextureInfo &texture_info, ImBuf &texture_buffer, ImBuf &tile_buffer, @@ -389,10 +419,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD { const int texture_width = texture_buffer.x; const int texture_height = texture_buffer.y; - const bool float_buffer_created = ensure_float_buffer(tile_buffer); - /* TODO(jbakker): Find leak when rendering VSE and don't free here. */ - const bool do_free_float_buffer = float_buffer_created && - instance_data.image->type == IMA_TYPE_R_RESULT; + ImBuf *float_tile_buffer = ensure_float_buffer(instance_data, &tile_buffer); /* IMB_transform works in a non-consistent space. This should be documented or fixed!. * Construct a variant of the info_uv_to_texture that adds the texel space @@ -423,16 +450,12 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD transform_mode = IMB_TRANSFORM_MODE_CROP_SRC; } - IMB_transform(&tile_buffer, + IMB_transform(float_tile_buffer, &texture_buffer, transform_mode, IMB_FILTER_NEAREST, uv_to_texel, crop_rect_ptr); - - if (do_free_float_buffer) { - imb_freerectfloatImBuf(&tile_buffer); - } } public: @@ -451,6 +474,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD instance_data->partial_update.ensure_image(image); instance_data->clear_dirty_flag(); + instance_data->float_buffers.reset_usage_flags(); /* Step: Find out which screen space textures are needed to draw on the screen. Remove the * screen space textures that aren't needed. */ @@ -459,7 +483,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD method.update_screen_uv_bounds(); /* Check for changes in the image user compared to the last time. */ - instance_data->update_image_user(iuser); + instance_data->update_image_usage(iuser); /* Step: Update the GPU textures based on the changes in the image. */ instance_data->update_gpu_texture_allocations(); @@ -467,12 +491,16 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD /* Step: Add the GPU textures to the shgroup. */ instance_data->update_batches(); - add_depth_shgroups(*instance_data, image, iuser); + if (!instance_data->flags.do_tile_drawing) { + add_depth_shgroups(*instance_data, image, iuser); + } add_shgroups(instance_data); } - void draw_finish(IMAGE_Data *UNUSED(vedata)) const override + void draw_finish(IMAGE_Data *vedata) const override { + IMAGE_InstanceData *instance_data = vedata->instance_data; + instance_data->float_buffers.remove_unused_buffers(); } void draw_scene(IMAGE_Data *vedata) const override @@ -481,8 +509,10 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); GPU_framebuffer_bind(dfbl->default_fb); + static float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - GPU_framebuffer_clear_color_depth(dfbl->default_fb, clear_col, 1.0); + float clear_depth = instance_data->flags.do_tile_drawing ? 0.75 : 1.0f; + GPU_framebuffer_clear_color_depth(dfbl->default_fb, clear_col, clear_depth); DRW_view_set_active(instance_data->view); DRW_draw_pass(instance_data->passes.depth_pass); diff --git a/source/blender/draw/engines/image/image_engine.cc b/source/blender/draw/engines/image/image_engine.cc index 180e9601cbd..e972d21cda4 100644 --- a/source/blender/draw/engines/image/image_engine.cc +++ b/source/blender/draw/engines/image/image_engine.cc @@ -107,6 +107,7 @@ class ImageEngine { space->release_buffer(instance_data->image, image_buffer, lock); ImageUser *iuser = space->get_image_user(); + BKE_image_multiview_index(instance_data->image, iuser); drawing_mode.cache_image(vedata, instance_data->image, iuser); } diff --git a/source/blender/draw/engines/image/image_instance_data.hh b/source/blender/draw/engines/image/image_instance_data.hh index dcc3b7d15cb..682b93a80b3 100644 --- a/source/blender/draw/engines/image/image_instance_data.hh +++ b/source/blender/draw/engines/image/image_instance_data.hh @@ -8,10 +8,12 @@ #pragma once #include "image_batches.hh" +#include "image_buffer_cache.hh" #include "image_partial_updater.hh" #include "image_private.hh" #include "image_shader_params.hh" #include "image_texture_info.hh" +#include "image_usage.hh" #include "image_wrappers.hh" #include "DRW_render.h" @@ -25,8 +27,8 @@ constexpr int SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN = 1; struct IMAGE_InstanceData { struct Image *image; - /** Copy of the last image user to detect iuser differences that require a full update. */ - struct ImageUser last_image_user; + /** Usage data of the previous time, to identify changes that require a full update. */ + ImageUsage last_usage; PartialImageUpdater partial_update; @@ -47,11 +49,18 @@ struct IMAGE_InstanceData { DRWPass *depth_pass; } passes; + /** + * Cache containing the float buffers when drawing byte images. + */ + FloatBufferCache float_buffers; + /** \brief Transform matrix to convert a normalized screen space coordinates to texture space. */ float ss_to_texture[4][4]; TextureInfo texture_infos[SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN]; public: + virtual ~IMAGE_InstanceData() = default; + void clear_dirty_flag() { reset_dirty_flag(false); @@ -95,24 +104,13 @@ struct IMAGE_InstanceData { } } - void update_image_user(const ImageUser *image_user) + void update_image_usage(const ImageUser *image_user) { - short requested_pass = image_user ? image_user->pass : 0; - short requested_layer = image_user ? image_user->layer : 0; - short requested_view = image_user ? image_user->multi_index : 0; - /* There is room for 2 multiview textures. When a higher number is requested we should always - * target the first view slot. This is fine as multi view images aren't used together. */ - if (requested_view > 1) { - requested_view = 0; - } - - if (last_image_user.pass != requested_pass || last_image_user.layer != requested_layer || - last_image_user.multi_index != requested_view) { - - last_image_user.pass = requested_pass; - last_image_user.layer = requested_layer; - last_image_user.multi_index = requested_view; + ImageUsage usage(image, image_user, flags.do_tile_drawing); + if (last_usage != usage) { + last_usage = usage; reset_dirty_flag(true); + float_buffers.clear(); } } diff --git a/source/blender/draw/engines/image/image_usage.hh b/source/blender/draw/engines/image/image_usage.hh new file mode 100644 index 00000000000..bea5c3853b0 --- /dev/null +++ b/source/blender/draw/engines/image/image_usage.hh @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +/** \file + * \ingroup draw_engine + */ + +#pragma once + +/** + * ImageUsage contains data of the image and image user to identify changes that require a rebuild + * the texture slots. + */ +struct ImageUsage { + /** Render pass of the image that is used. */ + short pass = 0; + /** Layer of the image that is used.*/ + short layer = 0; + /** View of the image that is used. */ + short view = 0; + + ColorManagedColorspaceSettings colorspace_settings; + /** IMA_ALPHA_* */ + char alpha_mode; + bool last_tile_drawing; + + const void *last_image = nullptr; + + ImageUsage() = default; + ImageUsage(const struct Image *image, const struct ImageUser *image_user, bool do_tile_drawing) + { + pass = image_user ? image_user->pass : 0; + layer = image_user ? image_user->layer : 0; + view = image_user ? image_user->multi_index : 0; + colorspace_settings = image->colorspace_settings; + alpha_mode = image->alpha_mode; + last_image = static_cast<const void *>(image); + last_tile_drawing = do_tile_drawing; + } + + bool operator==(const ImageUsage &other) const + { + return memcmp(this, &other, sizeof(ImageUsage)) == 0; + } + bool operator!=(const ImageUsage &other) const + { + return !(*this == other); + } +}; diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index b41d9ce69ef..ad0d939e99a 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -182,7 +182,9 @@ static void OVERLAY_cache_init(void *vedata) case CTX_MODE_WEIGHT_GPENCIL: OVERLAY_edit_gpencil_cache_init(vedata); break; + case CTX_MODE_SCULPT_CURVES: case CTX_MODE_OBJECT: + case CTX_MODE_EDIT_CURVES: break; default: BLI_assert_msg(0, "Draw mode invalid"); @@ -210,7 +212,7 @@ BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bo { OVERLAY_DupliData **dupli_data = (OVERLAY_DupliData **)DRW_duplidata_get(vedata); *do_init = false; - if (!ELEM(ob->type, OB_MESH, OB_SURF, OB_LATTICE, OB_CURVE, OB_FONT)) { + if (!ELEM(ob->type, OB_MESH, OB_SURF, OB_LATTICE, OB_CURVES_LEGACY, OB_FONT)) { return NULL; } @@ -237,7 +239,7 @@ static bool overlay_object_is_edit_mode(const OVERLAY_PrivateData *pd, const Obj return pd->ctx_mode == CTX_MODE_EDIT_MESH; case OB_ARMATURE: return pd->ctx_mode == CTX_MODE_EDIT_ARMATURE; - case OB_CURVE: + case OB_CURVES_LEGACY: return pd->ctx_mode == CTX_MODE_EDIT_CURVE; case OB_SURF: return pd->ctx_mode == CTX_MODE_EDIT_SURFACE; @@ -296,7 +298,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) (ob->sculpt->mode_type == OB_MODE_SCULPT); const bool has_surface = ELEM(ob->type, OB_MESH, - OB_CURVE, + OB_CURVES_LEGACY, OB_SURF, OB_MBALL, OB_FONT, @@ -366,7 +368,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) OVERLAY_edit_armature_cache_populate(vedata, ob); } break; - case OB_CURVE: + case OB_CURVES_LEGACY: OVERLAY_edit_curve_cache_populate(vedata, ob); break; case OB_SURF: @@ -661,6 +663,8 @@ static void OVERLAY_draw_scene(void *vedata) case CTX_MODE_WEIGHT_GPENCIL: OVERLAY_edit_gpencil_draw(vedata); break; + case CTX_MODE_SCULPT_CURVES: + break; default: break; } diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c index e370873c234..aae12e5513e 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.c +++ b/source/blender/draw/engines/overlay/overlay_extra.c @@ -456,7 +456,7 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, cons case ID_ME: BKE_mesh_texspace_get_reference((Mesh *)ob_data, NULL, &texcoloc, &texcosize); break; - case ID_CU: { + case ID_CU_LEGACY: { Curve *cu = (Curve *)ob_data; BKE_curve_texspace_ensure(cu); texcoloc = cu->loc; @@ -499,7 +499,7 @@ static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLay int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); float *color = DRW_color_background_blend_get(theme_id); PartDeflect *pd = ob->pd; - Curve *cu = (ob->type == OB_CURVE) ? ob->data : NULL; + Curve *cu = (ob->type == OB_CURVES_LEGACY) ? ob->data : NULL; union { float mat[4][4]; diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.c b/source/blender/draw/engines/overlay/overlay_motion_path.c index 58825923f37..aeba721e7ac 100644 --- a/source/blender/draw/engines/overlay/overlay_motion_path.c +++ b/source/blender/draw/engines/overlay/overlay_motion_path.c @@ -90,8 +90,8 @@ static void motion_path_get_frame_range_to_draw(bAnimVizSettings *avs, end = current_frame + avs->path_ac + 1; } else { - start = avs->path_sf; - end = avs->path_ef; + start = mpath->start_frame; + end = mpath->end_frame; } if (start > end) { diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.c b/source/blender/draw/engines/overlay/overlay_wireframe.c index 24eceb30441..2636d7876d5 100644 --- a/source/blender/draw/engines/overlay/overlay_wireframe.c +++ b/source/blender/draw/engines/overlay/overlay_wireframe.c @@ -196,14 +196,14 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata, } } - if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { + if (ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) { OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob); float *color; DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color); struct GPUBatch *geom = NULL; switch (ob->type) { - case OB_CURVE: + case OB_CURVES_LEGACY: geom = DRW_cache_curve_edge_wire_get(ob); break; case OB_FONT: diff --git a/source/blender/draw/engines/overlay/shaders/paint_texture_frag.glsl b/source/blender/draw/engines/overlay/shaders/paint_texture_frag.glsl index 4d0692039a4..ebaa898429d 100644 --- a/source/blender/draw/engines/overlay/shaders/paint_texture_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/paint_texture_frag.glsl @@ -15,7 +15,7 @@ void main() if (maskInvertStencil) { mask.rgb = 1.0 - mask.rgb; } - float mask_step = smoothstep(0, 3.0, mask.r + mask.g + mask.b); + float mask_step = smoothstep(0.0, 3.0, mask.r + mask.g + mask.b); mask.rgb *= maskColor; mask.a = mask_step * opacity; diff --git a/source/blender/draw/engines/select/select_draw_utils.c b/source/blender/draw/engines/select/select_draw_utils.c index 82812ef98a5..7615b5bb39c 100644 --- a/source/blender/draw/engines/select/select_draw_utils.c +++ b/source/blender/draw/engines/select/select_draw_utils.c @@ -225,7 +225,7 @@ void select_id_draw_object(void *vedata, stl, ob, select_mode, initial_offset, r_vert_offset, r_edge_offset, r_face_offset); } break; - case OB_CURVE: + case OB_CURVES_LEGACY: case OB_SURF: break; } diff --git a/source/blender/draw/engines/workbench/workbench_opaque.c b/source/blender/draw/engines/workbench/workbench_opaque.c index 5e12d6a736c..191a2e6d1cc 100644 --- a/source/blender/draw/engines/workbench/workbench_opaque.c +++ b/source/blender/draw/engines/workbench/workbench_opaque.c @@ -73,11 +73,13 @@ void workbench_opaque_cache_init(WORKBENCH_Data *vedata) sh = workbench_shader_opaque_get(wpd, data); wpd->prepass[opaque][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass); + DRW_shgroup_uniform_block(grp, "world_data", wpd->world_ubo); DRW_shgroup_uniform_block(grp, "materials_data", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1); DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); wpd->prepass[opaque][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass); + DRW_shgroup_uniform_block(grp, "world_data", wpd->world_ubo); DRW_shgroup_uniform_block(grp, "materials_data", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */ DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); @@ -85,6 +87,7 @@ void workbench_opaque_cache_init(WORKBENCH_Data *vedata) sh = workbench_shader_opaque_image_get(wpd, data, false); wpd->prepass[opaque][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass); + DRW_shgroup_uniform_block(grp, "world_data", wpd->world_ubo); DRW_shgroup_uniform_block(grp, "materials_data", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */ DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); @@ -92,6 +95,7 @@ void workbench_opaque_cache_init(WORKBENCH_Data *vedata) sh = workbench_shader_opaque_image_get(wpd, data, true); wpd->prepass[opaque][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass); + DRW_shgroup_uniform_block(grp, "world_data", wpd->world_ubo); DRW_shgroup_uniform_block(grp, "materials_data", wpd->material_ubo_curr); DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */ DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap); |