Hydra tasks refactor #73

Merged
Bogdan Nagirniak merged 8 commits from hydra-tasks-refactor into hydra-render 2023-07-25 22:13:33 +02:00
9 changed files with 168 additions and 181 deletions
Showing only changes of commit 084f04a95d - Show all commits

View File

@ -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)); render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers));
free_camera_delegate_ = std::make_unique<pxr::HdxFreeCameraSceneDelegate>( free_camera_delegate_ = std::make_unique<pxr::HdxFreeCameraSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera")); render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera"));
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
render_task_delegate_ = std::make_unique<GPURenderTaskDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
}
else {
render_task_delegate_ = std::make_unique<RenderTaskDelegate>( render_task_delegate_ = std::make_unique<RenderTaskDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
}
render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId());
if (render_delegate_name == "HdStormRendererPlugin") { if (render_delegate_name == "HdStormRendererPlugin") {
light_tasks_delegate_ = std::make_unique<LightTasksDelegate>( light_tasks_delegate_ = std::make_unique<LightTasksDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("lightTasks")); render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("lightTasks"));
light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId());
} }
engine_ = std::make_unique<pxr::HdEngine>(); engine_ = std::make_unique<pxr::HdEngine>();

View File

@ -43,17 +43,17 @@ void FinalEngine::render(Depsgraph *depsgraph)
pxr::HdTaskSharedPtrVector tasks; pxr::HdTaskSharedPtrVector tasks;
free_camera_delegate_->SetCamera(camera); 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])); render_task_delegate_->set_viewport(pxr::GfVec4d(0, 0, resolution_[0], resolution_[1]));
if (light_tasks_delegate_) { 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])); 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_->skydome_task());
tasks.push_back(light_tasks_delegate_->simple_task()); tasks.push_back(light_tasks_delegate_->simple_task());
} }
tasks.push_back(render_task_delegate_->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); engine_->Execute(render_index_.get(), &tasks);
@ -82,8 +82,7 @@ void FinalEngine::render(Depsgraph *depsgraph)
} }
update_render_result(); update_render_result();
render_task_delegate_->unbind();
post_render();
} }
void FinalEngine::notify_status(float progress, const std::string &title, const std::string &info) 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 */ /* TODO: only for the first render layer */
RenderLayer *layer = (RenderLayer *)result->layers.first; RenderLayer *layer = (RenderLayer *)result->layers.first;
for (RenderPass *pass = (RenderPass *)layer->passes.first; pass != nullptr; pass = pass->next) { 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); 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 } // namespace blender::render::hydra

View File

@ -3,11 +3,6 @@
#pragma once #pragma once
#include <epoxy/gl.h>
#include "GPU_framebuffer.h"
#include "GPU_texture.h"
#include "engine.h" #include "engine.h"
namespace blender::render::hydra { namespace blender::render::hydra {
@ -20,29 +15,11 @@ class FinalEngine : public Engine {
protected: protected:
virtual void notify_status(float progress, const std::string &title, const std::string &info); virtual void notify_status(float progress, const std::string &title, const std::string &info);
virtual void update_render_result(); void update_render_result();
virtual void update_render_pass(RenderPass *pass);
virtual void set_aovs();
virtual void post_render();
std::string scene_name_; std::string scene_name_;
std::string layer_name_; std::string layer_name_;
pxr::GfVec2i resolution_; 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 } // namespace blender::render::hydra

View File

@ -1,13 +1,6 @@
/* SPDX-License-Identifier: Apache-2.0 /* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */ * Copyright 2011-2022 Blender Foundation */
#include <epoxy/gl.h>
#include "GPU_framebuffer.h"
#include "GPU_texture.h"
#include "IMB_imbuf_types.h"
#include "preview_engine.h" #include "preview_engine.h"
namespace blender::render::hydra { namespace blender::render::hydra {
@ -19,11 +12,4 @@ void PreviewEngine::notify_status(float progress,
/* Empty fucntion */ /* Empty fucntion */
} }
void PreviewEngineGPU::notify_status(float progress,
const std::string &title,
const std::string &info)
{
/* Empty fucntion */
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -15,12 +15,4 @@ class PreviewEngine : public FinalEngine {
void notify_status(float progress, const std::string &title, const std::string &info) override; 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 } // namespace blender::render::hydra

View File

@ -71,22 +71,12 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
engine = new ViewportEngine(bl_engine, render_delegate_id); engine = new ViewportEngine(bl_engine, render_delegate_id);
} }
else if (STREQ(engine_type, "PREVIEW")) { 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 { else {
engine = new FinalEngine(bl_engine, render_delegate_id); engine = new FinalEngine(bl_engine, render_delegate_id);
} }
} }
}
catch (std::runtime_error &e) { catch (std::runtime_error &e) {
CLOG_ERROR(LOG_RENDER_HYDRA, "%s", e.what()); CLOG_ERROR(LOG_RENDER_HYDRA, "%s", e.what());
} }

View File

@ -1,10 +1,14 @@
/* SPDX-License-Identifier: Apache-2.0 /* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */ * Copyright 2011-2022 Blender Foundation */
#include <epoxy/gl.h>
#include <pxr/imaging/hd/renderBuffer.h> #include <pxr/imaging/hd/renderBuffer.h>
#include <pxr/imaging/hd/renderDelegate.h> #include <pxr/imaging/hd/renderDelegate.h>
#include <pxr/imaging/hdx/renderTask.h> #include <pxr/imaging/hdx/renderTask.h>
#include "MEM_guardedalloc.h"
#include "render_task_delegate.h" #include "render_task_delegate.h"
namespace blender::render::hydra { 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); 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) void RenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport)
{ {
if (task_params_.viewport == 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); 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, pxr::HdRenderBuffer *buffer = (pxr::HdRenderBuffer *)GetRenderIndex().GetBprim(
buffer_id(aov_key)); pxr::HdPrimTypeTokens->renderBuffer, buffer_id(aov_key));
} if (!buffer) {
return;
void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov, void *data) }
{
pxr::HdRenderBuffer *buffer = get_aov(aov);
void *buf_data = buffer->Map(); void *buf_data = buffer->Map();
memcpy(data, memcpy(data,
buf_data, buf_data,
@ -114,14 +121,107 @@ void RenderTaskDelegate::get_aov_data(pxr::TfToken const &aov, void *data)
buffer->Unmap(); 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 } // namespace blender::render::hydra

View File

@ -6,6 +6,9 @@
#include <pxr/imaging/hd/sceneDelegate.h> #include <pxr/imaging/hd/sceneDelegate.h>
#include <pxr/imaging/hdx/renderSetupTask.h> #include <pxr/imaging/hdx/renderSetupTask.h>
#include "GPU_framebuffer.h"
#include "GPU_texture.h"
namespace blender::render::hydra { namespace blender::render::hydra {
class RenderTaskDelegate : public pxr::HdSceneDelegate { class RenderTaskDelegate : public pxr::HdSceneDelegate {
@ -19,15 +22,16 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate {
pxr::HdRenderBufferDescriptor GetRenderBufferDescriptor(pxr::SdfPath const &id) override; pxr::HdRenderBufferDescriptor GetRenderBufferDescriptor(pxr::SdfPath const &id) override;
pxr::HdTaskSharedPtr task(); 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(); 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: protected:
pxr::SdfPath buffer_id(pxr::TfToken const &aov) const; pxr::SdfPath buffer_id(pxr::TfToken const &aov_key) const;
pxr::SdfPath task_id_; pxr::SdfPath task_id_;
pxr::HdxRenderTaskParams task_params_; pxr::HdxRenderTaskParams task_params_;
@ -35,4 +39,21 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate {
buffer_descriptors_; 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 } // namespace blender::render::hydra

View File

@ -231,14 +231,12 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context)
pxr::GfCamera gf_camera = view_settings.gf_camera(); pxr::GfCamera gf_camera = view_settings.gf_camera();
free_camera_delegate_->SetCamera(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], render_task_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0],
view_settings.border[1], view_settings.border[1],
view_settings.border[2], view_settings.border[2],
view_settings.border[3])); view_settings.border[3]));
if (light_tasks_delegate_) { if (light_tasks_delegate_) {
light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId());
light_tasks_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0], light_tasks_delegate_->set_viewport(pxr::GfVec4d(view_settings.border[0],
view_settings.border[1], view_settings.border[1],
view_settings.border[2], view_settings.border[2],
@ -262,7 +260,7 @@ void ViewportEngine::render(Depsgraph * /* depsgraph */, bContext *context)
engine_->Execute(render_index_.get(), &tasks); engine_->Execute(render_index_.get(), &tasks);
if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { 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]); draw_texture_.draw(shader, view_settings.border[0], view_settings.border[1]);
} }