From 442608fa2764d7a69a5e7e6a1648e3f598c61ef8 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 22 Jul 2023 18:21:04 +0300 Subject: [PATCH 1/7] Simplified and improved working with RenderTaskDelegate --- source/blender/render/hydra/final_engine.cc | 12 +- source/blender/render/hydra/preview_engine.cc | 6 +- .../render/hydra/render_task_delegate.cc | 117 ++++++++---------- .../render/hydra/render_task_delegate.h | 24 ++-- .../blender/render/hydra/viewport_engine.cc | 16 +-- 5 files changed, 83 insertions(+), 92 deletions(-) diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index ebc6d91c9218..f4da8c49ecc1 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -22,7 +22,7 @@ namespace blender::render::hydra { void FinalEngine::render(Depsgraph *depsgraph) { prepare_for_render(depsgraph); - render_task_delegate_->set_renderer_aov(pxr::HdAovTokens->color); + render_task_delegate_->add_aov(pxr::HdAovTokens->color); engine_->Execute(render_index_.get(), &tasks_); @@ -48,11 +48,11 @@ void FinalEngine::render(Depsgraph *depsgraph) break; } - render_task_delegate_->get_renderer_aov_data(pxr::HdAovTokens->color, pixels.data()); + render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); update_render_result(); } - render_task_delegate_->get_renderer_aov_data(pxr::HdAovTokens->color, pixels.data()); + render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); update_render_result(); } @@ -104,14 +104,14 @@ void FinalEngine::prepare_for_render(Depsgraph *depsgraph) CameraData(scene->camera, image_res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(border); free_camera_delegate_->SetCamera(camera); - render_task_delegate_->set_camera_and_viewport( - free_camera_delegate_->GetCameraId(), pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); + render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId()); + render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); if (light_tasks_delegate_) { light_tasks_delegate_->set_camera_and_viewport( free_camera_delegate_->GetCameraId(), pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); tasks_ = light_tasks_delegate_->get_tasks(); } - tasks_.push_back(render_task_delegate_->get_task()); + tasks_.push_back(render_task_delegate_->task()); render_images_.emplace( "Combined", diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index a0d7205287c8..771453816c17 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -15,7 +15,7 @@ namespace blender::render::hydra { void PreviewEngine::render(Depsgraph *depsgraph) { prepare_for_render(depsgraph); - render_task_delegate_->set_renderer_aov(pxr::HdAovTokens->color); + render_task_delegate_->add_aov(pxr::HdAovTokens->color); engine_->Execute(render_index_.get(), &tasks_); @@ -29,11 +29,11 @@ void PreviewEngine::render(Depsgraph *depsgraph) break; } - render_task_delegate_->get_renderer_aov_data(pxr::HdAovTokens->color, pixels.data()); + render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); update_render_result(pixels); } - render_task_delegate_->get_renderer_aov_data(pxr::HdAovTokens->color, pixels.data()); + render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); update_render_result(pixels); } diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 5351be086ca2..6285ccecd106 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -1,8 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#include - #include #include #include @@ -15,74 +13,58 @@ RenderTaskDelegate::RenderTaskDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id) : pxr::HdSceneDelegate(parent_index, delegate_id) { - pxr::SdfPath render_task_id = get_task_id(); - GetRenderIndex().InsertTask(this, render_task_id); - GetRenderIndex().GetChangeTracker().MarkTaskDirty(render_task_id, - pxr::HdChangeTracker::DirtyCollection); - GetRenderIndex().GetChangeTracker().MarkTaskDirty(render_task_id, - pxr::HdChangeTracker::DirtyRenderTags); + task_id_ = GetDelegateID().AppendElementString("task"); + GetRenderIndex().InsertTask(this, task_id_); task_params_.enableLighting = true; task_params_.alphaThreshold = 0.1f; } -pxr::SdfPath RenderTaskDelegate::get_task_id() const -{ - return GetDelegateID().AppendElementString("task"); -} - -pxr::SdfPath RenderTaskDelegate::get_aov_id(pxr::TfToken const &aov) const +pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov) const { return GetDelegateID().AppendElementString("aov_" + aov.GetString()); } bool RenderTaskDelegate::is_converged() { - pxr::HdTaskSharedPtr renderTask = GetRenderIndex().GetTask(get_task_id()); - return ((pxr::HdxRenderTask &)*renderTask).IsConverged(); + return ((pxr::HdxRenderTask *)task().get())->IsConverged(); } -void RenderTaskDelegate::set_renderer_aov(pxr::TfToken const &aov) +void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) { - pxr::HdAovDescriptor aov_desc = GetRenderIndex().GetRenderDelegate()->GetDefaultAovDescriptor( - aov); - pxr::HdRenderBufferDescriptor desc( - pxr::GfVec3i(task_params_.viewport[2], task_params_.viewport[3], 1), + auto &render_index = GetRenderIndex(); + pxr::SdfPath buf_id = buffer_id(aov_key); + if (buffer_descriptors_.find(buf_id) != buffer_descriptors_.end()) { + return; + } + pxr::HdAovDescriptor aov_desc = render_index.GetRenderDelegate()->GetDefaultAovDescriptor( + aov_key); + + int w = task_params_.viewport[2] - task_params_.viewport[0]; + int h = task_params_.viewport[3] - task_params_.viewport[1]; + render_index.InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, this, buf_id); + buffer_descriptors_[buf_id] = pxr::HdRenderBufferDescriptor( + pxr::GfVec3i(w, h, 1), aov_desc.format, aov_desc.multiSampled); - pxr::SdfPath buffer_id = get_aov_id(aov); - if (buffer_descriptors_.find(buffer_id) == buffer_descriptors_.end()) { - GetRenderIndex().InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, this, buffer_id); - buffer_descriptors_[buffer_id] = desc; - GetRenderIndex().GetChangeTracker().MarkBprimDirty(buffer_id, - pxr::HdRenderBuffer::DirtyDescription); - - pxr::HdRenderPassAovBinding binding; - binding.aovName = aov; - binding.renderBufferId = buffer_id; - binding.aovSettings = aov_desc.aovSettings; - task_params_.aovBindings.push_back(binding); - - GetRenderIndex().GetChangeTracker().MarkTaskDirty(get_task_id(), - pxr::HdChangeTracker::DirtyParams); - } - else if (buffer_descriptors_[buffer_id] != desc) { - buffer_descriptors_[buffer_id] = desc; - GetRenderIndex().GetChangeTracker().MarkBprimDirty(buffer_id, - pxr::HdRenderBuffer::DirtyDescription); - } + pxr::HdRenderPassAovBinding binding; + binding.aovName = aov_key; + binding.renderBufferId = buf_id; + binding.aovSettings = aov_desc.aovSettings; + task_params_.aovBindings.push_back(binding); + render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); } -pxr::HdRenderBuffer *RenderTaskDelegate::get_renderer_aov(pxr::TfToken const &aov) +pxr::HdRenderBuffer *RenderTaskDelegate::get_aov(pxr::TfToken const &aov_key) { - return (pxr::HdRenderBuffer *)(GetRenderIndex().GetBprim(pxr::HdPrimTypeTokens->renderBuffer, - get_aov_id(aov))); + return (pxr::HdRenderBuffer *)GetRenderIndex().GetBprim(pxr::HdPrimTypeTokens->renderBuffer, + buffer_id(aov_key)); } -void RenderTaskDelegate::get_renderer_aov_data(pxr::TfToken const &aov, void *data) +void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov, void *data) { - pxr::HdRenderBuffer *buffer = get_renderer_aov(aov); + pxr::HdRenderBuffer *buffer = get_aov(aov); void *buf_data = buffer->Map(); memcpy(data, buf_data, @@ -90,19 +72,32 @@ void RenderTaskDelegate::get_renderer_aov_data(pxr::TfToken const &aov, void *da buffer->Unmap(); } -pxr::HdTaskSharedPtr RenderTaskDelegate::get_task() +pxr::HdTaskSharedPtr RenderTaskDelegate::task() { - return GetRenderIndex().GetTask(get_task_id()); + return GetRenderIndex().GetTask(task_id_); } -void RenderTaskDelegate::set_camera_and_viewport(pxr::SdfPath const &camera_id, - pxr::GfVec4d const &viewport) +void RenderTaskDelegate::set_camera(pxr::SdfPath const &camera_id) { - if (task_params_.viewport != viewport || task_params_.camera != camera_id) { - task_params_.viewport = viewport; - task_params_.camera = camera_id; - GetRenderIndex().GetChangeTracker().MarkTaskDirty(get_task_id(), - pxr::HdChangeTracker::DirtyParams); + task_params_.camera = camera_id; + GetRenderIndex().GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); +} + +void RenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) +{ + if (task_params_.viewport == viewport) { + return; + } + auto &render_index = GetRenderIndex(); + task_params_.viewport = viewport; + render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); + + int w = viewport[2] - viewport[0]; + int h = viewport[3] - viewport[1]; + for (auto &it : buffer_descriptors_) { + it.second.dimensions = pxr::GfVec3i(w, h, 1); + render_index.GetChangeTracker().MarkBprimDirty(it.first, + pxr::HdRenderBuffer::DirtyDescription); } } @@ -112,12 +107,8 @@ pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const & /*id*/, pxr::TfToken c return pxr::VtValue(task_params_); } if (key == pxr::HdTokens->collection) { - pxr::HdRprimCollection rprim_collection(pxr::HdTokens->geometry, - pxr::HdReprSelector(pxr::HdReprTokens->smoothHull), - false, - pxr::TfToken()); - rprim_collection.SetRootPath(pxr::SdfPath::AbsoluteRootPath()); - return pxr::VtValue(rprim_collection); + return pxr::VtValue(pxr::HdRprimCollection( + pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->smoothHull))); } return pxr::VtValue(); } @@ -127,7 +118,7 @@ pxr::HdRenderBufferDescriptor RenderTaskDelegate::GetRenderBufferDescriptor(pxr: return buffer_descriptors_[id]; } -pxr::TfTokenVector RenderTaskDelegate::GetTaskRenderTags(pxr::SdfPath const & /*task_id*/) +pxr::TfTokenVector RenderTaskDelegate::GetTaskRenderTags(pxr::SdfPath const & /*id*/) { return {pxr::HdRenderTagTokens->geometry}; } diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index f8a1a956816c..758ee4c9d5ff 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -13,23 +13,23 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate { RenderTaskDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id); ~RenderTaskDelegate() override = default; - pxr::SdfPath get_task_id() const; - pxr::SdfPath get_aov_id(pxr::TfToken const &aov) const; - - bool is_converged(); - void set_renderer_aov(pxr::TfToken const &aovId); - pxr::HdRenderBuffer *get_renderer_aov(pxr::TfToken const &id); - void get_renderer_aov_data(pxr::TfToken const &id, void *buf); - - pxr::HdTaskSharedPtr get_task(); - void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport); - /* Delegate methods */ pxr::VtValue Get(pxr::SdfPath const &id, pxr::TfToken const &key) override; + pxr::TfTokenVector GetTaskRenderTags(pxr::SdfPath const &id) override; pxr::HdRenderBufferDescriptor GetRenderBufferDescriptor(pxr::SdfPath const &id) override; - pxr::TfTokenVector GetTaskRenderTags(pxr::SdfPath const &taskId) override; + + pxr::HdTaskSharedPtr task(); + void set_camera(pxr::SdfPath const &camera_id); + void set_viewport(pxr::GfVec4d const &viewport); + void add_aov(pxr::TfToken const &aov_key); + pxr::HdRenderBuffer *get_aov(pxr::TfToken const &aov_key); + void get_aov_data(pxr::TfToken const &aov_key, void *data); + bool is_converged(); private: + pxr::SdfPath buffer_id(pxr::TfToken const &aov) const; + + pxr::SdfPath task_id_; pxr::HdxRenderTaskParams task_params_; pxr::TfHashMap buffer_descriptors_; diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index b16c4ad776ae..f15742a67999 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -231,11 +231,11 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) pxr::GfCamera gf_camera = view_settings.gf_camera(); free_camera_delegate_->SetCamera(gf_camera); - render_task_delegate_->set_camera_and_viewport(free_camera_delegate_->GetCameraId(), - pxr::GfVec4d(view_settings.border[0], - view_settings.border[1], - view_settings.border[2], - view_settings.border[3])); + render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId()); + render_task_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0], + view_settings.border[1], + view_settings.border[2], + view_settings.border[3])); if (light_tasks_delegate_) { light_tasks_delegate_->set_camera_and_viewport(free_camera_delegate_->GetCameraId(), @@ -246,7 +246,7 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) } if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - render_task_delegate_->set_renderer_aov(pxr::HdAovTokens->color); + render_task_delegate_->add_aov(pxr::HdAovTokens->color); } GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); @@ -256,12 +256,12 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) if (light_tasks_delegate_) { tasks = light_tasks_delegate_->get_tasks(); } - tasks.push_back(render_task_delegate_->get_task()); + tasks.push_back(render_task_delegate_->task()); engine_->Execute(render_index_.get(), &tasks); if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - draw_texture_.set_buffer(render_task_delegate_->get_renderer_aov(pxr::HdAovTokens->color)); + draw_texture_.set_buffer(render_task_delegate_->get_aov(pxr::HdAovTokens->color)); draw_texture_.draw(shader, view_settings.border[0], view_settings.border[1]); } -- 2.30.2 From 35bc8deb9c2e6e238a698a611cc0c95208599271 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sun, 23 Jul 2023 01:14:23 +0300 Subject: [PATCH 2/7] Improved working with LightTasksDelegate --- source/blender/render/hydra/final_engine.cc | 7 +- .../render/hydra/light_tasks_delegate.cc | 69 +++++++----- .../render/hydra/light_tasks_delegate.h | 11 +- .../render/hydra/render_task_delegate.cc | 103 +++++++++--------- .../blender/render/hydra/viewport_engine.cc | 13 ++- 5 files changed, 110 insertions(+), 93 deletions(-) diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index f4da8c49ecc1..5b226719e581 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -107,9 +107,10 @@ void FinalEngine::prepare_for_render(Depsgraph *depsgraph) render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId()); render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); if (light_tasks_delegate_) { - light_tasks_delegate_->set_camera_and_viewport( - free_camera_delegate_->GetCameraId(), pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); - tasks_ = light_tasks_delegate_->get_tasks(); + light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId()); + light_tasks_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); + tasks_.push_back(light_tasks_delegate_->skydome_task()); + tasks_.push_back(light_tasks_delegate_->simple_task()); } tasks_.push_back(render_task_delegate_->task()); diff --git a/source/blender/render/hydra/light_tasks_delegate.cc b/source/blender/render/hydra/light_tasks_delegate.cc index 237ac8b0fc4b..82730c042da5 100644 --- a/source/blender/render/hydra/light_tasks_delegate.cc +++ b/source/blender/render/hydra/light_tasks_delegate.cc @@ -1,9 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#include -#include - #include "light_tasks_delegate.h" namespace blender::render::hydra { @@ -12,34 +9,10 @@ LightTasksDelegate::LightTasksDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id) : pxr::HdSceneDelegate(parent_index, delegate_id) { - skydome_task_id_ = GetDelegateID().AppendElementString("simpleLightTask"); - simple_task_id_ = GetDelegateID().AppendElementString("skydomeTask"); - GetRenderIndex().InsertTask(this, skydome_task_id_); + simple_task_id_ = GetDelegateID().AppendElementString("simpleTask"); GetRenderIndex().InsertTask(this, simple_task_id_); -} - -pxr::HdTaskSharedPtrVector LightTasksDelegate::get_tasks() -{ - /*Note that this task is intended to be the first "Render Task", - so that the AOV's are properly cleared, however it - does not spawn a HdRenderPass.*/ - return {GetRenderIndex().GetTask(skydome_task_id_), GetRenderIndex().GetTask(simple_task_id_)}; -} - -void LightTasksDelegate::set_camera_and_viewport(pxr::SdfPath const &camera_id, - pxr::GfVec4d const &viewport) -{ - if (simple_task_params_.cameraPath != camera_id) { - simple_task_params_.cameraPath = camera_id; - GetRenderIndex().GetChangeTracker().MarkTaskDirty(simple_task_id_, - pxr::HdChangeTracker::DirtyParams); - } - if (skydome_task_params_.viewport != viewport || skydome_task_params_.camera != camera_id) { - skydome_task_params_.viewport = viewport; - skydome_task_params_.camera = camera_id; - GetRenderIndex().GetChangeTracker().MarkTaskDirty(skydome_task_id_, - pxr::HdChangeTracker::DirtyParams); - } + skydome_task_id_ = GetDelegateID().AppendElementString("skydomeTask"); + GetRenderIndex().InsertTask(this, skydome_task_id_); } pxr::VtValue LightTasksDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key) @@ -55,4 +28,40 @@ pxr::VtValue LightTasksDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const return pxr::VtValue(); } +pxr::HdTaskSharedPtr LightTasksDelegate::simple_task() +{ + return GetRenderIndex().GetTask(simple_task_id_); +} + +pxr::HdTaskSharedPtr LightTasksDelegate::skydome_task() +{ + /* Note that this task is intended to be the first "Render Task", + so that the AOV's are properly cleared, however it + does not spawn a HdRenderPass. */ + return GetRenderIndex().GetTask(skydome_task_id_); +} + +void LightTasksDelegate::set_camera(pxr::SdfPath const &camera_id) +{ + if (simple_task_params_.cameraPath == camera_id) { + return; + } + simple_task_params_.cameraPath = camera_id; + GetRenderIndex().GetChangeTracker().MarkTaskDirty(simple_task_id_, + pxr::HdChangeTracker::DirtyParams); + skydome_task_params_.camera = camera_id; + GetRenderIndex().GetChangeTracker().MarkTaskDirty(skydome_task_id_, + pxr::HdChangeTracker::DirtyParams); +} + +void LightTasksDelegate::set_viewport(pxr::GfVec4d const &viewport) +{ + if (skydome_task_params_.viewport == viewport) { + return; + } + skydome_task_params_.viewport = viewport; + GetRenderIndex().GetChangeTracker().MarkTaskDirty(skydome_task_id_, + pxr::HdChangeTracker::DirtyParams); +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/light_tasks_delegate.h b/source/blender/render/hydra/light_tasks_delegate.h index ac99e4932623..bb94fa00a670 100644 --- a/source/blender/render/hydra/light_tasks_delegate.h +++ b/source/blender/render/hydra/light_tasks_delegate.h @@ -4,8 +4,8 @@ #pragma once #include -#include #include +#include namespace blender::render::hydra { @@ -14,12 +14,15 @@ class LightTasksDelegate : public pxr::HdSceneDelegate { LightTasksDelegate(pxr::HdRenderIndex *parentIndex, pxr::SdfPath const &delegate_id); ~LightTasksDelegate() override = default; - pxr::HdTaskSharedPtrVector get_tasks(); - void set_camera_and_viewport(pxr::SdfPath const &camera_id, pxr::GfVec4d const &viewport); - /* Delegate methods */ pxr::VtValue Get(pxr::SdfPath const &id, pxr::TfToken const &key) override; + pxr::HdTaskSharedPtr simple_task(); + pxr::HdTaskSharedPtr skydome_task(); + void set_camera(pxr::SdfPath const &camera_id); + void set_viewport(pxr::GfVec4d const &viewport); + + private: pxr::SdfPath simple_task_id_; pxr::SdfPath skydome_task_id_; diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 6285ccecd106..d2d1e88ddcd4 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -20,23 +20,67 @@ RenderTaskDelegate::RenderTaskDelegate(pxr::HdRenderIndex *parent_index, task_params_.alphaThreshold = 0.1f; } -pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov) const +pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const & /*id*/, pxr::TfToken const &key) { - return GetDelegateID().AppendElementString("aov_" + aov.GetString()); + if (key == pxr::HdTokens->params) { + return pxr::VtValue(task_params_); + } + if (key == pxr::HdTokens->collection) { + return pxr::VtValue(pxr::HdRprimCollection( + pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->smoothHull))); + } + return pxr::VtValue(); } -bool RenderTaskDelegate::is_converged() +pxr::TfTokenVector RenderTaskDelegate::GetTaskRenderTags(pxr::SdfPath const & /*id*/) { - return ((pxr::HdxRenderTask *)task().get())->IsConverged(); + return {pxr::HdRenderTagTokens->geometry}; +} + +pxr::HdRenderBufferDescriptor RenderTaskDelegate::GetRenderBufferDescriptor(pxr::SdfPath const &id) +{ + return buffer_descriptors_[id]; +} + +pxr::HdTaskSharedPtr RenderTaskDelegate::task() +{ + return GetRenderIndex().GetTask(task_id_); +} + +void RenderTaskDelegate::set_camera(pxr::SdfPath const &camera_id) +{ + if (task_params_.camera == camera_id) { + return; + } + task_params_.camera = camera_id; + GetRenderIndex().GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); +} + +void RenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) +{ + if (task_params_.viewport == viewport) { + return; + } + auto &render_index = GetRenderIndex(); + task_params_.viewport = viewport; + render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); + + int w = viewport[2] - viewport[0]; + int h = viewport[3] - viewport[1]; + for (auto &it : buffer_descriptors_) { + it.second.dimensions = pxr::GfVec3i(w, h, 1); + render_index.GetChangeTracker().MarkBprimDirty(it.first, + pxr::HdRenderBuffer::DirtyDescription); + } } void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) { - auto &render_index = GetRenderIndex(); pxr::SdfPath buf_id = buffer_id(aov_key); if (buffer_descriptors_.find(buf_id) != buffer_descriptors_.end()) { return; } + auto &render_index = GetRenderIndex(); pxr::HdAovDescriptor aov_desc = render_index.GetRenderDelegate()->GetDefaultAovDescriptor( aov_key); @@ -72,55 +116,14 @@ void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov, void *data) buffer->Unmap(); } -pxr::HdTaskSharedPtr RenderTaskDelegate::task() +bool RenderTaskDelegate::is_converged() { - return GetRenderIndex().GetTask(task_id_); + return ((pxr::HdxRenderTask *)task().get())->IsConverged(); } -void RenderTaskDelegate::set_camera(pxr::SdfPath const &camera_id) +pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov) const { - task_params_.camera = camera_id; - GetRenderIndex().GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); -} - -void RenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) -{ - if (task_params_.viewport == viewport) { - return; - } - auto &render_index = GetRenderIndex(); - task_params_.viewport = viewport; - render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); - - int w = viewport[2] - viewport[0]; - int h = viewport[3] - viewport[1]; - for (auto &it : buffer_descriptors_) { - it.second.dimensions = pxr::GfVec3i(w, h, 1); - render_index.GetChangeTracker().MarkBprimDirty(it.first, - pxr::HdRenderBuffer::DirtyDescription); - } -} - -pxr::VtValue RenderTaskDelegate::Get(pxr::SdfPath const & /*id*/, pxr::TfToken const &key) -{ - if (key == pxr::HdTokens->params) { - return pxr::VtValue(task_params_); - } - if (key == pxr::HdTokens->collection) { - return pxr::VtValue(pxr::HdRprimCollection( - pxr::HdTokens->geometry, pxr::HdReprSelector(pxr::HdReprTokens->smoothHull))); - } - return pxr::VtValue(); -} - -pxr::HdRenderBufferDescriptor RenderTaskDelegate::GetRenderBufferDescriptor(pxr::SdfPath const &id) -{ - return buffer_descriptors_[id]; -} - -pxr::TfTokenVector RenderTaskDelegate::GetTaskRenderTags(pxr::SdfPath const & /*id*/) -{ - return {pxr::HdRenderTagTokens->geometry}; + return GetDelegateID().AppendElementString("aov_" + aov.GetString()); } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index f15742a67999..075010424184 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -238,11 +238,11 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) view_settings.border[3])); if (light_tasks_delegate_) { - light_tasks_delegate_->set_camera_and_viewport(free_camera_delegate_->GetCameraId(), - pxr::GfVec4d(view_settings.border[0], - view_settings.border[1], - view_settings.border[2], - view_settings.border[3])); + light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId()); + light_tasks_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0], + view_settings.border[1], + view_settings.border[2], + view_settings.border[3])); } if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { @@ -254,7 +254,8 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) pxr::HdTaskSharedPtrVector tasks; if (light_tasks_delegate_) { - tasks = light_tasks_delegate_->get_tasks(); + tasks.push_back(light_tasks_delegate_->skydome_task()); + tasks.push_back(light_tasks_delegate_->simple_task()); } tasks.push_back(render_task_delegate_->task()); -- 2.30.2 From d3af74e678137bb62d944bb4c1b37ea13bf7fc36 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sun, 23 Jul 2023 03:10:52 +0300 Subject: [PATCH 3/7] Refactored FinalEngine and FinalEngineGPU. Simplified PreviewEngine --- source/blender/render/hydra/final_engine.cc | 254 +++++++++--------- source/blender/render/hydra/final_engine.h | 28 +- .../render/hydra/light_tasks_delegate.h | 1 - source/blender/render/hydra/preview_engine.cc | 110 +------- source/blender/render/hydra/preview_engine.h | 9 +- .../render/hydra/render_task_delegate.cc | 4 +- 6 files changed, 159 insertions(+), 247 deletions(-) diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 5b226719e581..d5566ffe3e92 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -1,15 +1,12 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#include - #include +#include #include "BKE_lib_id.h" #include "BLI_timecode.h" #include "DEG_depsgraph_query.h" -#include "GPU_framebuffer.h" -#include "GPU_texture.h" #include "PIL_time.h" #include "IMB_imbuf_types.h" @@ -19,75 +16,16 @@ namespace blender::render::hydra { +/* FinalEngine implementation */ + void FinalEngine::render(Depsgraph *depsgraph) -{ - prepare_for_render(depsgraph); - render_task_delegate_->add_aov(pxr::HdAovTokens->color); - - engine_->Execute(render_index_.get(), &tasks_); - - std::vector &pixels = render_images_["Combined"]; - char elapsed_time[32]; - double time_begin = PIL_check_seconds_timer(); - float percent_done = 0.0; - - while (true) { - if (RE_engine_test_break(bl_engine_)) { - break; - } - - percent_done = renderer_percent_done(); - BLI_timecode_string_from_time_simple( - elapsed_time, sizeof(elapsed_time), PIL_check_seconds_timer() - time_begin); - notify_status(percent_done / 100.0, - scene_name_ + ": " + layer_name_, - std::string("Render Time: ") + elapsed_time + - " | Done: " + std::to_string(int(percent_done)) + "%"); - - if (render_task_delegate_->is_converged()) { - break; - } - - render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); - update_render_result(); - } - - render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); - update_render_result(); -} - -void FinalEngine::update_render_result() -{ - RenderResult *result = RE_engine_begin_result( - bl_engine_, 0, 0, resolution_[0], resolution_[1], layer_name_.c_str(), nullptr); - - /* TODO: only for the first render layer */ - RenderLayer *layer = (RenderLayer *)result->layers.first; - for (RenderPass *pass = (RenderPass *)layer->passes.first; pass != nullptr; pass = pass->next) { - auto it_image = render_images_.find(pass->name); - if (it_image == render_images_.end()) { - continue; - } - memcpy(pass->ibuf->float_buffer.data, - it_image->second.data(), - sizeof(float) * pass->rectx * pass->recty * pass->channels); - } - - RE_engine_end_result(bl_engine_, result, false, false, false); -} - -void FinalEngine::notify_status(float progress, const std::string &title, const std::string &info) -{ - RE_engine_update_progress(bl_engine_, progress); - RE_engine_update_stats(bl_engine_, title.c_str(), info.c_str()); -} - -void FinalEngine::prepare_for_render(Depsgraph *depsgraph) { const Scene *scene = DEG_get_evaluated_scene(depsgraph); const ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - BKE_id_full_name_get(scene_name_.data(), (ID *)scene, 0); + char scene_name[MAX_NAME]; + BKE_id_full_name_get(scene_name, (ID *)scene, 0); + scene_name_ = scene_name; layer_name_ = view_layer->name; const RenderData &r = scene->r; @@ -103,64 +41,22 @@ void FinalEngine::prepare_for_render(Depsgraph *depsgraph) pxr::GfCamera camera = CameraData(scene->camera, image_res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(border); + pxr::HdTaskSharedPtrVector tasks; free_camera_delegate_->SetCamera(camera); render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId()); render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); if (light_tasks_delegate_) { light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId()); light_tasks_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); - tasks_.push_back(light_tasks_delegate_->skydome_task()); - tasks_.push_back(light_tasks_delegate_->simple_task()); + tasks.push_back(light_tasks_delegate_->skydome_task()); + tasks.push_back(light_tasks_delegate_->simple_task()); } - tasks_.push_back(render_task_delegate_->task()); + tasks.push_back(render_task_delegate_->task()); - render_images_.emplace( - "Combined", - std::vector(resolution_[0] * resolution_[1] * 4)); /* 4 - number of channels. */ -} + set_aovs(); -void FinalEngineGPU::render(Depsgraph *depsgraph) -{ - prepare_for_render(depsgraph); + engine_->Execute(render_index_.get(), &tasks); - GPUFrameBuffer *framebuffer = GPU_framebuffer_create("fb_render_hydra"); - GPUTexture *tex_color = GPU_texture_create_2d("tex_render_hydra_color", - resolution_[0], - resolution_[1], - 1, - GPU_RGBA32F, - GPU_TEXTURE_USAGE_GENERAL, - nullptr); - GPUTexture *tex_depth = GPU_texture_create_2d("tex_render_hydra_depth", - resolution_[0], - resolution_[1], - 1, - GPU_DEPTH32F_STENCIL8, - GPU_TEXTURE_USAGE_GENERAL, - nullptr); - GPU_texture_filter_mode(tex_color, true); - GPU_texture_mipmap_mode(tex_color, true, true); - GPU_texture_filter_mode(tex_depth, true); - GPU_texture_mipmap_mode(tex_depth, true, true); - - GPU_framebuffer_ensure_config( - &framebuffer, {GPU_ATTACHMENT_TEXTURE(tex_depth), GPU_ATTACHMENT_TEXTURE(tex_color)}); - - GPU_framebuffer_bind(framebuffer); - - float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - - GPU_framebuffer_clear_color_depth(framebuffer, clear_color, 1.0f); - - /* Important: we have to create and bind at least one Vertex Array Object (VAO) before render - execution: More info at https://open.gl/drawing */ - GLuint VAO; - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - - engine_->Execute(render_index_.get(), &tasks_); - - std::vector &pixels = render_images_["Combined"]; char elapsed_time[32]; double time_begin = PIL_check_seconds_timer(); float percent_done = 0.0; @@ -171,10 +67,8 @@ void FinalEngineGPU::render(Depsgraph *depsgraph) } percent_done = renderer_percent_done(); - BLI_timecode_string_from_time_simple( elapsed_time, sizeof(elapsed_time), PIL_check_seconds_timer() - time_begin); - notify_status(percent_done / 100.0, scene_name_ + ": " + layer_name_, std::string("Render Time: ") + elapsed_time + @@ -184,21 +78,125 @@ void FinalEngineGPU::render(Depsgraph *depsgraph) break; } - void *data = GPU_texture_read(tex_color, GPU_DATA_FLOAT, 0); - memcpy(pixels.data(), data, pixels.size() * sizeof(float)); - MEM_freeN(data); update_render_result(); } - void *data = GPU_texture_read(tex_color, GPU_DATA_FLOAT, 0); - memcpy(pixels.data(), data, pixels.size() * sizeof(float)); - MEM_freeN(data); update_render_result(); - glDeleteVertexArrays(1, &VAO); - GPU_framebuffer_free(framebuffer); - GPU_texture_free(tex_color); - GPU_texture_free(tex_depth); + post_render(); +} + +void FinalEngine::notify_status(float progress, const std::string &title, const std::string &info) +{ + RE_engine_update_progress(bl_engine_, progress); + RE_engine_update_stats(bl_engine_, title.c_str(), info.c_str()); +} + +void FinalEngine::update_render_result() +{ + RenderResult *result = RE_engine_begin_result( + bl_engine_, 0, 0, resolution_[0], resolution_[1], layer_name_.c_str(), nullptr); + + /* TODO: only for the first render layer */ + RenderLayer *layer = (RenderLayer *)result->layers.first; + for (RenderPass *pass = (RenderPass *)layer->passes.first; pass != nullptr; pass = pass->next) { + update_render_pass(pass); + } + + RE_engine_end_result(bl_engine_, result, false, false, false); +} + +void FinalEngine::update_render_pass(RenderPass *pass) +{ + pxr::HdRenderBuffer *buf = nullptr; + if (STREQ(pass->name, "Combined")) { + buf = render_task_delegate_->get_aov(pxr::HdAovTokens->color); + } + else if (STREQ(pass->name, "Depth")) { + buf = render_task_delegate_->get_aov(pxr::HdAovTokens->depth); + } + if (!buf) { + return; + } + void *data = buf->Map(); + memcpy(pass->ibuf->float_buffer.data, + data, + sizeof(float) * pass->rectx * pass->recty * pass->channels); + buf->Unmap(); +} + +void FinalEngine::set_aovs() +{ + render_task_delegate_->add_aov(pxr::HdAovTokens->color); +} + +void FinalEngine::post_render() {} + +/* FinalEngineGPU implementation */ + +void FinalEngineGPU::update_render_pass(RenderPass *pass) +{ + GPUTexture *tex = nullptr; + if (STREQ(pass->name, "Combined")) { + tex = tex_color_; + } + else if (STREQ(pass->name, "Depth")) { + tex = tex_depth_; + } + if (!tex) { + return; + } + void *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 0); + memcpy(pass->ibuf->float_buffer.data, + data, + sizeof(float) * pass->rectx * pass->recty * pass->channels); + MEM_freeN(data); +} + +void FinalEngineGPU::set_aovs() +{ + framebuffer_ = GPU_framebuffer_create("fb_render_hydra"); + tex_color_ = GPU_texture_create_2d("tex_render_hydra_color", + resolution_[0], + resolution_[1], + 1, + GPU_RGBA32F, + GPU_TEXTURE_USAGE_GENERAL, + nullptr); + tex_depth_ = GPU_texture_create_2d("tex_render_hydra_depth", + resolution_[0], + resolution_[1], + 1, + GPU_DEPTH32F_STENCIL8, + GPU_TEXTURE_USAGE_GENERAL, + nullptr); + GPU_texture_filter_mode(tex_color_, true); + GPU_texture_mipmap_mode(tex_color_, true, true); + GPU_texture_filter_mode(tex_depth_, true); + GPU_texture_mipmap_mode(tex_depth_, true, true); + + GPU_framebuffer_ensure_config( + &framebuffer_, {GPU_ATTACHMENT_TEXTURE(tex_depth_), GPU_ATTACHMENT_TEXTURE(tex_color_)}); + + GPU_framebuffer_bind(framebuffer_); + + float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + + GPU_framebuffer_clear_color_depth(framebuffer_, clear_color, 1.0f); + + /* Important: we have to create and bind at least one Vertex Array Object (VAO) before render + execution: More info at https://open.gl/drawing */ + GLuint VAO_; + glGenVertexArrays(1, &VAO_); + glBindVertexArray(VAO_); +} + +void FinalEngineGPU::post_render() +{ + glDeleteVertexArrays(1, &VAO_); + GPU_framebuffer_free(framebuffer_); + GPU_texture_free(tex_color_); + GPU_texture_free(tex_depth_); } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/final_engine.h b/source/blender/render/hydra/final_engine.h index 2ab44bbadaa5..eee0f7eff0a9 100644 --- a/source/blender/render/hydra/final_engine.h +++ b/source/blender/render/hydra/final_engine.h @@ -3,6 +3,11 @@ #pragma once +#include + +#include "GPU_framebuffer.h" +#include "GPU_texture.h" + #include "engine.h" namespace blender::render::hydra { @@ -11,18 +16,17 @@ class FinalEngine : public Engine { public: using Engine::Engine; - void render(Depsgraph *b_depsgraph) override; + void render(Depsgraph *depsgraph) override; protected: - void update_render_result(); - void notify_status(float progress, const std::string &title, const std::string &info); - void prepare_for_render(Depsgraph *depsgraph); + virtual void notify_status(float progress, const std::string &title, const std::string &info); + virtual void update_render_result(); + virtual void update_render_pass(RenderPass *pass); + virtual void set_aovs(); + virtual void post_render(); - pxr::HdRenderSettingsMap render_settings_; - pxr::HdTaskSharedPtrVector tasks_; std::string scene_name_; std::string layer_name_; - std::map> render_images_; pxr::GfVec2i resolution_; }; @@ -30,7 +34,15 @@ class FinalEngineGPU : public FinalEngine { public: using FinalEngine::FinalEngine; - void render(Depsgraph *depsgraph) override; + protected: + void update_render_pass(RenderPass *pass) override; + void set_aovs() override; + void post_render() override; + + GPUFrameBuffer *framebuffer_; + GPUTexture *tex_color_; + GPUTexture *tex_depth_; + GLuint VAO_; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/light_tasks_delegate.h b/source/blender/render/hydra/light_tasks_delegate.h index bb94fa00a670..6b350469bb72 100644 --- a/source/blender/render/hydra/light_tasks_delegate.h +++ b/source/blender/render/hydra/light_tasks_delegate.h @@ -22,7 +22,6 @@ class LightTasksDelegate : public pxr::HdSceneDelegate { void set_camera(pxr::SdfPath const &camera_id); void set_viewport(pxr::GfVec4d const &viewport); - private: pxr::SdfPath simple_task_id_; pxr::SdfPath skydome_task_id_; diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index 771453816c17..fb812807c97f 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -12,112 +12,18 @@ namespace blender::render::hydra { -void PreviewEngine::render(Depsgraph *depsgraph) +void PreviewEngine::notify_status(float progress, + const std::string &title, + const std::string &info) { - prepare_for_render(depsgraph); - render_task_delegate_->add_aov(pxr::HdAovTokens->color); - - engine_->Execute(render_index_.get(), &tasks_); - - std::vector &pixels = render_images_["Combined"]; - while (true) { - if (RE_engine_test_break(bl_engine_)) { - break; - } - - if (render_task_delegate_->is_converged()) { - break; - } - - render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); - update_render_result(pixels); - } - - render_task_delegate_->get_aov_data(pxr::HdAovTokens->color, pixels.data()); - update_render_result(pixels); + /* Empty fucntion */ } -void PreviewEngineGPU::render(Depsgraph *depsgraph) +void PreviewEngineGPU::notify_status(float progress, + const std::string &title, + const std::string &info) { - prepare_for_render(depsgraph); - - GPUFrameBuffer *framebuffer = GPU_framebuffer_create("fb_render_mat_prev_hydra"); - GPUTexture *tex_color = GPU_texture_create_2d("tex_render_mat_prev_hydra_color", - resolution_[0], - resolution_[1], - 1, - GPU_RGBA32F, - GPU_TEXTURE_USAGE_GENERAL, - nullptr); - GPUTexture *tex_depth = GPU_texture_create_2d("tex_render_mat_prev_hydra_depth", - resolution_[0], - resolution_[1], - 1, - GPU_DEPTH32F_STENCIL8, - GPU_TEXTURE_USAGE_GENERAL, - nullptr); - GPU_texture_filter_mode(tex_color, true); - GPU_texture_mipmap_mode(tex_color, true, true); - GPU_texture_filter_mode(tex_depth, true); - GPU_texture_mipmap_mode(tex_depth, true, true); - - GPU_framebuffer_ensure_config( - &framebuffer, {GPU_ATTACHMENT_TEXTURE(tex_depth), GPU_ATTACHMENT_TEXTURE(tex_color)}); - - GPU_framebuffer_bind(framebuffer); - - float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - - GPU_framebuffer_clear_color_depth(framebuffer, clear_color, 1.0f); - - /* Important: we have to create and bind at least one Vertex Array Object (VAO) before render - execution: More info at https://open.gl/drawing */ - GLuint VAO; - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - - engine_->Execute(render_index_.get(), &tasks_); - - std::vector &pixels = render_images_["Combined"]; - - while (true) { - if (RE_engine_test_break(bl_engine_)) { - break; - } - - if (render_task_delegate_->is_converged()) { - break; - } - - void *data = GPU_texture_read(tex_color, GPU_DATA_FLOAT, 0); - memcpy(pixels.data(), data, pixels.size() * sizeof(float)); - MEM_freeN(data); - update_render_result(); - } - - void *data = GPU_texture_read(tex_color, GPU_DATA_FLOAT, 0); - memcpy(pixels.data(), data, pixels.size() * sizeof(float)); - MEM_freeN(data); - update_render_result(); - - glDeleteVertexArrays(1, &VAO); - GPU_framebuffer_free(framebuffer); - GPU_texture_free(tex_color); - GPU_texture_free(tex_depth); -} - -void PreviewEngine::update_render_result(std::vector &pixels) -{ - RenderResult *result = RE_engine_begin_result( - bl_engine_, 0, 0, resolution_[0], resolution_[1], layer_name_.c_str(), nullptr); - - RenderLayer *layer = (RenderLayer *)result->layers.first; - RenderPass *pass = (RenderPass *)layer->passes.first; - memcpy(pass->ibuf->float_buffer.data, - pixels.data(), - sizeof(float) * pass->rectx * pass->recty * pass->channels); - - RE_engine_end_result(bl_engine_, result, false, false, false); + /* Empty fucntion */ } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index a3fa9e045603..a3e4609d2855 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -11,17 +11,16 @@ class PreviewEngine : public FinalEngine { public: using FinalEngine::FinalEngine; - void render(Depsgraph *depsgraph) override; - - private: - void update_render_result(std::vector &pixels); + protected: + void notify_status(float progress, const std::string &title, const std::string &info) override; }; class PreviewEngineGPU : public FinalEngineGPU { public: using FinalEngineGPU::FinalEngineGPU; - void render(Depsgraph *depsgraph) override; + protected: + void notify_status(float progress, const std::string &title, const std::string &info) override; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index d2d1e88ddcd4..138a455ba90e 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -88,9 +88,7 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) int h = task_params_.viewport[3] - task_params_.viewport[1]; render_index.InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, this, buf_id); buffer_descriptors_[buf_id] = pxr::HdRenderBufferDescriptor( - pxr::GfVec3i(w, h, 1), - aov_desc.format, - aov_desc.multiSampled); + pxr::GfVec3i(w, h, 1), aov_desc.format, aov_desc.multiSampled); pxr::HdRenderPassAovBinding binding; binding.aovName = aov_key; -- 2.30.2 From 084f04a95dfd0469c9f4dd810943c150b8db2644 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sun, 23 Jul 2023 16:48:20 +0300 Subject: [PATCH 4/7] Moving working with GPUTexture to RanderTaskDelegate --- source/blender/render/hydra/engine.cc | 14 +- source/blender/render/hydra/final_engine.cc | 111 ++-------------- source/blender/render/hydra/final_engine.h | 25 +--- source/blender/render/hydra/preview_engine.cc | 14 -- source/blender/render/hydra/preview_engine.h | 8 -- source/blender/render/hydra/python.cc | 14 +- .../render/hydra/render_task_delegate.cc | 124 ++++++++++++++++-- .../render/hydra/render_task_delegate.h | 35 ++++- .../blender/render/hydra/viewport_engine.cc | 4 +- 9 files changed, 168 insertions(+), 181 deletions(-) diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 7be85fb22430..dfe39edee02c 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -50,11 +50,21 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name) render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers)); free_camera_delegate_ = std::make_unique( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera")); - render_task_delegate_ = std::make_unique( - render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); + + if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { + render_task_delegate_ = std::make_unique( + render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); + } + else { + render_task_delegate_ = std::make_unique( + render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); + } + render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId()); + if (render_delegate_name == "HdStormRendererPlugin") { light_tasks_delegate_ = std::make_unique( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("lightTasks")); + light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId()); } engine_ = std::make_unique(); diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index d5566ffe3e92..6de6f847676a 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -43,17 +43,17 @@ void FinalEngine::render(Depsgraph *depsgraph) pxr::HdTaskSharedPtrVector tasks; free_camera_delegate_->SetCamera(camera); - render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId()); render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); if (light_tasks_delegate_) { - light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId()); light_tasks_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); tasks.push_back(light_tasks_delegate_->skydome_task()); tasks.push_back(light_tasks_delegate_->simple_task()); } tasks.push_back(render_task_delegate_->task()); - set_aovs(); + render_task_delegate_->add_aov(pxr::HdAovTokens->color); + render_task_delegate_->add_aov(pxr::HdAovTokens->depth); + render_task_delegate_->bind(); engine_->Execute(render_index_.get(), &tasks); @@ -82,8 +82,7 @@ void FinalEngine::render(Depsgraph *depsgraph) } update_render_result(); - - post_render(); + render_task_delegate_->unbind(); } void FinalEngine::notify_status(float progress, const std::string &title, const std::string &info) @@ -100,103 +99,17 @@ void FinalEngine::update_render_result() /* TODO: only for the first render layer */ RenderLayer *layer = (RenderLayer *)result->layers.first; for (RenderPass *pass = (RenderPass *)layer->passes.first; pass != nullptr; pass = pass->next) { - update_render_pass(pass); + pxr::TfToken aov_key; + if (STREQ(pass->name, "Combined")) { + aov_key = pxr::HdAovTokens->color; + } + else if (STREQ(pass->name, "Depth")) { + aov_key = pxr::HdAovTokens->depth; + } + render_task_delegate_->get_aov_data(aov_key, pass->ibuf->float_buffer.data); } RE_engine_end_result(bl_engine_, result, false, false, false); } -void FinalEngine::update_render_pass(RenderPass *pass) -{ - pxr::HdRenderBuffer *buf = nullptr; - if (STREQ(pass->name, "Combined")) { - buf = render_task_delegate_->get_aov(pxr::HdAovTokens->color); - } - else if (STREQ(pass->name, "Depth")) { - buf = render_task_delegate_->get_aov(pxr::HdAovTokens->depth); - } - if (!buf) { - return; - } - void *data = buf->Map(); - memcpy(pass->ibuf->float_buffer.data, - data, - sizeof(float) * pass->rectx * pass->recty * pass->channels); - buf->Unmap(); -} - -void FinalEngine::set_aovs() -{ - render_task_delegate_->add_aov(pxr::HdAovTokens->color); -} - -void FinalEngine::post_render() {} - -/* FinalEngineGPU implementation */ - -void FinalEngineGPU::update_render_pass(RenderPass *pass) -{ - GPUTexture *tex = nullptr; - if (STREQ(pass->name, "Combined")) { - tex = tex_color_; - } - else if (STREQ(pass->name, "Depth")) { - tex = tex_depth_; - } - if (!tex) { - return; - } - void *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 0); - memcpy(pass->ibuf->float_buffer.data, - data, - sizeof(float) * pass->rectx * pass->recty * pass->channels); - MEM_freeN(data); -} - -void FinalEngineGPU::set_aovs() -{ - framebuffer_ = GPU_framebuffer_create("fb_render_hydra"); - tex_color_ = GPU_texture_create_2d("tex_render_hydra_color", - resolution_[0], - resolution_[1], - 1, - GPU_RGBA32F, - GPU_TEXTURE_USAGE_GENERAL, - nullptr); - tex_depth_ = GPU_texture_create_2d("tex_render_hydra_depth", - resolution_[0], - resolution_[1], - 1, - GPU_DEPTH32F_STENCIL8, - GPU_TEXTURE_USAGE_GENERAL, - nullptr); - GPU_texture_filter_mode(tex_color_, true); - GPU_texture_mipmap_mode(tex_color_, true, true); - GPU_texture_filter_mode(tex_depth_, true); - GPU_texture_mipmap_mode(tex_depth_, true, true); - - GPU_framebuffer_ensure_config( - &framebuffer_, {GPU_ATTACHMENT_TEXTURE(tex_depth_), GPU_ATTACHMENT_TEXTURE(tex_color_)}); - - GPU_framebuffer_bind(framebuffer_); - - float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - - GPU_framebuffer_clear_color_depth(framebuffer_, clear_color, 1.0f); - - /* Important: we have to create and bind at least one Vertex Array Object (VAO) before render - execution: More info at https://open.gl/drawing */ - GLuint VAO_; - glGenVertexArrays(1, &VAO_); - glBindVertexArray(VAO_); -} - -void FinalEngineGPU::post_render() -{ - glDeleteVertexArrays(1, &VAO_); - GPU_framebuffer_free(framebuffer_); - GPU_texture_free(tex_color_); - GPU_texture_free(tex_depth_); -} - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/final_engine.h b/source/blender/render/hydra/final_engine.h index eee0f7eff0a9..81155629a010 100644 --- a/source/blender/render/hydra/final_engine.h +++ b/source/blender/render/hydra/final_engine.h @@ -3,11 +3,6 @@ #pragma once -#include - -#include "GPU_framebuffer.h" -#include "GPU_texture.h" - #include "engine.h" namespace blender::render::hydra { @@ -20,29 +15,11 @@ class FinalEngine : public Engine { protected: virtual void notify_status(float progress, const std::string &title, const std::string &info); - virtual void update_render_result(); - virtual void update_render_pass(RenderPass *pass); - virtual void set_aovs(); - virtual void post_render(); + void update_render_result(); std::string scene_name_; std::string layer_name_; pxr::GfVec2i resolution_; }; -class FinalEngineGPU : public FinalEngine { - public: - using FinalEngine::FinalEngine; - - protected: - void update_render_pass(RenderPass *pass) override; - void set_aovs() override; - void post_render() override; - - GPUFrameBuffer *framebuffer_; - GPUTexture *tex_color_; - GPUTexture *tex_depth_; - GLuint VAO_; -}; - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index fb812807c97f..c0086fe2e0b0 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -1,13 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#include - -#include "GPU_framebuffer.h" -#include "GPU_texture.h" - -#include "IMB_imbuf_types.h" - #include "preview_engine.h" namespace blender::render::hydra { @@ -19,11 +12,4 @@ void PreviewEngine::notify_status(float progress, /* Empty fucntion */ } -void PreviewEngineGPU::notify_status(float progress, - const std::string &title, - const std::string &info) -{ - /* Empty fucntion */ -} - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index a3e4609d2855..07c3947c3eca 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -15,12 +15,4 @@ class PreviewEngine : public FinalEngine { void notify_status(float progress, const std::string &title, const std::string &info) override; }; -class PreviewEngineGPU : public FinalEngineGPU { - public: - using FinalEngineGPU::FinalEngineGPU; - - protected: - void notify_status(float progress, const std::string &title, const std::string &info) override; -}; - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index da8b5b96dce4..cc4ab4bbe00d 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -71,20 +71,10 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) engine = new ViewportEngine(bl_engine, render_delegate_id); } else if (STREQ(engine_type, "PREVIEW")) { - if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { - engine = new PreviewEngineGPU(bl_engine, render_delegate_id); - } - else { - engine = new PreviewEngine(bl_engine, render_delegate_id); - } + engine = new PreviewEngine(bl_engine, render_delegate_id); } else { - if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { - engine = new FinalEngineGPU(bl_engine, render_delegate_id); - } - else { - engine = new FinalEngine(bl_engine, render_delegate_id); - } + engine = new FinalEngine(bl_engine, render_delegate_id); } } catch (std::runtime_error &e) { diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 138a455ba90e..e83ef1963f65 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -1,10 +1,14 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ +#include + #include #include #include +#include "MEM_guardedalloc.h" + #include "render_task_delegate.h" namespace blender::render::hydra { @@ -56,6 +60,11 @@ void RenderTaskDelegate::set_camera(pxr::SdfPath const &camera_id) GetRenderIndex().GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); } +bool RenderTaskDelegate::is_converged() +{ + return ((pxr::HdxRenderTask *)task().get())->IsConverged(); +} + void RenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) { if (task_params_.viewport == viewport) { @@ -98,15 +107,13 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); } -pxr::HdRenderBuffer *RenderTaskDelegate::get_aov(pxr::TfToken const &aov_key) +void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov_key, void *data) { - return (pxr::HdRenderBuffer *)GetRenderIndex().GetBprim(pxr::HdPrimTypeTokens->renderBuffer, - buffer_id(aov_key)); -} - -void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov, void *data) -{ - pxr::HdRenderBuffer *buffer = get_aov(aov); + pxr::HdRenderBuffer *buffer = (pxr::HdRenderBuffer *)GetRenderIndex().GetBprim( + pxr::HdPrimTypeTokens->renderBuffer, buffer_id(aov_key)); + if (!buffer) { + return; + } void *buf_data = buffer->Map(); memcpy(data, buf_data, @@ -114,14 +121,107 @@ void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov, void *data) buffer->Unmap(); } -bool RenderTaskDelegate::is_converged() +void RenderTaskDelegate::bind() {} + +void RenderTaskDelegate::unbind() {} + +pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov_key) const { - return ((pxr::HdxRenderTask *)task().get())->IsConverged(); + return GetDelegateID().AppendElementString("aov_" + aov_key.GetString()); } -pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov) const +void GPURenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) { - return GetDelegateID().AppendElementString("aov_" + aov.GetString()); + if (task_params_.viewport == viewport) { + return; + } + auto &render_index = GetRenderIndex(); + task_params_.viewport = viewport; + render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); + + if (tex_color_) { + GPU_texture_free(tex_color_); + add_aov(pxr::HdAovTokens->color); + } + if (tex_depth_) { + GPU_texture_free(tex_depth_); + add_aov(pxr::HdAovTokens->depth); + } +} + +void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) +{ + eGPUTextureFormat format; + GPUTexture **tex; + if (aov_key == pxr::HdAovTokens->color) { + format = GPU_RGBA32F; + tex = &tex_color_; + } + else if (aov_key == pxr::HdAovTokens->depth) { + format = GPU_DEPTH32F_STENCIL8; + tex = &tex_depth_; + } + else { + return; + } + + *tex = GPU_texture_create_2d(("tex_render_hydra_" + aov_key.GetString()).c_str(), + task_params_.viewport[2] - task_params_.viewport[0], + task_params_.viewport[3] - task_params_.viewport[1], + 1, + format, + GPU_TEXTURE_USAGE_GENERAL, + nullptr); +} + +void GPURenderTaskDelegate::get_aov_data(pxr::TfToken const &aov_key, void *data) +{ + GPUTexture *tex = nullptr; + int c; + if (aov_key == pxr::HdAovTokens->color) { + tex = tex_color_; + c = 4; + } + else if (aov_key == pxr::HdAovTokens->depth) { + tex = tex_depth_; + c = 1; + } + if (!tex) { + return; + } + + int w = GPU_texture_width(tex), h = GPU_texture_height(tex); + void *tex_data = GPU_texture_read(tex, GPU_DATA_FLOAT, 0); + memcpy(data, tex_data, sizeof(float) * w * h * c); + MEM_freeN(tex_data); +} + +void GPURenderTaskDelegate::bind() +{ + if (!framebuffer_) { + framebuffer_ = GPU_framebuffer_create("fb_render_hydra"); + } + GPU_framebuffer_ensure_config( + &framebuffer_, {GPU_ATTACHMENT_TEXTURE(tex_depth_), GPU_ATTACHMENT_TEXTURE(tex_color_)}); + GPU_framebuffer_bind(framebuffer_); + + float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + GPU_framebuffer_clear_color_depth(framebuffer_, clear_color, 1.0f); + + /* Important: we have to create and bind at least one Vertex Array Object (VAO) before render + execution: More info at https://open.gl/drawing */ + if (VAO_ == 0) { + glGenVertexArrays(1, &VAO_); + } + glBindVertexArray(VAO_); +} + +void GPURenderTaskDelegate::unbind() +{ + glDeleteVertexArrays(1, &VAO_); + GPU_framebuffer_free(framebuffer_); + GPU_texture_free(tex_color_); + GPU_texture_free(tex_depth_); } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index 758ee4c9d5ff..f0395423f092 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -6,6 +6,9 @@ #include #include +#include "GPU_framebuffer.h" +#include "GPU_texture.h" + namespace blender::render::hydra { class RenderTaskDelegate : public pxr::HdSceneDelegate { @@ -19,15 +22,16 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate { pxr::HdRenderBufferDescriptor GetRenderBufferDescriptor(pxr::SdfPath const &id) override; pxr::HdTaskSharedPtr task(); - void set_camera(pxr::SdfPath const &camera_id); - void set_viewport(pxr::GfVec4d const &viewport); - void add_aov(pxr::TfToken const &aov_key); - pxr::HdRenderBuffer *get_aov(pxr::TfToken const &aov_key); - void get_aov_data(pxr::TfToken const &aov_key, void *data); bool is_converged(); + void set_camera(pxr::SdfPath const &camera_id); + virtual void set_viewport(pxr::GfVec4d const &viewport); + virtual void add_aov(pxr::TfToken const &aov_key); + virtual void get_aov_data(pxr::TfToken const &aov_key, void *data); + virtual void bind(); + virtual void unbind(); - private: - pxr::SdfPath buffer_id(pxr::TfToken const &aov) const; + protected: + pxr::SdfPath buffer_id(pxr::TfToken const &aov_key) const; pxr::SdfPath task_id_; pxr::HdxRenderTaskParams task_params_; @@ -35,4 +39,21 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate { buffer_descriptors_; }; +class GPURenderTaskDelegate : public RenderTaskDelegate { + public: + using RenderTaskDelegate::RenderTaskDelegate; + + void set_viewport(pxr::GfVec4d const &viewport) override; + void add_aov(pxr::TfToken const &aov_key) override; + void get_aov_data(pxr::TfToken const &aov_key, void *data) override; + void bind() override; + void unbind() override; + + private: + GPUFrameBuffer *framebuffer_ = nullptr; + GPUTexture *tex_color_ = nullptr; + GPUTexture *tex_depth_ = nullptr; + unsigned int VAO_ = 0; +}; + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 075010424184..b0ab6e98994f 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -231,14 +231,12 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) pxr::GfCamera gf_camera = view_settings.gf_camera(); free_camera_delegate_->SetCamera(gf_camera); - render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId()); render_task_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0], view_settings.border[1], view_settings.border[2], view_settings.border[3])); if (light_tasks_delegate_) { - light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId()); light_tasks_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0], view_settings.border[1], view_settings.border[2], @@ -262,7 +260,7 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) engine_->Execute(render_index_.get(), &tasks); if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - draw_texture_.set_buffer(render_task_delegate_->get_aov(pxr::HdAovTokens->color)); + //draw_texture_.set_buffer(render_task_delegate_->get_aov(pxr::HdAovTokens->color)); draw_texture_.draw(shader, view_settings.border[0], view_settings.border[1]); } -- 2.30.2 From bf1e52b2e48cce51af5623475bc14efd5040ab2a Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sun, 23 Jul 2023 18:47:35 +0300 Subject: [PATCH 5/7] Improved working with DrawTexture. Fixes in GPURenderTaskDelegate. Improved ViewportEngine::render --- source/blender/render/hydra/final_engine.cc | 17 ++-- .../render/hydra/render_task_delegate.cc | 12 ++- .../render/hydra/render_task_delegate.h | 4 +- .../blender/render/hydra/viewport_engine.cc | 96 +++++++------------ source/blender/render/hydra/viewport_engine.h | 11 +-- 5 files changed, 62 insertions(+), 78 deletions(-) diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 6de6f847676a..09cd14dba39a 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -41,20 +41,23 @@ void FinalEngine::render(Depsgraph *depsgraph) pxr::GfCamera camera = CameraData(scene->camera, image_res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(border); - pxr::HdTaskSharedPtrVector tasks; free_camera_delegate_->SetCamera(camera); render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); if (light_tasks_delegate_) { light_tasks_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1])); + } + + render_task_delegate_->add_aov(pxr::HdAovTokens->color); + render_task_delegate_->add_aov(pxr::HdAovTokens->depth); + + render_task_delegate_->bind(); + + pxr::HdTaskSharedPtrVector tasks; + if (light_tasks_delegate_) { tasks.push_back(light_tasks_delegate_->skydome_task()); tasks.push_back(light_tasks_delegate_->simple_task()); } tasks.push_back(render_task_delegate_->task()); - - render_task_delegate_->add_aov(pxr::HdAovTokens->color); - render_task_delegate_->add_aov(pxr::HdAovTokens->depth); - render_task_delegate_->bind(); - engine_->Execute(render_index_.get(), &tasks); char elapsed_time[32]; @@ -106,7 +109,7 @@ void FinalEngine::update_render_result() else if (STREQ(pass->name, "Depth")) { aov_key = pxr::HdAovTokens->depth; } - render_task_delegate_->get_aov_data(aov_key, pass->ibuf->float_buffer.data); + render_task_delegate_->read_aov(aov_key, pass->ibuf->float_buffer.data); } RE_engine_end_result(bl_engine_, result, false, false, false); diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index e83ef1963f65..932c28e1b20a 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -107,7 +107,7 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); } -void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov_key, void *data) +void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) { pxr::HdRenderBuffer *buffer = (pxr::HdRenderBuffer *)GetRenderIndex().GetBprim( pxr::HdPrimTypeTokens->renderBuffer, buffer_id(aov_key)); @@ -141,10 +141,12 @@ void GPURenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) if (tex_color_) { GPU_texture_free(tex_color_); + tex_color_ = nullptr; add_aov(pxr::HdAovTokens->color); } if (tex_depth_) { GPU_texture_free(tex_depth_); + tex_depth_ = nullptr; add_aov(pxr::HdAovTokens->depth); } } @@ -165,6 +167,10 @@ void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) return; } + if (*tex) { + return; + } + *tex = GPU_texture_create_2d(("tex_render_hydra_" + aov_key.GetString()).c_str(), task_params_.viewport[2] - task_params_.viewport[0], task_params_.viewport[3] - task_params_.viewport[1], @@ -174,7 +180,7 @@ void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) nullptr); } -void GPURenderTaskDelegate::get_aov_data(pxr::TfToken const &aov_key, void *data) +void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) { GPUTexture *tex = nullptr; int c; @@ -218,7 +224,7 @@ void GPURenderTaskDelegate::bind() void GPURenderTaskDelegate::unbind() { - glDeleteVertexArrays(1, &VAO_); + //glDeleteVertexArrays(1, &VAO_); GPU_framebuffer_free(framebuffer_); GPU_texture_free(tex_color_); GPU_texture_free(tex_depth_); diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index f0395423f092..9f9a9cd0cfca 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -26,7 +26,7 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate { void set_camera(pxr::SdfPath const &camera_id); virtual void set_viewport(pxr::GfVec4d const &viewport); virtual void add_aov(pxr::TfToken const &aov_key); - virtual void get_aov_data(pxr::TfToken const &aov_key, void *data); + virtual void read_aov(pxr::TfToken const &aov_key, void *data); virtual void bind(); virtual void unbind(); @@ -45,7 +45,7 @@ class GPURenderTaskDelegate : public RenderTaskDelegate { void set_viewport(pxr::GfVec4d const &viewport) override; void add_aov(pxr::TfToken const &aov_key) override; - void get_aov_data(pxr::TfToken const &aov_key, void *data) override; + void read_aov(pxr::TfToken const &aov_key, void *data) override; void bind() override; void unbind() override; diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index b0ab6e98994f..008e882ddfd7 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -5,19 +5,15 @@ #include #include -#include "DNA_camera_types.h" -#include "DNA_screen_types.h" #include "DNA_vec_types.h" /* this include must be before BKE_camera.h due to "rctf" type */ +#include "DNA_camera_types.h" +#include "DNA_screen_types.h" #include "BKE_camera.h" - #include "BLI_math_matrix.h" #include "BLI_timecode.h" - #include "DEG_depsgraph_query.h" - #include "GPU_matrix.h" - #include "PIL_time.h" #include "camera.h" @@ -136,7 +132,7 @@ pxr::GfCamera ViewSettings::gf_camera() (float)border[3] / screen_height)); } -DrawTexture::DrawTexture() : texture_(nullptr), width_(0), height_(0), channels_(4) +DrawTexture::DrawTexture() { float coords[8] = {0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0}; @@ -154,67 +150,50 @@ DrawTexture::DrawTexture() : texture_(nullptr), width_(0), height_(0), channels_ DrawTexture::~DrawTexture() { if (texture_) { - free(); + GPU_texture_free(texture_); } GPU_batch_discard(batch_); } -void DrawTexture::set_buffer(pxr::HdRenderBuffer *buffer) +void DrawTexture::write_data(int width, int height, const void *data) { - if (!texture_) { - create(buffer); + if (texture_ && width == GPU_texture_width(texture_) && height == GPU_texture_height(texture_)) { + GPU_texture_update(texture_, GPU_DATA_FLOAT, data); return; } - if (width_ != buffer->GetWidth() || height_ != buffer->GetHeight()) { - free(); - create(buffer); - return; + if (texture_ ) { + GPU_texture_free(texture_); } - void *data = buffer->Map(); - GPU_texture_update(texture_, GPU_DATA_FLOAT, data); - buffer->Unmap(); -} - -void DrawTexture::draw(GPUShader *shader, float x, float y) -{ - int slot = GPU_shader_get_sampler_binding(shader, "image"); - GPU_texture_bind(texture_, slot); - GPU_shader_uniform_1i(shader, "image", slot); - - GPU_matrix_push(); - GPU_matrix_translate_2f(x, y); - GPU_matrix_scale_2f(width_, height_); - GPU_batch_set_shader(batch_, shader); - GPU_batch_draw(batch_); - GPU_matrix_pop(); -} - -void DrawTexture::create(pxr::HdRenderBuffer *buffer) -{ - width_ = buffer->GetWidth(); - height_ = buffer->GetHeight(); - channels_ = pxr::HdGetComponentCount(buffer->GetFormat()); - - void *data = buffer->Map(); texture_ = GPU_texture_create_2d("tex_hydra_render_viewport", - width_, - height_, + width, + height, 1, GPU_RGBA16F, GPU_TEXTURE_USAGE_GENERAL, (float *)data); - buffer->Unmap(); - GPU_texture_filter_mode(texture_, true); GPU_texture_mipmap_mode(texture_, true, true); } -void DrawTexture::free() +void DrawTexture::draw(GPUShader *shader, const pxr::GfVec4d &viewport) { - GPU_texture_free(texture_); - texture_ = nullptr; + draw(shader, texture_, viewport); +} + +void DrawTexture::draw(GPUShader *shader, GPUTexture *tex, const pxr::GfVec4d &viewport) +{ + int slot = GPU_shader_get_sampler_binding(shader, "image"); + GPU_texture_bind(tex, slot); + GPU_shader_uniform_1i(shader, "image", slot); + + GPU_matrix_push(); + GPU_matrix_translate_2f(viewport[0], viewport[1]); + GPU_matrix_scale_2f(viewport[2] - viewport[0], viewport[3] - viewport[1]); + GPU_batch_set_shader(batch_, shader); + GPU_batch_draw(batch_); + GPU_matrix_pop(); } void ViewportEngine::render(Depsgraph * /* depsgraph */) @@ -231,16 +210,14 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) pxr::GfCamera gf_camera = view_settings.gf_camera(); free_camera_delegate_->SetCamera(gf_camera); - render_task_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0], - view_settings.border[1], - view_settings.border[2], - view_settings.border[3])); + pxr::GfVec4d viewport(view_settings.border[0], + view_settings.border[1], + view_settings.border[2], + view_settings.border[3]); + render_task_delegate_->set_viewport(viewport); if (light_tasks_delegate_) { - light_tasks_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0], - view_settings.border[1], - view_settings.border[2], - view_settings.border[3])); + light_tasks_delegate_->set_viewport(viewport); } if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { @@ -256,12 +233,13 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) tasks.push_back(light_tasks_delegate_->simple_task()); } tasks.push_back(render_task_delegate_->task()); - engine_->Execute(render_index_.get(), &tasks); if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - //draw_texture_.set_buffer(render_task_delegate_->get_aov(pxr::HdAovTokens->color)); - draw_texture_.draw(shader, view_settings.border[0], view_settings.border[1]); + std::vector data(view_settings.width() * view_settings.height() * 4, 0.0f); + render_task_delegate_->read_aov(pxr::HdAovTokens->color, data.data()); + draw_texture_.write_data(view_settings.width(), view_settings.height(), data.data()); + draw_texture_.draw(shader, viewport); } GPU_shader_unbind(); diff --git a/source/blender/render/hydra/viewport_engine.h b/source/blender/render/hydra/viewport_engine.h index a21ccda581e8..57596f2c5888 100644 --- a/source/blender/render/hydra/viewport_engine.h +++ b/source/blender/render/hydra/viewport_engine.h @@ -18,16 +18,13 @@ class DrawTexture { DrawTexture(); ~DrawTexture(); - void set_buffer(pxr::HdRenderBuffer *buffer); - void draw(GPUShader *shader, float x, float y); + void write_data(int width, int height, const void *data); + void draw(GPUShader *shader, const pxr::GfVec4d &viewport); + void draw(GPUShader *shader, GPUTexture *tex, const pxr::GfVec4d &viewport); private: - void create(pxr::HdRenderBuffer *buffer); - void free(); - - GPUTexture *texture_; + GPUTexture *texture_ = nullptr; GPUBatch *batch_; - int width_, height_, channels_; }; class ViewportEngine : public Engine { -- 2.30.2 From 5944ea8a38b8a7afb0294752522b013abb150c1b Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sun, 23 Jul 2023 21:36:01 +0300 Subject: [PATCH 6/7] Optimized writing aov data to GPU texture --- .../render/hydra/render_task_delegate.cc | 33 +++++++++++++++++++ .../render/hydra/render_task_delegate.h | 2 ++ .../blender/render/hydra/viewport_engine.cc | 14 +++++--- source/blender/render/hydra/viewport_engine.h | 1 + 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 932c28e1b20a..11160db64119 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -121,6 +121,18 @@ void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) buffer->Unmap(); } +void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) +{ + pxr::HdRenderBuffer *buffer = (pxr::HdRenderBuffer *)GetRenderIndex().GetBprim( + pxr::HdPrimTypeTokens->renderBuffer, buffer_id(aov_key)); + if (!buffer) { + return; + } + void *buf_data = buffer->Map(); + GPU_texture_update(texture, GPU_DATA_FLOAT, buf_data); + buffer->Unmap(); +} + void RenderTaskDelegate::bind() {} void RenderTaskDelegate::unbind() {} @@ -202,6 +214,27 @@ void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data) MEM_freeN(tex_data); } +void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) +{ + GPUTexture *tex = nullptr; + int c; + if (aov_key == pxr::HdAovTokens->color) { + tex = tex_color_; + c = 4; + } + else if (aov_key == pxr::HdAovTokens->depth) { + tex = tex_depth_; + c = 1; + } + if (!tex) { + return; + } + + void *tex_data = GPU_texture_read(tex, GPU_DATA_FLOAT, 0); + GPU_texture_update(texture, GPU_DATA_FLOAT, tex_data); + MEM_freeN(tex_data); +} + void GPURenderTaskDelegate::bind() { if (!framebuffer_) { diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index 9f9a9cd0cfca..548fec3a02c5 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -27,6 +27,7 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate { virtual void set_viewport(pxr::GfVec4d const &viewport); virtual void add_aov(pxr::TfToken const &aov_key); virtual void read_aov(pxr::TfToken const &aov_key, void *data); + virtual void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture); virtual void bind(); virtual void unbind(); @@ -46,6 +47,7 @@ class GPURenderTaskDelegate : public RenderTaskDelegate { void set_viewport(pxr::GfVec4d const &viewport) override; void add_aov(pxr::TfToken const &aov_key) override; void read_aov(pxr::TfToken const &aov_key, void *data) override; + void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) override; void bind() override; void unbind() override; diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 008e882ddfd7..861d2cb16f53 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -158,7 +158,9 @@ DrawTexture::~DrawTexture() void DrawTexture::write_data(int width, int height, const void *data) { if (texture_ && width == GPU_texture_width(texture_) && height == GPU_texture_height(texture_)) { - GPU_texture_update(texture_, GPU_DATA_FLOAT, data); + if (data) { + GPU_texture_update(texture_, GPU_DATA_FLOAT, data); + } return; } @@ -196,6 +198,11 @@ void DrawTexture::draw(GPUShader *shader, GPUTexture *tex, const pxr::GfVec4d &v GPU_matrix_pop(); } +GPUTexture *DrawTexture::texture() const +{ + return texture_; +} + void ViewportEngine::render(Depsgraph * /* depsgraph */) { /* Empty function */ @@ -236,9 +243,8 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context) engine_->Execute(render_index_.get(), &tasks); if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - std::vector data(view_settings.width() * view_settings.height() * 4, 0.0f); - render_task_delegate_->read_aov(pxr::HdAovTokens->color, data.data()); - draw_texture_.write_data(view_settings.width(), view_settings.height(), data.data()); + draw_texture_.write_data(view_settings.width(), view_settings.height(), nullptr); + render_task_delegate_->read_aov(pxr::HdAovTokens->color, draw_texture_.texture()); draw_texture_.draw(shader, viewport); } diff --git a/source/blender/render/hydra/viewport_engine.h b/source/blender/render/hydra/viewport_engine.h index 57596f2c5888..b9ec215ea068 100644 --- a/source/blender/render/hydra/viewport_engine.h +++ b/source/blender/render/hydra/viewport_engine.h @@ -21,6 +21,7 @@ class DrawTexture { void write_data(int width, int height, const void *data); void draw(GPUShader *shader, const pxr::GfVec4d &viewport); void draw(GPUShader *shader, GPUTexture *tex, const pxr::GfVec4d &viewport); + GPUTexture *texture() const; private: GPUTexture *texture_ = nullptr; -- 2.30.2 From 9e5242f9a71038d952c54cbb60c9c5c230bfa458 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sun, 23 Jul 2023 22:31:51 +0300 Subject: [PATCH 7/7] make format + fix --- source/blender/render/hydra/render_task_delegate.cc | 2 +- source/blender/render/hydra/viewport_engine.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index fba4aec75ae7..278f6e99a203 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -257,7 +257,7 @@ void GPURenderTaskDelegate::bind() void GPURenderTaskDelegate::unbind() { - //glDeleteVertexArrays(1, &VAO_); + glDeleteVertexArrays(1, &VAO_); GPU_framebuffer_free(framebuffer_); GPU_texture_free(tex_color_); GPU_texture_free(tex_depth_); diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 92d75fc40e35..229ec9fff309 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -7,12 +7,12 @@ #include "DNA_vec_types.h" /* this include must be before BKE_camera.h due to "rctf" type */ -#include "DNA_camera_types.h" -#include "DNA_screen_types.h" #include "BKE_camera.h" #include "BLI_math_matrix.h" #include "BLI_timecode.h" #include "DEG_depsgraph_query.h" +#include "DNA_camera_types.h" +#include "DNA_screen_types.h" #include "GPU_matrix.h" #include "PIL_time.h" @@ -164,7 +164,7 @@ void DrawTexture::write_data(int width, int height, const void *data) return; } - if (texture_ ) { + if (texture_) { GPU_texture_free(texture_); } -- 2.30.2