diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 12fe44325d62..d70a3371ec20 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -57,8 +57,6 @@ void FinalEngine::render(Depsgraph *depsgraph) 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_) { if (scene->r.alphamode != R_ALPHAPREMUL) { @@ -67,6 +65,9 @@ void FinalEngine::render(Depsgraph *depsgraph) tasks.push_back(light_tasks_delegate_->simple_task()); } tasks.push_back(render_task_delegate_->task()); + + render_task_delegate_->bind(); + engine_->Execute(render_index_.get(), &tasks); char elapsed_time[32]; diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 02d2392ddf00..8c6997f03b03 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -105,6 +105,7 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key) binding.aovName = aov_key; binding.renderBufferId = buf_id; binding.aovSettings = aov_desc.aovSettings; + binding.clearValue = pxr::VtValue(pxr::GfVec4f(0)); task_params_.aovBindings.push_back(binding); render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); } @@ -130,8 +131,11 @@ void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *textu if (!buffer) { return; } + eGPUDataFormat format = buffer->GetFormat() == pxr::HdFormat::HdFormatFloat16Vec4 ? + GPU_DATA_HALF_FLOAT : + GPU_DATA_FLOAT; void *buf_data = buffer->Map(); - GPU_texture_update(texture, GPU_DATA_FLOAT, buf_data); + GPU_texture_update(texture, format, buf_data); buffer->Unmap(); } @@ -144,6 +148,17 @@ pxr::SdfPath RenderTaskDelegate::buffer_id(pxr::TfToken const &aov_key) const return GetDelegateID().AppendElementString("aov_" + aov_key.GetString()); } +GPURenderTaskDelegate::~GPURenderTaskDelegate() +{ + unbind(); + if (tex_color_) { + GPU_texture_free(tex_color_); + } + if (tex_depth_) { + GPU_texture_free(tex_depth_); + } +} + void GPURenderTaskDelegate::set_viewport(pxr::GfVec4d const &viewport) { if (task_params_.viewport == viewport) { @@ -251,22 +266,33 @@ void GPURenderTaskDelegate::bind() /* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility * profile this is not a problem, but for core profile it is. */ - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - if (VAO_ == 0) { - glGenVertexArrays(1, &VAO_); - } + if (VAO_ == 0 && GPU_backend_get_type() == GPU_BACKEND_OPENGL) { + glGenVertexArrays(1, &VAO_); glBindVertexArray(VAO_); } } void GPURenderTaskDelegate::unbind() { - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { + if (VAO_) { glDeleteVertexArrays(1, &VAO_); + VAO_ = 0; } - GPU_framebuffer_free(framebuffer_); - GPU_texture_free(tex_color_); - GPU_texture_free(tex_depth_); + if (framebuffer_) { + GPU_framebuffer_free(framebuffer_); + framebuffer_ = nullptr; + } +} + +GPUTexture *GPURenderTaskDelegate::aov_texture(pxr::TfToken const &aov_key) +{ + if (aov_key == pxr::HdAovTokens->color) { + return tex_color_; + } + if (aov_key == pxr::HdAovTokens->depth) { + return tex_depth_; + } + return nullptr; } } // 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 5952b8f86859..82a006889ebd 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -52,6 +52,7 @@ class GPURenderTaskDelegate : public RenderTaskDelegate { public: using RenderTaskDelegate::RenderTaskDelegate; + ~GPURenderTaskDelegate() override; void set_viewport(pxr::GfVec4d const &viewport) override; void add_aov(pxr::TfToken const &aov_key) override; @@ -59,6 +60,7 @@ class GPURenderTaskDelegate : public RenderTaskDelegate { void read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) override; void bind() override; void unbind() override; + GPUTexture *aov_texture(pxr::TfToken const &aov_key); }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 4438e7bce56d..10fc69862c52 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -183,18 +183,16 @@ void DrawTexture::write_data(int width, int height, const void *data) width, height, 1, - GPU_RGBA16F, + GPU_RGBA32F, GPU_TEXTURE_USAGE_GENERAL, (float *)data); } -void DrawTexture::draw(GPUShader *shader, const pxr::GfVec4d &viewport) -{ - draw(shader, texture_, viewport); -} - -void DrawTexture::draw(GPUShader *shader, GPUTexture *tex, const pxr::GfVec4d &viewport) +void DrawTexture::draw(GPUShader *shader, const pxr::GfVec4d &viewport, GPUTexture *tex) { + if (!tex) { + tex = texture_; + } int slot = GPU_shader_get_sampler_binding(shader, "image"); GPU_texture_bind(tex, slot); GPU_shader_uniform_1i(shader, "image", slot); @@ -237,20 +235,8 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) light_tasks_delegate_->set_viewport(viewport); } - if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { - render_task_delegate_->add_aov(pxr::HdAovTokens->color); - } - - /* Workaround missing/buggy VAOs in hgiGL and hdSt. For OpenGL compatibility - * profile this is not a problem, but for core profile it is. */ - GLuint VAO; - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - } - - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); - GPU_shader_bind(shader); + render_task_delegate_->add_aov(pxr::HdAovTokens->color); + render_task_delegate_->add_aov(pxr::HdAovTokens->depth); pxr::HdTaskSharedPtrVector tasks; if (light_tasks_delegate_) { @@ -260,9 +246,24 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) tasks.push_back(light_tasks_delegate_->simple_task()); } tasks.push_back(render_task_delegate_->task()); + + GPUFrameBuffer *view_framebuffer = GPU_framebuffer_active_get(); + render_task_delegate_->bind(); + engine_->Execute(render_index_.get(), &tasks); - if ((bl_engine_->type->flag & RE_USE_GPU_CONTEXT) == 0) { + render_task_delegate_->unbind(); + + GPU_framebuffer_bind(view_framebuffer); + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE); + GPU_shader_bind(shader); + + GPURenderTaskDelegate *gpu_task = dynamic_cast( + render_task_delegate_.get()); + if (gpu_task) { + draw_texture_.draw(shader, viewport, gpu_task->aov_texture(pxr::HdAovTokens->color)); + } + else { 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); @@ -270,10 +271,6 @@ void ViewportEngine::render(Depsgraph *depsgraph, bContext *context) GPU_shader_unbind(); - if (GPU_backend_get_type() == GPU_BACKEND_OPENGL) { - glDeleteVertexArrays(1, &VAO); - } - if (renderer_percent_done() == 0.0f) { time_begin_ = PIL_check_seconds_timer(); } diff --git a/source/blender/render/hydra/viewport_engine.h b/source/blender/render/hydra/viewport_engine.h index 60b889846284..dab01863196b 100644 --- a/source/blender/render/hydra/viewport_engine.h +++ b/source/blender/render/hydra/viewport_engine.h @@ -23,8 +23,7 @@ class DrawTexture { ~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); + void draw(GPUShader *shader, const pxr::GfVec4d &viewport, GPUTexture *tex = nullptr); GPUTexture *texture() const; private: