[Bf-blender-cvs] [34f94a02f37] blender-v3.2-release: Fix use of OpenGL interop breaking in Hydra viewports that do not support it

Patrick Mours noreply at git.blender.org
Fri Jun 3 19:02:34 CEST 2022


Commit: 34f94a02f37005210f629f04635c457d98ff5f91
Author: Patrick Mours
Date:   Wed Jun 1 15:26:55 2022 +0200
Branches: blender-v3.2-release
https://developer.blender.org/rB34f94a02f37005210f629f04635c457d98ff5f91

Fix use of OpenGL interop breaking in Hydra viewports that do not support it

Rendering directly to a resource using OpenGL interop and Hgi
doesn't work in Houdini, since it never uses the resulting resource
(it does not call `HdRenderBuffer::GetResource`). But since doing
that simultaneously disables mapping (`HdRenderBuffer::Map` is
not implemented then), nothing was displayed. To fix this, keep
track of whether a Hydra viewport does support displaying a Hgi
resource directly, by checking whether
`HdRenderBuffer::GetResource` is ever called and only enable use
of OpenGL interop if that is the case.

Differential Revision: https://developer.blender.org/D15090

===================================================================

M	intern/cycles/hydra/display_driver.cpp
M	intern/cycles/hydra/display_driver.h
M	intern/cycles/hydra/output_driver.cpp
M	intern/cycles/hydra/render_buffer.cpp
M	intern/cycles/hydra/render_buffer.h

===================================================================

diff --git a/intern/cycles/hydra/display_driver.cpp b/intern/cycles/hydra/display_driver.cpp
index a809ace63e2..0c0b577c358 100644
--- a/intern/cycles/hydra/display_driver.cpp
+++ b/intern/cycles/hydra/display_driver.cpp
@@ -23,10 +23,18 @@ HdCyclesDisplayDriver::HdCyclesDisplayDriver(HdCyclesSession *renderParam, Hgi *
 
 HdCyclesDisplayDriver::~HdCyclesDisplayDriver()
 {
-  deinit();
+  if (texture_) {
+    _hgi->DestroyTexture(&texture_);
+  }
+
+  if (gl_pbo_id_) {
+    glDeleteBuffers(1, &gl_pbo_id_);
+  }
+
+  gl_context_dispose();
 }
 
-void HdCyclesDisplayDriver::init()
+void HdCyclesDisplayDriver::gl_context_create()
 {
 #ifdef _WIN32
   if (!gl_context_) {
@@ -64,16 +72,42 @@ void HdCyclesDisplayDriver::init()
   }
 }
 
-void HdCyclesDisplayDriver::deinit()
+bool HdCyclesDisplayDriver::gl_context_enable()
 {
-  if (texture_) {
-    _hgi->DestroyTexture(&texture_);
+#ifdef _WIN32
+  if (!hdc_ || !gl_context_) {
+    return false;
   }
 
-  if (gl_pbo_id_) {
-    glDeleteBuffers(1, &gl_pbo_id_);
+  mutex_.lock();
+
+  // Do not change context if this is called in the main thread
+  if (wglGetCurrentContext() == nullptr) {
+    if (!TF_VERIFY(wglMakeCurrent((HDC)hdc_, (HGLRC)gl_context_))) {
+      mutex_.unlock();
+      return false;
+    }
+  }
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+void HdCyclesDisplayDriver::gl_context_disable()
+{
+#ifdef _WIN32
+  if (wglGetCurrentContext() == gl_context_) {
+    TF_VERIFY(wglMakeCurrent(nullptr, nullptr));
   }
 
+  mutex_.unlock();
+#endif
+}
+
+void HdCyclesDisplayDriver::gl_context_dispose()
+{
 #ifdef _WIN32
   if (gl_context_) {
     TF_VERIFY(wglDeleteContext((HGLRC)gl_context_));
@@ -90,13 +124,9 @@ bool HdCyclesDisplayDriver::update_begin(const Params &params,
                                          int texture_width,
                                          int texture_height)
 {
-#ifdef _WIN32
-  if (!hdc_ || !gl_context_) {
+  if (!gl_context_enable()) {
     return false;
   }
-#endif
-
-  graphics_interop_activate();
 
   if (gl_render_sync_) {
     glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
@@ -121,15 +151,14 @@ bool HdCyclesDisplayDriver::update_begin(const Params &params,
 void HdCyclesDisplayDriver::update_end()
 {
   gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-
   glFlush();
 
-  graphics_interop_deactivate();
+  gl_context_disable();
 }
 
 void HdCyclesDisplayDriver::flush()
 {
-  graphics_interop_activate();
+  gl_context_enable();
 
   if (gl_upload_sync_) {
     glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
@@ -139,7 +168,7 @@ void HdCyclesDisplayDriver::flush()
     glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
   }
 
-  graphics_interop_deactivate();
+  gl_context_disable();
 }
 
 half4 *HdCyclesDisplayDriver::map_texture_buffer()
@@ -179,25 +208,12 @@ DisplayDriver::GraphicsInterop HdCyclesDisplayDriver::graphics_interop_get()
 
 void HdCyclesDisplayDriver::graphics_interop_activate()
 {
-  mutex_.lock();
-
-#ifdef _WIN32
-  // Do not change context if this is called in the main thread
-  if (wglGetCurrentContext() == nullptr) {
-    TF_VERIFY(wglMakeCurrent((HDC)hdc_, (HGLRC)gl_context_));
-  }
-#endif
+  gl_context_enable();
 }
 
 void HdCyclesDisplayDriver::graphics_interop_deactivate()
 {
-#ifdef _WIN32
-  if (wglGetCurrentContext() == gl_context_) {
-    TF_VERIFY(wglMakeCurrent(nullptr, nullptr));
-  }
-#endif
-
-  mutex_.unlock();
+  gl_context_disable();
 }
 
 void HdCyclesDisplayDriver::clear()
@@ -214,7 +230,11 @@ void HdCyclesDisplayDriver::draw(const Params &params)
     return;
   }
 
-  init();
+  if (!renderBuffer->IsResourceUsed()) {
+    return;
+  }
+
+  gl_context_create();
 
   // Cycles 'DisplayDriver' only supports 'half4' format
   TF_VERIFY(renderBuffer->GetFormat() == HdFormatFloat16Vec4);
@@ -255,7 +275,6 @@ void HdCyclesDisplayDriver::draw(const Params &params)
   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 
   gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-
   glFlush();
 
   need_update_ = false;
diff --git a/intern/cycles/hydra/display_driver.h b/intern/cycles/hydra/display_driver.h
index 20086830e6a..2a05397c325 100644
--- a/intern/cycles/hydra/display_driver.h
+++ b/intern/cycles/hydra/display_driver.h
@@ -19,9 +19,6 @@ 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;
@@ -41,6 +38,11 @@ class HdCyclesDisplayDriver final : public CCL_NS::DisplayDriver {
 
   void draw(const Params &params) override;
 
+  void gl_context_create();
+  bool gl_context_enable();
+  void gl_context_disable();
+  void gl_context_dispose();
+
   HdCyclesSession *const _renderParam;
   Hgi *const _hgi;
 
@@ -48,7 +50,6 @@ class HdCyclesDisplayDriver final : public CCL_NS::DisplayDriver {
   void *hdc_ = nullptr;
   void *gl_context_ = nullptr;
 #endif
-
   CCL_NS::thread_mutex mutex_;
 
   PXR_NS::HgiTextureHandle texture_;
diff --git a/intern/cycles/hydra/output_driver.cpp b/intern/cycles/hydra/output_driver.cpp
index c5f64ac1c18..f4ea853f243 100644
--- a/intern/cycles/hydra/output_driver.cpp
+++ b/intern/cycles/hydra/output_driver.cpp
@@ -30,11 +30,11 @@ bool HdCyclesOutputDriver::update_render_tile(const Tile &tile)
   std::vector<float> pixels;
 
   for (const HdRenderPassAovBinding &aovBinding : _renderParam->GetAovBindings()) {
-    if (aovBinding == _renderParam->GetDisplayAovBinding()) {
-      continue;  // Display AOV binding is already updated by Cycles display driver
-    }
-
     if (const auto renderBuffer = static_cast<HdCyclesRenderBuffer *>(aovBinding.renderBuffer)) {
+      if (aovBinding == _renderParam->GetDisplayAovBinding() && renderBuffer->IsResourceUsed()) {
+        continue;  // Display AOV binding is already updated by Cycles display driver
+      }
+
       const HdFormat format = renderBuffer->GetFormat();
       if (format == HdFormatInvalid) {
         continue;  // Skip invalid AOV bindings
diff --git a/intern/cycles/hydra/render_buffer.cpp b/intern/cycles/hydra/render_buffer.cpp
index 4867def0624..4d8b21d1e61 100644
--- a/intern/cycles/hydra/render_buffer.cpp
+++ b/intern/cycles/hydra/render_buffer.cpp
@@ -35,7 +35,7 @@ bool HdCyclesRenderBuffer::Allocate(const GfVec3i &dimensions, HdFormat format,
     return false;
   }
 
-  const size_t oldSize = _data.size();
+  const size_t oldSize = _dataSize;
   const size_t newSize = dimensions[0] * dimensions[1] * HdDataSizeOfFormat(format);
   if (oldSize == newSize) {
     return true;
@@ -49,8 +49,8 @@ bool HdCyclesRenderBuffer::Allocate(const GfVec3i &dimensions, HdFormat format,
   _width = dimensions[0];
   _height = dimensions[1];
   _format = format;
-
-  _data.resize(newSize);
+  _dataSize = newSize;
+  _resourceUsed = false;
 
   return true;
 }
@@ -63,6 +63,7 @@ void HdCyclesRenderBuffer::_Deallocate()
 
   _data.clear();
   _data.shrink_to_fit();
+  _dataSize = 0;
 
   _resource = VtValue();
 }
@@ -74,6 +75,10 @@ void *HdCyclesRenderBuffer::Map()
     return nullptr;
   }
 
+  if (_data.size() != _dataSize) {
+    _data.resize(_dataSize);
+  }
+
   ++_mapped;
 
   return _data.data();
@@ -103,10 +108,17 @@ void HdCyclesRenderBuffer::SetConverged(bool converged)
   _converged = converged;
 }
 
+bool HdCyclesRenderBuffer::IsResourceUsed() const
+{
+  return _resourceUsed;
+}
+
 VtValue HdCyclesRenderBuffer::GetResource(bool multiSampled) const
 {
   TF_UNUSED(multiSampled);
 
+  _resourceUsed = true;
+
   return _resource;
 }
 
diff --git a/intern/cycles/hydra/render_buffer.h b/intern/cycles/hydra/render_buffer.h
index 8eb874f0068..90629d4aee0 100644
--- a/intern/cycles/hydra/render_buffer.h
+++ b/intern/cycles/hydra/render_buffer.h
@@ -58,6 +58,8 @@ class HdCyclesRenderBuffer final : public PXR_NS::HdRenderBuffer {
 
   void SetConverged(bool converged);
 
+  bool IsResourceUsed() const;
+
   PXR_NS::VtValue GetResource(bool multiSampled = false) const override;
 
   void SetResource(const PXR_NS::VtValue &resource);
@@ -74,9 +76,11 @@ class HdCyclesRenderBuffer final : public PXR_NS::HdRenderBuffer {
   unsigned int _width = 0u;
   unsigned int _height = 0u;
   PXR_NS::HdFormat _format = PXR_NS::HdFormatInvalid;
+  size_t _dataSize = 0;
 
   std::vector<uint8_t> _data;
   PXR_NS::VtValue _resource;
+  mutable std::atomic_bool _resourceUsed = false;
 
   std::atomic_int _mapped = 0;
   std::atomic_bool _converged = false;



More information about the Bf-blender-cvs mailing list