Merge pull request #2564 from marsupial/MR/opengl+vulkan-interop
authorpixar-oss <pixar-oss@users.noreply.github.com>
Tue, 19 Dec 2023 23:52:10 +0000 (15:52 -0800)
committerpixar-oss <pixar-oss@users.noreply.github.com>
Tue, 19 Dec 2023 23:52:10 +0000 (15:52 -0800)
Support both OpenGL and Vulkan Hgi from single build.

(Internal change: 2309483)

1  2 
cmake/defaults/Packages.cmake
pxr/imaging/hgiInterop/CMakeLists.txt
pxr/imaging/hgiInterop/hgiInterop.cpp
pxr/imaging/hgiInterop/hgiInterop.h

index c782245b8032604a2a4b0fad5822f872eb523091,2bb1f30d0fceaaea4b0b13337d2485c72a84bf8f..e17fb863af73defcae8228cb153b17a6f0fabd77
@@@ -231,11 -226,7 +231,12 @@@ if (PXR_BUILD_IMAGING
          if (POLICY CMP0072)
              cmake_policy(SET CMP0072 OLD)
          endif()
 -        find_package(OpenGL REQUIRED)
 +        if (APPLE)
 +            set(OPENGL_gl_LIBRARY "-framework OpenGL")
 +        else ()
 +            find_package(OpenGL REQUIRED)
 +        endif()
++        add_definitions(-DPXR_GL_SUPPORT_ENABLED)
      endif()
      # --Metal
      if (PXR_ENABLE_METAL_SUPPORT)
index b2845be163eb133a639a934d467bc6a2d8c22b86,3ede7084e6ce656932640ffa91034509d475acb0..64ebfcb9ed25d3045567784b9b871d88151d5c12
@@@ -14,19 -14,22 +14,22 @@@ set(optionalPrivateHeaders ""
  # Destination of hgiInterop is always OpenGL, so always include garch
  list(APPEND optionalLibraries garch)
  
 -if (PXR_ENABLE_METAL_SUPPORT)
 -    add_compile_options(-x objective-c++)
 -    FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo)
 -    list(APPEND optionalLibraries ${COREVIDEO_LIBRARY} hgiMetal)
 -    list(APPEND optionalCppFiles metal.mm)
 -    list(APPEND optionalPrivateHeaders metal.h)
 -else()
 -    # No OpenGL-to-OpenGL interop when using Metal.
++if (PXR_ENABLE_GL_SUPPORT)
+     list(APPEND optionalCppFiles opengl.cpp)
+     list(APPEND optionalPrivateHeaders opengl.h)
+ endif()
+ if (PXR_ENABLE_VULKAN_SUPPORT)
++    list(APPEND optionalLibraries hgiVulkan)
+     list(APPEND optionalCppFiles vulkan.cpp)
+     list(APPEND optionalPrivateHeaders vulkan.h)
 -    list(APPEND optionalLibraries hgiVulkan)
++endif()
++
 +if (PXR_ENABLE_METAL_SUPPORT)
 +    add_compile_options(-x objective-c++)
 +    list(APPEND optionalLibraries "-framework CoreVideo" hgiMetal)
 +    list(APPEND optionalCppFiles metal.mm)
 +    list(APPEND optionalPrivateHeaders metal.h)
- elseif(PXR_ENABLE_VULKAN_SUPPORT)
-     list(APPEND optionalLibraries hgiVulkan)
-     list(APPEND optionalCppFiles vulkan.cpp)
-     list(APPEND optionalPrivateHeaders vulkan.h)
- else()
-     # No OpenGL-to-OpenGL interop when using Vulkan or Metal.
-     list(APPEND optionalCppFiles opengl.cpp)
-     list(APPEND optionalPrivateHeaders opengl.h)
  endif()
  
  pxr_library(hgiInterop
index 63748bc77f11df0130c1fd8dcad4abfc38a2c3e9,3d44c50c8d1ac7391deafe4174f2753bf9d87010..d1437edcccfbb454bbc2d8de8339f4e34c829561
  #include "pxr/imaging/hgi/hgi.h"
  #include "pxr/imaging/hgi/tokens.h"
  
 -
 -#if defined(PXR_METAL_SUPPORT_ENABLED)
 -    #include "pxr/imaging/hgiMetal/hgi.h"
 -    #include "pxr/imaging/hgiInterop/metal.h"
 -#else
 -    #include "pxr/imaging/hgiInterop/opengl.h"
++#if defined(PXR_GL_SUPPORT_ENABLED)
++#include "pxr/imaging/hgiInterop/opengl.h"
+ #endif
++
+ #if defined(PXR_VULKAN_SUPPORT_ENABLED)
 -    #include "pxr/imaging/hgiVulkan/hgi.h"
 -    #include "pxr/imaging/hgiInterop/vulkan.h"
++#include "pxr/imaging/hgiInterop/vulkan.h"
++#endif
 +
 +#if defined(PXR_METAL_SUPPORT_ENABLED)
-     #include "pxr/imaging/hgiMetal/hgi.h"
-     #include "pxr/imaging/hgiInterop/metal.h"
- #elif defined(PXR_VULKAN_SUPPORT_ENABLED)
-     #include "pxr/imaging/hgiVulkan/hgi.h"
-     #include "pxr/imaging/hgiInterop/vulkan.h"
- #else
-     #include "pxr/imaging/hgiInterop/opengl.h"
++#include "pxr/imaging/hgiMetal/hgi.h"
++#include "pxr/imaging/hgiInterop/metal.h"
  #endif
  
  PXR_NAMESPACE_OPEN_SCOPE
  
--HgiInterop::HgiInterop() = default;
++struct HgiInteropImpl
++{
++#if defined(PXR_GL_SUPPORT_ENABLED)
++    std::unique_ptr<HgiInteropOpenGL> _openGLToOpenGL;
++#endif
++#if defined(PXR_VULKAN_SUPPORT_ENABLED)
++    std::unique_ptr<HgiInteropVulkan> _vulkanToOpenGL;
++#endif
++#if defined(PXR_METAL_SUPPORT_ENABLED)
++    std::unique_ptr<HgiInteropMetal> _metalToOpenGL;
++#endif
++};
++
++HgiInterop::HgiInterop() 
++ : _hgiInteropImpl(std::make_unique<HgiInteropImpl>())
++{}
  
  HgiInterop::~HgiInterop() = default;
  
@@@ -52,40 -53,43 +69,57 @@@ void HgiInterop::TransferToApp
  {
      TfToken const& srcApi = srcHgi->GetAPIName();
  
- #if defined(PXR_METAL_SUPPORT_ENABLED)
-     if (srcApi==HgiTokens->Metal && dstApi==HgiTokens->OpenGL) {
-         // Transfer Metal textures to OpenGL application
-         if (!_metalToOpenGL) {
-             _metalToOpenGL = std::make_unique<HgiInteropMetal>(srcHgi);
+     if (dstApi != HgiTokens->OpenGL) {
 -        TF_CODING_ERROR("Unsupported destination Hgi backend: %s", dstApi.GetText());
++        TF_CODING_ERROR("Unsupported destination Hgi backend: %s",
++                        dstApi.GetText());
+         return;
+     }
 -#if defined(PXR_METAL_SUPPORT_ENABLED)
 -    if (srcApi==HgiTokens->Metal) {
 -        // Transfer Metal textures to OpenGL application
 -        if (!_metalToOpenGL) {
 -            _metalToOpenGL = std::make_unique<HgiInteropMetal>(srcHgi);
 -        }
 -        return _metalToOpenGL->CompositeToInterop(
 -            srcColor, srcDepth, dstFramebuffer, dstRegion);
 -    }
 -#else
 -    if (srcApi==HgiTokens->OpenGL) {
++#if defined(PXR_GL_SUPPORT_ENABLED)
++    if (srcApi == HgiTokens->OpenGL) {
+         // Transfer OpenGL textures to OpenGL application
 -        if (!_openGLToOpenGL) {
 -            _openGLToOpenGL = std::make_unique<HgiInteropOpenGL>();
++        if (!_hgiInteropImpl->_openGLToOpenGL) {
++            _hgiInteropImpl->_openGLToOpenGL =
++                std::make_unique<HgiInteropOpenGL>();
          }
-         _metalToOpenGL->CompositeToInterop(
 -        return _openGLToOpenGL->CompositeToInterop(
++        return _hgiInteropImpl->_openGLToOpenGL->CompositeToInterop(
              srcColor, srcDepth, dstFramebuffer, dstRegion);
-     } else {
-         TF_CODING_ERROR("Unsupported Hgi backend: %s", srcApi.GetText());
      }
- #elif defined(PXR_VULKAN_SUPPORT_ENABLED)
-     if (srcApi==HgiTokens->Vulkan && dstApi==HgiTokens->OpenGL) {
+ #endif
+ #if defined(PXR_VULKAN_SUPPORT_ENABLED)
 -    if (srcApi==HgiTokens->Vulkan) {
++    if (srcApi == HgiTokens->Vulkan) {
          // Transfer Vulkan textures to OpenGL application
--        if (!_vulkanToOpenGL) {
--            _vulkanToOpenGL = std::make_unique<HgiInteropVulkan>(srcHgi);
++        // XXX: It's possible that if we use the same HgiInterop with a 
++        // different Hgi instance passed to this function, HgiInteropVulkan 
++        // will have the wrong Hgi instance since we wouldn't recreate it here.
++        // We should fix this.
++        if (!_hgiInteropImpl->_vulkanToOpenGL) {
++            _hgiInteropImpl->_vulkanToOpenGL =
++                std::make_unique<HgiInteropVulkan>(srcHgi);
 +        }
-         _vulkanToOpenGL->CompositeToInterop(
++        return _hgiInteropImpl->_vulkanToOpenGL->CompositeToInterop(
 +            srcColor, srcDepth, dstFramebuffer, dstRegion);
-     } else {
-         TF_CODING_ERROR("Unsupported Hgi backend: %s", srcApi.GetText());
 +    }
- #else
-     if (srcApi==HgiTokens->OpenGL && dstApi==HgiTokens->OpenGL) {
-         // Transfer OpenGL textures to OpenGL application
-         if (!_openGLToOpenGL) {
-             _openGLToOpenGL = std::make_unique<HgiInteropOpenGL>();
++#endif
++
++#if defined(PXR_METAL_SUPPORT_ENABLED)
++    if (srcApi == HgiTokens->Metal) {
++        // Transfer Metal textures to OpenGL application
++        // XXX: It's possible that if we use the same HgiInterop with a 
++        // different Hgi instance passed to this function, HgiInteropMetal 
++        // will have the wrong Hgi instance since we wouldn't recreate it here.
++        // We should fix this.
++        if (!_hgiInteropImpl->_metalToOpenGL) {
++            _hgiInteropImpl->_metalToOpenGL =
++                std::make_unique<HgiInteropMetal>(srcHgi);
          }
-         _openGLToOpenGL->CompositeToInterop(
 -        return _vulkanToOpenGL->CompositeToInterop(
++        return _hgiInteropImpl->_metalToOpenGL->CompositeToInterop(
              srcColor, srcDepth, dstFramebuffer, dstRegion);
-     } else {
-         TF_CODING_ERROR("Unsupported Hgi backend: %s", srcApi.GetText());
      }
  #endif
+     TF_CODING_ERROR("Unsupported source Hgi backend: %s", srcApi.GetText());
  }
  
  PXR_NAMESPACE_CLOSE_SCOPE
index eb7ddfdf379ee9696bf559798d3e51a40041c849,c8c617efd9008a1870f6e5640ec6851471f6b624..0c233bb9f927bcf8869c6e23552d59e0e0c45399
  PXR_NAMESPACE_OPEN_SCOPE
  
  class Hgi;
--class HgiInteropMetal;
--class HgiInteropOpenGL;
--class HgiInteropVulkan;
  class VtValue;
  
++struct HgiInteropImpl;
++
  /// \class HgiInterop
  ///
  /// Hydra Graphics Interface Interop.
@@@ -100,13 -100,14 +99,7 @@@ private
      HgiInterop & operator=(const HgiInterop&) = delete;
      HgiInterop(const HgiInterop&) = delete;
  
--#if defined(PXR_METAL_SUPPORT_ENABLED)
--    std::unique_ptr<HgiInteropMetal> _metalToOpenGL;
- #elif defined(PXR_VULKAN_SUPPORT_ENABLED)
-     std::unique_ptr<HgiInteropVulkan> _vulkanToOpenGL;
--#else
--    std::unique_ptr<HgiInteropOpenGL> _openGLToOpenGL;
 -#endif
 -#if defined(PXR_VULKAN_SUPPORT_ENABLED)
 -    std::unique_ptr<HgiInteropVulkan> _vulkanToOpenGL;
--#endif
++    std::unique_ptr<HgiInteropImpl> _hgiInteropImpl;
  };