Skip to content

Commit

Permalink
migrate UBOBindingsSaver class to px_vp20/utils
Browse files Browse the repository at this point in the history
This workaround was originally extracted from the Pixar batch renderer and
turned into a more convenient and reusable RAII-style class. Since the
workaround it provides is needed in multiple places, it would be good to have
it defined publicly to take advantage of that reuse.
  • Loading branch information
mattyjams committed Feb 20, 2020
1 parent c75e696 commit 32def62
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 42 deletions.
43 changes: 1 addition & 42 deletions lib/render/mayaToHydra/renderOverride.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ PXR_NAMESPACE_CLOSE_SCOPE
#include <chrono>
#include <exception>

#include "mayaUsd/render/px_vp20/utils.h"
#include "../../usd/hdMaya/delegates/delegateRegistry.h"
#include "../../usd/hdMaya/delegates/sceneDelegate.h"

Expand Down Expand Up @@ -107,48 +108,6 @@ class UfeSelectionObserver : public UFE_NS::Observer {

#endif // WANT_UFE_BUILD

/// Simple RAII class to save uniform buffer bindings, to deal with a maya
/// issue.
///
/// As originally explained by Pixar in their usdmaya plugin:
///
/// XXX: When Maya is using OpenGL Core Profile as the rendering engine (in
/// either compatibility or strict mode), batch renders like those done in
/// the "Render View" window or through the ogsRender command do not
/// properly track uniform buffer binding state. This was causing issues
/// where the first batch render performed would look correct, but then all
/// subsequent renders done in that Maya session would be completely black
/// (no alpha), even if the frame contained only Maya-native geometry or if
/// a new scene was created/opened.
///
/// To avoid this problem, we need to save and restore Maya's bindings
/// across Hydra calls. We try not to bog down performance by saving and
/// restoring *all* GL_MAX_UNIFORM_BUFFER_BINDINGS possible bindings, so
/// instead we only do just enough to avoid issues. Empirically, the
/// problematic binding has been the material binding at index 4.
class UBOBindingsSaver {
public:
static constexpr size_t UNIFORM_BINDINGS_TO_SAVE = 5u;

UBOBindingsSaver() {
for (size_t i = 0u; i < _uniformBufferBindings.size(); ++i) {
glGetIntegeri_v(
GL_UNIFORM_BUFFER_BINDING, (GLuint)i,
&_uniformBufferBindings[i]);
}
}

~UBOBindingsSaver() {
for (size_t i = 0u; i < _uniformBufferBindings.size(); ++i) {
glBindBufferBase(
GL_UNIFORM_BUFFER, (GLuint)i, _uniformBufferBindings[i]);
}
}

private:
std::array<GLint, UNIFORM_BINDINGS_TO_SAVE> _uniformBufferBindings;
};

} // namespace

MtohRenderOverride::MtohRenderOverride(const MtohRendererDescription& desc)
Expand Down
22 changes: 22 additions & 0 deletions lib/render/px_vp20/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "pxr/base/gf/vec3f.h"
#include "pxr/base/gf/vec4f.h"
#include "pxr/base/tf/stringUtils.h"
#include "pxr/imaging/garch/gl.h"
#include "pxr/imaging/glf/simpleLight.h"
#include "pxr/imaging/glf/simpleLightingContext.h"
#include "pxr/imaging/glf/simpleMaterial.h"
Expand Down Expand Up @@ -1081,4 +1082,25 @@ px_vp20Utils::OutputDisplayStatusToStream(
}


UBOBindingsSaver::UBOBindingsSaver()
{
for (size_t i = 0u; i < _uniformBufferBindings.size(); ++i) {
glGetIntegeri_v(
GL_UNIFORM_BUFFER_BINDING,
static_cast<GLuint>(i),
&_uniformBufferBindings[i]);
}
}

UBOBindingsSaver::~UBOBindingsSaver()
{
for (size_t i = 0u; i < _uniformBufferBindings.size(); ++i) {
glBindBufferBase(
GL_UNIFORM_BUFFER,
static_cast<GLuint>(i),
_uniformBufferBindings[i]);
}
}


PXR_NAMESPACE_CLOSE_SCOPE
36 changes: 36 additions & 0 deletions lib/render/px_vp20/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "pxr/base/gf/matrix4d.h"
#include "pxr/base/gf/matrix4f.h"
#include "pxr/base/gf/vec4f.h"
#include "pxr/imaging/garch/gl.h"
#include "pxr/imaging/glf/simpleLightingContext.h"

#include <maya/M3dView.h>
Expand All @@ -33,6 +34,7 @@
#include <maya/MMatrix.h>
#include <maya/MSelectionContext.h>

#include <array>
#include <ostream>


Expand Down Expand Up @@ -115,6 +117,40 @@ class px_vp20Utils
};


/// Simple RAII class to save uniform buffer bindings, to deal with a Maya
/// issue.
///
/// XXX: When Maya is using OpenGL Core Profile as the rendering engine (in
/// either compatibility or strict mode), batch renders like those done in the
/// "Render View" window or through the ogsRender command do not properly track
/// uniform buffer binding state. This was causing issues where the first batch
/// render performed would look correct, but then all subsequent renders done
/// in that Maya session would be completely black (no alpha), even if the
/// frame contained only Maya-native geometry or if a new scene was
/// created/opened.
///
/// To avoid this problem, this object can be used to save and restore Maya's
/// uniform buffer bindings across Hydra/OpenGL calls. We try not to bog down
/// performance by saving and restoring *all* GL_MAX_UNIFORM_BUFFER_BINDINGS
/// possible bindings, so instead we only do just enough to avoid issues.
/// Empirically, the problematic binding has been the material binding at
/// index 4.
class UBOBindingsSaver
{
public:
static constexpr size_t UNIFORM_BINDINGS_TO_SAVE = 5u;

MAYAUSD_CORE_PUBLIC
UBOBindingsSaver();

MAYAUSD_CORE_PUBLIC
~UBOBindingsSaver();

private:
std::array<GLint, UNIFORM_BINDINGS_TO_SAVE> _uniformBufferBindings;
};


PXR_NAMESPACE_CLOSE_SCOPE


Expand Down

0 comments on commit 32def62

Please sign in to comment.