Blender V5.0
hydra/engine.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "engine.hh"
6
7#include <pxr/base/plug/plugin.h>
8#include <pxr/base/plug/registry.h>
9#include <pxr/imaging/hd/rendererPluginRegistry.h>
10#include <pxr/imaging/hdSt/renderDelegate.h>
11#include <pxr/imaging/hgi/tokens.h>
12#include <pxr/usd/usdGeom/tokens.h>
13
14#include "BLI_path_utils.hh"
15
16#include "BKE_context.hh"
17
18#include "GPU_context.hh"
19
21
22#include "RE_engine.h"
23
24#include "CLG_log.h"
25
26namespace blender::render::hydra {
27
29
30Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
31 : render_delegate_name_(render_delegate_name), bl_engine_(bl_engine)
32{
33 pxr::HdRendererPluginRegistry &registry = pxr::HdRendererPluginRegistry::GetInstance();
34
35 pxr::TF_PY_ALLOW_THREADS_IN_SCOPE();
36
37 pxr::HdDriverVector hd_drivers;
38 if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
39 pxr::TfToken hgi_token;
40 switch (GPU_backend_get_type()) {
42 hgi_token = pxr::TfToken("Metal");
43 break;
45 hgi_token = pxr::TfToken("OpenGL");
46 break;
48 hgi_token = pxr::TfToken("Vulkan");
49 break;
51 case GPU_BACKEND_ANY:
52 /* When pxr::Hgi::CreateNamedHgi is called with an empty token it will select the default
53 * platform Hgi. */
54 break;
55 }
56 hgi_ = pxr::Hgi::CreateNamedHgi(hgi_token);
57 hgi_driver_.name = pxr::HgiTokens->renderDriver;
58 hgi_driver_.driver = pxr::VtValue(hgi_.get());
59
60 hd_drivers.push_back(&hgi_driver_);
61 }
62 render_delegate_ = registry.CreateRenderDelegate(pxr::TfToken(render_delegate_name_));
63
64 if (!render_delegate_) {
65 throw std::runtime_error("Cannot create render delegate: " + render_delegate_name_);
66 }
67
68 render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers));
69 free_camera_delegate_ = std::make_unique<io::hydra::CameraDelegate>(
70 render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera"));
71
73 render_task_delegate_ = std::make_unique<GPURenderTaskDelegate>(
74 render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
75 }
76 else {
77 render_task_delegate_ = std::make_unique<RenderTaskDelegate>(
78 render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
79 }
80 render_task_delegate_->set_camera(free_camera_delegate_->GetCameraId());
81
82 if (render_delegate_name_ == "HdStormRendererPlugin") {
83 light_tasks_delegate_ = std::make_unique<LightTasksDelegate>(
84 render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("lightTasks"));
85 light_tasks_delegate_->set_camera(free_camera_delegate_->GetCameraId());
86 }
87
88 engine_ = std::make_unique<pxr::HdEngine>();
89}
90
91void Engine::sync(Depsgraph *depsgraph, bContext *context)
92{
94 context_ = context;
96
97 const bool use_materialx = bl_engine_->type->flag & RE_USE_MATERIALX;
98
99 if (scene_->hydra.export_method == SCE_HYDRA_EXPORT_HYDRA) {
100 /* Fast path. */
101 usd_scene_delegate_.reset();
102
104 pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene");
105 hydra_scene_delegate_ = std::make_unique<io::hydra::HydraSceneDelegate>(
106 render_index_.get(), scene_path, free_camera_delegate_.get(), use_materialx);
107 }
108 hydra_scene_delegate_->populate(depsgraph, context ? CTX_wm_view3d(context) : nullptr);
109 }
110 else {
111 /* Slow USD export for reference. */
113 /* Freeing the Hydra scene delegate crashes as something internal to USD
114 * still holds a pointer to it, only clear it instead. */
115 hydra_scene_delegate_->clear();
116 }
117
118 if (!usd_scene_delegate_) {
119 pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("usd_scene");
120 usd_scene_delegate_ = std::make_unique<io::hydra::USDSceneDelegate>(
121 render_index_.get(), scene_path, use_materialx);
122 }
124 }
126}
127
128void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val)
129{
130 render_delegate_->SetRenderSetting(pxr::TfToken(key), val);
131}
132
134{
135 pxr::VtDictionary render_stats = render_delegate_->GetRenderStats();
136 auto it = render_stats.find("percentDone");
137 if (it == render_stats.end()) {
138 return 0.0f;
139 }
140 return float(it->second.UncheckedGet<double>());
141}
142
143pxr::HdTaskSharedPtrVector Engine::tasks()
144{
145 pxr::HdTaskSharedPtrVector res;
147 if (scene_->r.alphamode != R_ALPHAPREMUL) {
148#ifndef __APPLE__
149 /* TODO: Temporary disable skydome task for MacOS due to crash with error:
150 * Failed to create pipeline state, error depthAttachmentPixelFormat is not valid
151 * and shader writes to depth */
152 res.push_back(light_tasks_delegate_->skydome_task());
153#endif
154 }
155 res.push_back(light_tasks_delegate_->simple_task());
156 }
157 res.push_back(render_task_delegate_->task());
158 return res;
159}
160
161} // namespace blender::render::hydra
View3D * CTX_wm_view3d(const bContext *C)
#define CLG_LOGREF_DECLARE_GLOBAL(var, id)
Definition CLG_log.h:139
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
@ SCE_HYDRA_EXPORT_HYDRA
@ R_ALPHAPREMUL
GPUBackendType GPU_backend_get_type()
@ RE_USE_MATERIALX
Definition RE_engine.h:53
@ RE_USE_GPU_CONTEXT
Definition RE_engine.h:50
BPy_StructRNA * depsgraph
Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
RenderEngine * bl_engine_
Definition engine.hh:36
void sync(Depsgraph *depsgraph, bContext *context)
pxr::HdTaskSharedPtrVector tasks()
std::unique_ptr< RenderTaskDelegate > render_task_delegate_
Definition engine.hh:51
pxr::HdPluginRenderDelegateUniqueHandle render_delegate_
Definition engine.hh:44
std::string render_delegate_name_
Definition engine.hh:35
std::unique_ptr< io::hydra::CameraDelegate > free_camera_delegate_
Definition engine.hh:47
std::unique_ptr< io::hydra::USDSceneDelegate > usd_scene_delegate_
Definition engine.hh:49
std::unique_ptr< pxr::HdRenderIndex > render_index_
Definition engine.hh:45
std::unique_ptr< io::hydra::HydraSceneDelegate > hydra_scene_delegate_
Definition engine.hh:48
pxr::HgiUniquePtr hgi_
Definition engine.hh:42
virtual void set_render_setting(const std::string &key, const pxr::VtValue &val)
std::unique_ptr< LightTasksDelegate > light_tasks_delegate_
Definition engine.hh:52
std::unique_ptr< pxr::HdEngine > engine_
Definition engine.hh:53
nullptr float
struct CLG_LogRef * LOG_HYDRA_RENDER
RenderEngineType * type
Definition RE_engine.h:130