Cycles: Hydra fixes for stageMetersPerUnit and OpenGL context on Windows

Add "stageMetersPerUnit" render setting for USD files that have that set to
something other than the default (e.g. exported by Blender).

And fix a crash when an application creates a Hydra render pass on a thread
that does not have an OpenGL context current.
This commit is contained in:
Patrick Mours 2022-04-20 13:40:48 +02:00 committed by Brecht Van Lommel
parent 9b92ce9dc0
commit fc2c22e90c
5 changed files with 82 additions and 49 deletions

View File

@ -19,44 +19,66 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE
HdCyclesDisplayDriver::HdCyclesDisplayDriver(HdCyclesSession *renderParam, Hgi *hgi)
: _renderParam(renderParam), _hgi(hgi)
{
#ifdef _WIN32
hdc_ = GetDC(CreateWindowA("STATIC",
"HdCycles",
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0,
0,
64,
64,
NULL,
NULL,
GetModuleHandle(NULL),
NULL));
int pixelFormat = GetPixelFormat(wglGetCurrentDC());
PIXELFORMATDESCRIPTOR pfd = {sizeof(pfd)};
DescribePixelFormat((HDC)hdc_, pixelFormat, sizeof(pfd), &pfd);
SetPixelFormat((HDC)hdc_, pixelFormat, &pfd);
TF_VERIFY(gl_context_ = wglCreateContext((HDC)hdc_));
TF_VERIFY(wglShareLists(wglGetCurrentContext(), (HGLRC)gl_context_));
#endif
glewInit();
glGenBuffers(1, &gl_pbo_id_);
}
HdCyclesDisplayDriver::~HdCyclesDisplayDriver()
{
deinit();
}
void HdCyclesDisplayDriver::init()
{
#ifdef _WIN32
if (!gl_context_) {
hdc_ = GetDC(CreateWindowA("STATIC",
"HdCycles",
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0,
0,
64,
64,
NULL,
NULL,
GetModuleHandle(NULL),
NULL));
int pixelFormat = GetPixelFormat(wglGetCurrentDC());
PIXELFORMATDESCRIPTOR pfd = {sizeof(pfd)};
DescribePixelFormat((HDC)hdc_, pixelFormat, sizeof(pfd), &pfd);
SetPixelFormat((HDC)hdc_, pixelFormat, &pfd);
TF_VERIFY(gl_context_ = wglCreateContext((HDC)hdc_));
TF_VERIFY(wglShareLists(wglGetCurrentContext(), (HGLRC)gl_context_));
}
if (!gl_context_) {
return;
}
#endif
if (!gl_pbo_id_) {
if (glewInit() != GLEW_OK) {
return;
}
glGenBuffers(1, &gl_pbo_id_);
}
}
void HdCyclesDisplayDriver::deinit()
{
if (texture_) {
_hgi->DestroyTexture(&texture_);
}
glDeleteBuffers(1, &gl_pbo_id_);
if (gl_pbo_id_) {
glDeleteBuffers(1, &gl_pbo_id_);
}
#ifdef _WIN32
TF_VERIFY(wglDeleteContext((HGLRC)gl_context_));
DestroyWindow(WindowFromDC((HDC)hdc_));
if (gl_context_) {
TF_VERIFY(wglDeleteContext((HGLRC)gl_context_));
DestroyWindow(WindowFromDC((HDC)hdc_));
}
#endif
}
@ -192,6 +214,8 @@ void HdCyclesDisplayDriver::draw(const Params &params)
return;
}
init();
// Cycles 'DisplayDriver' only supports 'half4' format
TF_VERIFY(renderBuffer->GetFormat() == HdFormatFloat16Vec4);

View File

@ -19,6 +19,9 @@ class HdCyclesDisplayDriver final : public CCL_NS::DisplayDriver {
~HdCyclesDisplayDriver();
private:
void init();
void deinit();
void next_tile_begin() override;
bool update_begin(const Params &params, int texture_width, int texture_height) override;

View File

@ -18,6 +18,7 @@
#include <pxr/imaging/hd/task.h>
#include <pxr/usd/usd/stage.h>
#include <pxr/usd/usdGeom/camera.h>
#include <pxr/usd/usdGeom/metrics.h>
#include <pxr/usdImaging/usdImaging/delegate.h>
HDCYCLES_NAMESPACE_OPEN_SCOPE
@ -69,6 +70,9 @@ void HdCyclesFileReader::read(Session *session, const char *filepath, const bool
/* Create render delegate. */
HdRenderSettingsMap settings_map;
settings_map.insert(std::make_pair(HdCyclesRenderSettingsTokens->stageMetersPerUnit,
VtValue(UsdGeomGetStageMetersPerUnit(stage))));
HdCyclesDelegate render_delegate(settings_map, session, true);
/* Create render index and scene delegate. */
@ -110,7 +114,7 @@ void HdCyclesFileReader::read(Session *session, const char *filepath, const bool
HdSprim *sprim = render_index->GetSprim(HdPrimTypeTokens->camera, prim.GetPath());
if (sprim) {
HdCyclesCamera *camera = dynamic_cast<HdCyclesCamera *>(sprim);
camera->ApplyCameraSettings(session->scene->camera);
camera->ApplyCameraSettings(render_delegate.GetRenderParam(), session->scene->camera);
break;
}
}

View File

@ -26,20 +26,13 @@
HDCYCLES_NAMESPACE_OPEN_SCOPE
TF_DEFINE_PUBLIC_TOKENS(HdCyclesRenderSettingsTokens, HD_CYCLES_RENDER_SETTINGS_TOKENS);
// clang-format off
TF_DEFINE_PRIVATE_TOKENS(_tokens,
(cycles)
(openvdbAsset)
);
TF_DEFINE_PRIVATE_TOKENS(HdCyclesRenderSettingsTokens,
(stageMetersPerUnit)
((device, "cycles:device"))
((threads, "cycles:threads"))
((timeLimit, "cycles:time_limit"))
((samples, "cycles:samples"))
((sampleOffset, "cycles:sample_offset"))
);
// clang-format on
namespace {
@ -127,17 +120,14 @@ HdCyclesDelegate::HdCyclesDelegate(const HdRenderSettingsMap &settingsMap,
_renderParam = session_ ? std::make_unique<HdCyclesSession>(session_, keep_nodes) :
std::make_unique<HdCyclesSession>(GetSessionParams(settingsMap));
// If the delegate owns the session, pull any remaining settings
if (!session_) {
for (const auto &setting : settingsMap) {
// Skip over the settings known to be used for initialization only
if (setting.first == HdCyclesRenderSettingsTokens->device ||
setting.first == HdCyclesRenderSettingsTokens->threads) {
continue;
}
SetRenderSetting(setting.first, setting.second);
for (const auto &setting : settingsMap) {
// Skip over the settings known to be used for initialization only
if (setting.first == HdCyclesRenderSettingsTokens->device ||
setting.first == HdCyclesRenderSettingsTokens->threads) {
continue;
}
SetRenderSetting(setting.first, setting.second);
}
}
@ -328,7 +318,7 @@ HdBprim *HdCyclesDelegate::CreateBprim(const TfToken &typeId, const SdfPath &bpr
}
#endif
TF_RUNTIME_ERROR("Unknown Bprim type %s", typeId.GetText());
TF_CODING_ERROR("Unknown Bprim type %s", typeId.GetText());
return nullptr;
}

View File

@ -11,6 +11,18 @@
HDCYCLES_NAMESPACE_OPEN_SCOPE
// clang-format off
#define HD_CYCLES_RENDER_SETTINGS_TOKENS \
(stageMetersPerUnit) \
((device, "cycles:device")) \
((threads, "cycles:threads")) \
((timeLimit, "cycles:time_limit")) \
((samples, "cycles:samples")) \
((sampleOffset, "cycles:sample_offset"))
// clang-format on
TF_DECLARE_PUBLIC_TOKENS(HdCyclesRenderSettingsTokens, HD_CYCLES_RENDER_SETTINGS_TOKENS);
class HdCyclesDelegate final : public PXR_NS::HdRenderDelegate {
public:
HdCyclesDelegate(const PXR_NS::HdRenderSettingsMap &settingsMap,