Skip to content

Commit

Permalink
Merge pull request #291 from mattyjams/pr/batch_renderer_selection_un…
Browse files Browse the repository at this point in the history
…iform_buffer_binding_workaround

save and restore uniform buffer bindings during batch renderer selection
  • Loading branch information
Krystian Ligenza authored Feb 20, 2020
2 parents c75e696 + 5c448b5 commit 77c1585
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 73 deletions.
45 changes: 2 additions & 43 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 Expand Up @@ -420,7 +379,7 @@ MStatus MtohRenderOverride::Render(const MHWRender::MDrawContext& drawContext) {
_InitHydraResources();
}

UBOBindingsSaver bindingsSaver;
GLUniformBufferBindingsSaver bindingsSaver;

_SelectionChanged();

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(
}


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

GLUniformBufferBindingsSaver::~GLUniformBufferBindingsSaver()
{
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 GLUniformBufferBindingsSaver
{
public:
MAYAUSD_CORE_PUBLIC
GLUniformBufferBindingsSaver();

MAYAUSD_CORE_PUBLIC
~GLUniformBufferBindingsSaver();

private:
static constexpr size_t UNIFORM_BINDINGS_TO_SAVE = 5u;

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


PXR_NAMESPACE_CLOSE_SCOPE


Expand Down
37 changes: 7 additions & 30 deletions lib/render/pxrUsdMayaGL/batchRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
#include "./debugCodes.h"
#include "./userData.h"

#include "../px_vp20/utils.h"
#include "../px_vp20/utils_legacy.h"
#include "mayaUsd/render/px_vp20/utils.h"
#include "mayaUsd/render/px_vp20/utils_legacy.h"

#include "pxr/base/gf/matrix4d.h"
#include "pxr/base/gf/vec2i.h"
Expand Down Expand Up @@ -993,6 +993,8 @@ UsdMayaGLBatchRenderer::TestIntersectionCustomPrimFilter(
// Differs from viewport implementations in that it doesn't rely on
// _ComputeSelection being called first.

GLUniformBufferBindingsSaver bindingsSaver;

return _TestIntersection(primFilter.collection,
primFilter.renderTags,
viewMatrix, projectionMatrix,
Expand Down Expand Up @@ -1196,6 +1198,8 @@ UsdMayaGLBatchRenderer::_ComputeSelection(

_selectResults.clear();

GLUniformBufferBindingsSaver bindingsSaver;

for (const PxrMayaHdPrimFilter& primFilter : primFilters) {
TF_DEBUG(PXRUSDMAYAGL_BATCHED_SELECTION).Msg(
" --- Intersection Testing with collection: %s\n",
Expand Down Expand Up @@ -1294,27 +1298,7 @@ UsdMayaGLBatchRenderer::_Render(
GL_DEPTH_BUFFER_BIT |
GL_VIEWPORT_BIT);

// 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.
static constexpr size_t _UNIFORM_BINDINGS_TO_SAVE = 5u;
std::vector<GLint> uniformBufferBindings(_UNIFORM_BINDINGS_TO_SAVE, 0);
for (size_t i = 0u; i < uniformBufferBindings.size(); ++i) {
glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING,
(GLuint)i,
&uniformBufferBindings[i]);
}
GLUniformBufferBindingsSaver bindingsSaver;

// hydra orients all geometry during topological processing so that
// front faces have ccw winding. We disable culling because culling
Expand Down Expand Up @@ -1374,13 +1358,6 @@ UsdMayaGLBatchRenderer::_Render(

glDisable(GL_FRAMEBUFFER_SRGB_EXT);

// XXX: Restore Maya's uniform buffer binding state. See above for details.
for (size_t i = 0u; i < uniformBufferBindings.size(); ++i) {
glBindBufferBase(GL_UNIFORM_BUFFER,
(GLuint)i,
uniformBufferBindings[i]);
}

glPopAttrib(); // GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT |
// GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT
}
Expand Down

0 comments on commit 77c1585

Please sign in to comment.