Fixed rendering for MacOS #82

Merged
Bogdan Nagirniak merged 10 commits from BLEN-473 into hydra-render 2023-08-02 09:37:25 +02:00
9 changed files with 70 additions and 37 deletions

View File

@ -7,6 +7,7 @@ USD Hydra Based Renderer
import bpy import bpy
class CustomHydraRenderEngine(bpy.types.HydraRenderEngine): class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
# Identifier and name in the user interface. # Identifier and name in the user interface.
bl_idname = "CUSTOM_HYDRA_RENDERER" bl_idname = "CUSTOM_HYDRA_RENDERER"
@ -53,8 +54,10 @@ class CustomHydraRenderEngine(bpy.types.HydraRenderEngine):
def register(): def register():
bpy.utils.register_class(CustomHydraRenderEngine) bpy.utils.register_class(CustomHydraRenderEngine)
def unregister(): def unregister():
bpy.utils.unregister_class(CustomHydraRenderEngine) bpy.utils.unregister_class(CustomHydraRenderEngine)
if __name__ == "__main__": if __name__ == "__main__":
register() register()

View File

@ -4,6 +4,7 @@ __all__ = (
"export_mtlx", "export_mtlx",
) )
def export_mtlx(material): def export_mtlx(material):
""" Exports material to .mtlx file. It is called from Blender source code. """ """ Exports material to .mtlx file. It is called from Blender source code. """
import materialx.utils as mx_utils import materialx.utils as mx_utils

View File

@ -62,6 +62,7 @@ set(INC_SYS
${BOOST_INCLUDE_DIR} ${BOOST_INCLUDE_DIR}
${TBB_INCLUDE_DIR} ${TBB_INCLUDE_DIR}
${GFLAGS_INCLUDE_DIRS} ${GFLAGS_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIRS}
) )
set(LIB set(LIB

View File

@ -55,7 +55,7 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
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) { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT && GPU_backend_get_type() == GPU_BACKEND_OPENGL) {
render_task_delegate_ = std::make_unique<GPURenderTaskDelegate>( render_task_delegate_ = std::make_unique<GPURenderTaskDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
} }
@ -133,4 +133,22 @@ float Engine::renderer_percent_done()
return (float)it->second.UncheckedGet<double>(); return (float)it->second.UncheckedGet<double>();
} }
pxr::HdTaskSharedPtrVector Engine::tasks()
{
pxr::HdTaskSharedPtrVector res;
if (light_tasks_delegate_) {
if (scene_->r.alphamode != R_ALPHAPREMUL) {
#ifndef __APPLE__
/* TODO: Temporary disable skydome task for MacOS due to crash with error:
* Failed to created pipeline state, error depthAttachmentPixelFormat is not valid
* and shader writes to depth */
res.push_back(light_tasks_delegate_->skydome_task());
#endif
}
res.push_back(light_tasks_delegate_->simple_task());
}
res.push_back(render_task_delegate_->task());
return res;
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -64,7 +64,10 @@ class Engine {
protected: protected:
float renderer_percent_done(); float renderer_percent_done();
virtual void notify_status(float progress, const std::string &title, const std::string &info) = 0; pxr::HdTaskSharedPtrVector tasks();
virtual void notify_status(float progress,
const std::string &title,
const std::string &info) = 0;
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -66,18 +66,10 @@ void FinalEngine::render()
render_task_delegate_->add_aov(pxr::HdAovTokens->depth); render_task_delegate_->add_aov(pxr::HdAovTokens->depth);
} }
pxr::HdTaskSharedPtrVector tasks;
if (light_tasks_delegate_) {
if (scene_->r.alphamode != R_ALPHAPREMUL) {
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_->bind(); render_task_delegate_->bind();
engine_->Execute(render_index_.get(), &tasks); auto t = tasks();
engine_->Execute(render_index_.get(), &t);
char elapsed_time[32]; char elapsed_time[32];
double time_begin = PIL_check_seconds_timer(); double time_begin = PIL_check_seconds_timer();

View File

@ -37,6 +37,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
RenderEngine *bl_engine = pyrna_to_pointer<RenderEngine>(pyengine, &RNA_RenderEngine); RenderEngine *bl_engine = pyrna_to_pointer<RenderEngine>(pyengine, &RNA_RenderEngine);
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %s", engine_type);
Engine *engine = nullptr; Engine *engine = nullptr;
try { try {
if (STREQ(engine_type, "VIEWPORT")) { if (STREQ(engine_type, "VIEWPORT")) {
@ -53,9 +54,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
CLOG_ERROR(LOG_HYDRA_RENDER, "%s", e.what()); CLOG_ERROR(LOG_HYDRA_RENDER, "%s", e.what());
} }
if (engine) { CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine);
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p %s", engine, engine_type);
}
return PyLong_FromVoidPtr(engine); return PyLong_FromVoidPtr(engine);
} }
@ -67,9 +66,9 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
} }
Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine)); Engine *engine = static_cast<Engine *>(PyLong_AsVoidPtr(pyengine));
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine);
delete engine; delete engine;
CLOG_INFO(LOG_HYDRA_RENDER, 1, "Engine %p", engine);
Py_RETURN_NONE; Py_RETURN_NONE;
} }

View File

@ -13,8 +13,9 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "Eigen/Core"
#include "engine.h" #include "engine.h"
#include "render_task_delegate.h"
namespace blender::render::hydra { namespace blender::render::hydra {
@ -107,6 +108,16 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
aov_key); aov_key);
if (aov_desc.format == pxr::HdFormatInvalid) { if (aov_desc.format == pxr::HdFormatInvalid) {
CLOG_ERROR(LOG_HYDRA_RENDER, "Invalid AOV: %s", aov_key.GetText());
return;
}
if (!ELEM(
pxr::HdGetComponentFormat(aov_desc.format), pxr::HdFormatFloat32, pxr::HdFormatFloat16))
{
CLOG_WARN(LOG_HYDRA_RENDER,
"Unsupported data format %s for AOV %s",
pxr::TfEnum::GetName(aov_desc.format).c_str(),
aov_key.GetText());
return; return;
} }
@ -120,7 +131,7 @@ void RenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
binding.aovName = aov_key; binding.aovName = aov_key;
binding.renderBufferId = buf_id; binding.renderBufferId = buf_id;
binding.aovSettings = aov_desc.aovSettings; binding.aovSettings = aov_desc.aovSettings;
binding.clearValue = pxr::VtValue(pxr::GfVec4f(0)); binding.clearValue = aov_desc.clearValue;
task_params_.aovBindings.push_back(binding); task_params_.aovBindings.push_back(binding);
render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams); render_index.GetChangeTracker().MarkTaskDirty(task_id_, pxr::HdChangeTracker::DirtyParams);
@ -134,11 +145,25 @@ void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data)
if (!buffer) { if (!buffer) {
return; return;
} }
pxr::HdFormat format = buffer->GetFormat();
size_t len = buffer->GetWidth() * buffer->GetHeight() * pxr::HdGetComponentCount(format);
if (pxr::HdGetComponentFormat(format) == pxr::HdFormatFloat32) {
void *buf_data = buffer->Map(); void *buf_data = buffer->Map();
memcpy(data, memcpy(data, buf_data, len * sizeof(float));
buf_data,
buffer->GetWidth() * buffer->GetHeight() * pxr::HdDataSizeOfFormat(buffer->GetFormat()));
buffer->Unmap(); buffer->Unmap();
}
else if (pxr::HdGetComponentFormat(format) == pxr::HdFormatFloat16) {
Eigen::half *buf_data = (Eigen::half *)buffer->Map();
float *fdata = (float *)data;
for (size_t i = 0; i < len; ++i) {
fdata[i] = buf_data[i];
}
buffer->Unmap();
}
else {
BLI_assert_unreachable();
}
} }
void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) void RenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture)
@ -210,6 +235,7 @@ void GPURenderTaskDelegate::add_aov(pxr::TfToken const &aov_key)
tex = &tex_depth_; tex = &tex_depth_;
} }
else { else {
CLOG_ERROR(LOG_HYDRA_RENDER, "Invalid AOV: %s", aov_key.GetText());
return; return;
} }
@ -253,14 +279,11 @@ void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, void *data)
void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture) void GPURenderTaskDelegate::read_aov(pxr::TfToken const &aov_key, GPUTexture *texture)
{ {
GPUTexture *tex = nullptr; GPUTexture *tex = nullptr;
int c;
if (aov_key == pxr::HdAovTokens->color) { if (aov_key == pxr::HdAovTokens->color) {
tex = tex_color_; tex = tex_color_;
c = 4;
} }
else if (aov_key == pxr::HdAovTokens->depth) { else if (aov_key == pxr::HdAovTokens->depth) {
tex = tex_depth_; tex = tex_depth_;
c = 1;
} }
if (!tex) { if (!tex) {
return; return;

View File

@ -232,19 +232,11 @@ void ViewportEngine::render()
render_task_delegate_->add_aov(pxr::HdAovTokens->color); render_task_delegate_->add_aov(pxr::HdAovTokens->color);
render_task_delegate_->add_aov(pxr::HdAovTokens->depth); render_task_delegate_->add_aov(pxr::HdAovTokens->depth);
pxr::HdTaskSharedPtrVector tasks;
if (light_tasks_delegate_) {
if (scene_->r.alphamode != R_ALPHAPREMUL) {
tasks.push_back(light_tasks_delegate_->skydome_task());
}
tasks.push_back(light_tasks_delegate_->simple_task());
}
tasks.push_back(render_task_delegate_->task());
GPUFrameBuffer *view_framebuffer = GPU_framebuffer_active_get(); GPUFrameBuffer *view_framebuffer = GPU_framebuffer_active_get();
render_task_delegate_->bind(); render_task_delegate_->bind();
engine_->Execute(render_index_.get(), &tasks); auto t = tasks();
engine_->Execute(render_index_.get(), &t);
render_task_delegate_->unbind(); render_task_delegate_->unbind();
@ -293,7 +285,8 @@ void ViewportEngine::render(bContext *context)
render(); render();
} }
void ViewportEngine::notify_status(float /*progress*/, const std::string &info, void ViewportEngine::notify_status(float /*progress*/,
const std::string &info,
const std::string &status) const std::string &status)
{ {
RE_engine_update_stats(bl_engine_, status.c_str(), info.c_str()); RE_engine_update_stats(bl_engine_, status.c_str(), info.c_str());