forked from blender/blender
Hydra tasks refactor #73
@ -1,15 +1,12 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#include <pxr/imaging/hd/light.h>
|
||||
#include <pxr/imaging/hd/renderBuffer.h>
|
||||
|
||||
#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<float> &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<float>(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<float> &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
|
||||
|
@ -3,6 +3,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#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<std::string, std::vector<float>> 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
|
||||
|
@ -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_;
|
||||
|
@ -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<float> &pixels = render_images_["Combined"];
|
||||
while (true) {
|
||||
if (RE_engine_test_break(bl_engine_)) {
|
||||
break;
|
||||
/* Empty fucntion */
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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<float> &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<float> &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
|
||||
|
@ -11,17 +11,16 @@ class PreviewEngine : public FinalEngine {
|
||||
public:
|
||||
using FinalEngine::FinalEngine;
|
||||
|
||||
void render(Depsgraph *depsgraph) override;
|
||||
|
||||
private:
|
||||
void update_render_result(std::vector<float> &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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user