EEVEE-Next: Fix ObjectHandle::recalc #115243

Merged
Miguel Pozo merged 3 commits from pragma37/blender:pull-recalc-last_update-eevee into main 2023-11-27 12:23:27 +01:00
5 changed files with 34 additions and 16 deletions

View File

@ -180,7 +180,7 @@ void Instance::scene_sync()
/* This refers specifically to the Scene camera that can be accessed
* via View Layer Attribute nodes, rather than the actual render camera. */
if (scene->camera != nullptr) {
ObjectHandle &ob_handle = sync.sync_object(scene->camera);
ObjectHandle &ob_handle = sync.sync_object({scene->camera, nullptr, nullptr});
ob_handle.reset_recalc_flag();
}
@ -209,7 +209,7 @@ void Instance::object_sync(Object *ob)
/* TODO cleanup. */
ObjectRef ob_ref = DRW_object_ref_get(ob);
ObjectHandle &ob_handle = sync.sync_object(ob);
ObjectHandle &ob_handle = sync.sync_object(ob_ref);
ResourceHandle res_handle = {0};
if (is_drawable_type) {
res_handle = manager->resource_handle(ob_ref);
@ -289,6 +289,8 @@ void Instance::end_sync()
planar_probes.end_sync();
global_ubo_.push_update();
depsgraph_last_update_ = DEG_get_update_count(depsgraph);
}
void Instance::render_sync()

View File

@ -54,6 +54,8 @@ class Instance {
UniformDataBuf global_ubo_;
uint64_t depsgraph_last_update_ = 0;
public:
ShaderModule &shaders;
SyncModule sync;
@ -229,6 +231,27 @@ class Instance {
pass->bind_ubo(UNIFORM_BUF_SLOT, &global_ubo_);
}
int get_recalc_flags(const ObjectRef &ob_ref)
{
auto get_flags = [&](const ObjectRuntimeHandle &runtime) {
int flags = 0;
SET_FLAG_FROM_TEST(
flags, runtime.last_update_transform > depsgraph_last_update_, ID_RECALC_TRANSFORM);
SET_FLAG_FROM_TEST(
flags, runtime.last_update_geometry > depsgraph_last_update_, ID_RECALC_GEOMETRY);
SET_FLAG_FROM_TEST(
flags, runtime.last_update_shading > depsgraph_last_update_, ID_RECALC_SHADING);
return flags;
};
int flags = get_flags(*ob_ref.object->runtime);
if (ob_ref.dupli_parent) {
flags |= get_flags(*ob_ref.dupli_parent->runtime);
}
return flags;
}
private:
static void object_sync_render(void *instance_,
Object *ob,

View File

@ -40,27 +40,19 @@ static void draw_data_init_cb(DrawData *dd)
dd->recalc = ID_RECALC_ALL;
}
ObjectHandle &SyncModule::sync_object(Object *ob)
ObjectHandle &SyncModule::sync_object(const ObjectRef &ob_ref)
{
ObjectKey key(ob);
ObjectKey key(ob_ref.object);
ObjectHandle &handle = ob_handles.lookup_or_add_cb(key, [&]() {
ObjectHandle new_handle;
new_handle.object_key = key;
new_handle.recalc = ID_RECALC_ALL;
return new_handle;
});
/** TODO(Miguel Pozo): DrawData is the only way of retrieving the correct recalc flags.
* We should find a more optimal way to handle this. */
DrawEngineType *owner = (DrawEngineType *)&DRW_engine_viewport_eevee_next_type;
DrawData *dd = DRW_drawdata_ensure((ID *)ob, owner, sizeof(DrawData), nullptr, nullptr);
handle.recalc |= dd->recalc;
dd->recalc = 0;
handle.recalc = inst_.get_recalc_flags(ob_ref);
const int recalc_flags = ID_RECALC_COPY_ON_WRITE | ID_RECALC_TRANSFORM | ID_RECALC_SHADING |
ID_RECALC_GEOMETRY;
if ((handle.recalc & recalc_flags) != 0) {
if (handle.recalc != 0) {
inst_.sampling.reset();
}

View File

@ -140,7 +140,7 @@ class SyncModule {
SyncModule(Instance &inst) : inst_(inst){};
~SyncModule(){};
ObjectHandle &sync_object(Object *ob);
ObjectHandle &sync_object(const ObjectRef &ob_ref);
WorldHandle &sync_world(::World *world);
SceneHandle &sync_scene(::Scene *scene);

View File

@ -78,7 +78,8 @@ static void step_object_sync_render(void *instance,
/* NOTE: Dummy resource handle since this won't be used for drawing. */
ResourceHandle resource_handle(0);
ObjectHandle &ob_handle = inst.sync.sync_object(ob);
ObjectRef ob_ref = DRW_object_ref_get(ob);
ObjectHandle &ob_handle = inst.sync.sync_object(ob_ref);
if (partsys_is_visible) {
auto sync_hair =