diff --git a/Package.swift b/Package.swift index 82dc6c542..abd41e0d1 100644 --- a/Package.swift +++ b/Package.swift @@ -193,6 +193,10 @@ let package = Package( name: "HdSt", targets: ["HdSt"] ), + .library( + name: "HdStorm", + targets: ["HdStorm"] + ), .library( name: "Hdx", targets: ["Hdx"] @@ -1209,6 +1213,7 @@ let package = Package( .target(name: "Tf"), .target(name: "Trace"), .target(name: "Hgi"), + .target(name: "Vt"), ], resources: [ .process("Resources") @@ -1432,6 +1437,7 @@ let package = Package( .target(name: "Hd"), .target(name: "HdSi"), .target(name: "HgiGL", condition: .when(platforms: Arch.OS.noembeddedapple.platform)), + .target(name: "HgiMetal", condition: .when(platforms: Arch.OS.apple.platform)), .target(name: "HgiInterop"), .target(name: "Sdr"), .target(name: "Arch"), @@ -1454,6 +1460,30 @@ let package = Package( ] ), + .target( + name: "HdStorm", + dependencies: [ + .target(name: "Arch"), + .target(name: "Tf"), + .target(name: "Plug"), + .target(name: "Trace"), + .target(name: "Vt"), + .target(name: "Work"), + .target(name: "Hd"), + .target(name: "HdSt", condition: .when(platforms: Arch.OS.noembeddedapple.platform)), + ], + resources: [ + .process("Resources") + ], + cxxSettings: [ + .define("MFB_PACKAGE_NAME", to: "HdStorm"), + .define("MFB_ALT_PACKAGE_NAME", to: "HdStorm"), + .define("MFB_PACKAGE_MODULE", to: "HdStorm"), + .define("HDSTORM_EXPORTS", to: "1"), + .define("_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH", .when(platforms: [.windows])), + ] + ), + .target( name: "Hdx", dependencies: [ @@ -1742,6 +1772,7 @@ let package = Package( .target(name: "HdMtlx"), .target(name: "HdSi"), .target(name: "HdSt", condition: .when(platforms: Arch.OS.noembeddedapple.platform)), + .target(name: "HdStorm", condition: .when(platforms: Arch.OS.noembeddedapple.platform)), .target(name: "Hdx", condition: .when(platforms: Arch.OS.noembeddedapple.platform)), .target(name: "Hgi"), .target(name: "HgiMetal", condition: .when(platforms: Arch.OS.apple.platform)), diff --git a/Sources/HdSt/include/HdSt/basisCurvesComputations.h b/Sources/HdSt/include/HdSt/basisCurvesComputations.h index 672fde8c0..bc44919ae 100644 --- a/Sources/HdSt/include/HdSt/basisCurvesComputations.h +++ b/Sources/HdSt/include/HdSt/basisCurvesComputations.h @@ -240,7 +240,7 @@ class HdSt_BasisCurvesPrimvarInterpolaterComputation : public HdComputedBufferSo << "(need " << numVertsExpected << ", got " << authoredSize << "), using fallback value " << _fallbackValue << " for rendering."; - TF_WARN(s.str()); + TF_WARN("%s", s.str().c_str()); } } else if (_interpolation == HdInterpolationVarying) { @@ -277,7 +277,7 @@ class HdSt_BasisCurvesPrimvarInterpolaterComputation : public HdComputedBufferSo << "(need " << numVaryingExpected << ", got " << authoredSize << "), using fallback value " << _fallbackValue << " for rendering."; - TF_WARN(s.str()); + TF_WARN("%s", s.str().c_str()); } } diff --git a/Sources/HdSt/include/HdSt/renderDelegate.h b/Sources/HdSt/include/HdSt/renderDelegate.h index 36380f6d6..13e4dbaeb 100644 --- a/Sources/HdSt/include/HdSt/renderDelegate.h +++ b/Sources/HdSt/include/HdSt/renderDelegate.h @@ -10,6 +10,8 @@ #include "HdSt/api.h" #include "pxr/pxrns.h" +#include "Arch/defines.h" + #include #include @@ -46,6 +48,11 @@ class HdStRenderDelegate final : public HdRenderDelegate { HDST_API void SetDrivers(HdDriverVector const &drivers) override; +#if defined(ARCH_OS_DARWIN) + HDST_API + bool GetHgiFromMetalDriver(HdDriver *hdDriver); +#endif // defined(ARCH_OS_DARWIN) + HDST_API HdRenderParam *GetRenderParam() const override; diff --git a/Sources/HdSt/renderDelegate.cpp b/Sources/HdSt/renderDelegate.cpp index 42f4c09af..c64a6ef04 100644 --- a/Sources/HdSt/renderDelegate.cpp +++ b/Sources/HdSt/renderDelegate.cpp @@ -212,6 +212,11 @@ void HdStRenderDelegate::SetDrivers(HdDriverVector const &drivers) _hgi = hdDriver->driver.UncheckedGet(); break; } +#if defined(ARCH_OS_DARWIN) + if (GetHgiFromMetalDriver(hdDriver)) { + break; + } +#endif } TF_VERIFY(_hgi, "HdSt requires Hgi HdDriver"); diff --git a/Sources/HdSt/renderDelegate.mm b/Sources/HdSt/renderDelegate.mm new file mode 100644 index 000000000..281584dd3 --- /dev/null +++ b/Sources/HdSt/renderDelegate.mm @@ -0,0 +1,23 @@ +#include "pxr/pxrns.h" +#include "Arch/defines.h" + +#if defined(ARCH_OS_DARWIN) +# include "HdSt/renderDelegate.h" +# include "Hd/driver.h" +# include "HgiMetal/hgi.h" + +PXR_NAMESPACE_OPEN_SCOPE + +bool HdStRenderDelegate::GetHgiFromMetalDriver(HdDriver *hdDriver) +{ + if (hdDriver->name == HgiTokens->renderDriver && hdDriver->driver.IsHolding()) { + _hgi = hdDriver->driver.UncheckedGet(); + return true; + } + + return false; +} + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // defined(ARCH_OS_DARWIN) diff --git a/Sources/HdStorm/Resources/plugInfo.json b/Sources/HdStorm/Resources/plugInfo.json new file mode 100644 index 000000000..d7b995395 --- /dev/null +++ b/Sources/HdStorm/Resources/plugInfo.json @@ -0,0 +1,22 @@ +{ + "Plugins": [ + { + "Info": { + "Types": { + "HdStormRendererPlugin": { + "bases": [ + "HdRendererPlugin" + ], + "displayName": "GL", + "priority": 0 + } + } + }, + "LibraryPath": "", + "Name": "HdStorm", + "ResourcePath": "Contents/Resources", + "Root": "../..", + "Type": "library" + } + ] +} diff --git a/Sources/HdStorm/include/HdStorm/HdStorm.h b/Sources/HdStorm/include/HdStorm/HdStorm.h new file mode 100644 index 000000000..b83cada8a --- /dev/null +++ b/Sources/HdStorm/include/HdStorm/HdStorm.h @@ -0,0 +1,6 @@ +#ifndef __PXR_IMAGING_PLUGIN_HD_STORM_H__ +#define __PXR_IMAGING_PLUGIN_HD_STORM_H__ + +#include + +#endif // __PXR_IMAGING_PLUGIN_HD_STORM_H__ diff --git a/Sources/HdStorm/include/HdStorm/rendererPlugin.h b/Sources/HdStorm/include/HdStorm/rendererPlugin.h new file mode 100644 index 000000000..3e962c349 --- /dev/null +++ b/Sources/HdStorm/include/HdStorm/rendererPlugin.h @@ -0,0 +1,35 @@ +// +// Copyright 2017 Pixar +// +// Licensed under the terms set forth in the LICENSE.txt file available at +// https://openusd.org/license. +// +#ifndef PXR_IMAGING_PLUGIN_HD_STORM_RENDERER_PLUGIN_H +#define PXR_IMAGING_PLUGIN_HD_STORM_RENDERER_PLUGIN_H + +#include "pxr/pxrns.h" +#include "Hd/rendererPlugin.h" + +PXR_NAMESPACE_OPEN_SCOPE + +class HdStormRendererPlugin final : public HdRendererPlugin +{ + public: + HdStormRendererPlugin() = default; + virtual ~HdStormRendererPlugin() = default; + + virtual HdRenderDelegate *CreateRenderDelegate() override; + virtual HdRenderDelegate *CreateRenderDelegate(HdRenderSettingsMap const &settingsMap) override; + + virtual void DeleteRenderDelegate(HdRenderDelegate *renderDelegate) override; + + virtual bool IsSupported(bool gpuEnabled = true) const override; + + private: + HdStormRendererPlugin(const HdStormRendererPlugin &) = delete; + HdStormRendererPlugin &operator=(const HdStormRendererPlugin &) = delete; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // PXR_IMAGING_PLUGIN_HD_STORM_RENDERER_PLUGIN_H diff --git a/Sources/HdStorm/rendererPlugin.cpp b/Sources/HdStorm/rendererPlugin.cpp new file mode 100644 index 000000000..d443226fa --- /dev/null +++ b/Sources/HdStorm/rendererPlugin.cpp @@ -0,0 +1,46 @@ +// +// Copyright 2017 Pixar +// +// Licensed under the terms set forth in the LICENSE.txt file available at +// https://openusd.org/license. +// +#include "pxr/pxrns.h" +#include "HdStorm/rendererPlugin.h" + +#include "HdSt/renderDelegate.h" +#include "Hd/rendererPluginRegistry.h" + +PXR_NAMESPACE_OPEN_SCOPE + +TF_REGISTRY_FUNCTION(TfType) +{ + HdRendererPluginRegistry::Define(); +} + +HdRenderDelegate *HdStormRendererPlugin::CreateRenderDelegate() +{ + return new HdStRenderDelegate(); +} + +HdRenderDelegate *HdStormRendererPlugin::CreateRenderDelegate(HdRenderSettingsMap const &settingsMap) +{ + return new HdStRenderDelegate(settingsMap); +} + +void HdStormRendererPlugin::DeleteRenderDelegate(HdRenderDelegate *renderDelegate) +{ + delete renderDelegate; +} + +bool HdStormRendererPlugin::IsSupported(bool gpuEnabled) const +{ + const bool support = gpuEnabled && HdStRenderDelegate::IsSupported(); + if (!support) { + TF_DEBUG(HD_RENDERER_PLUGIN) + .Msg("hdStorm renderer plugin unsupported: %s\n", + gpuEnabled ? "hgi unsupported" : "no gpu"); + } + return support; +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/HgiMetal/hgi.mm b/Sources/HgiMetal/hgi.mm index 18ee7f9a1..719c2db44 100644 --- a/Sources/HgiMetal/hgi.mm +++ b/Sources/HgiMetal/hgi.mm @@ -168,6 +168,11 @@ void Drain() {} return hgi; } +VtValue HgiMetal::GetValue(HgiMetalPtr ptr) const +{ + return VtValue(ptr.get()); +} + bool HgiMetal::IsBackendSupported() const { diff --git a/Sources/HgiMetal/include/HgiMetal/hgi.h b/Sources/HgiMetal/include/HgiMetal/hgi.h index 7828bf3a4..de46cb6bc 100644 --- a/Sources/HgiMetal/include/HgiMetal/hgi.h +++ b/Sources/HgiMetal/include/HgiMetal/hgi.h @@ -14,6 +14,7 @@ #include "HgiMetal/api.h" #include "HgiMetal/capabilities.h" #include "HgiMetal/indirectCommandEncoder.h" +#include "Vt/value.h" #include "pxr/pxrns.h" #import @@ -46,6 +47,9 @@ class HgiMetal final : public Hgi { HGIMETAL_API static HgiMetalPtr CreateHgi(); + HGIMETAL_API + VtValue GetValue(HgiMetalPtr ptr) const; + HGIMETAL_API bool IsBackendSupported() const override; diff --git a/Sources/PixarUSD/Bundle.swift b/Sources/PixarUSD/Bundle.swift index 2fe2a397a..cc7067f74 100644 --- a/Sources/PixarUSD/Bundle.swift +++ b/Sources/PixarUSD/Bundle.swift @@ -162,6 +162,10 @@ public extension Bundle * Where ``HdSt`` application bundle resources are located. */ static let hdSt = Bundle(path: "\(pxrRoot)/SwiftUSD_HdSt\(ext)") + /** + * Where ``HdStorm`` application bundle resources are located. */ + static let hdStorm = Bundle(path: "\(pxrRoot)/SwiftUSD_HdStorm\(ext)") + /** * Where ``Hdx`` application bundle resources are located. */ static let hdx = Bundle(path: "\(pxrRoot)/SwiftUSD_Hdx\(ext)") @@ -441,6 +445,7 @@ public enum BundleFramework: CaseIterable case hgiVulkan case hgiGL case hdSt + case hdStorm case hdx case hio case glf @@ -477,6 +482,7 @@ public enum BundleFramework: CaseIterable case .hgiVulkan: Bundle.hgiVulkan?.resourcePath case .hgiGL: Bundle.hgiGL?.resourcePath case .hdSt: Bundle.hdSt?.resourcePath + case .hdStorm: Bundle.hdStorm?.resourcePath case .hdx: Bundle.hdx?.resourcePath case .hio: Bundle.hio?.resourcePath case .glf: Bundle.glf?.resourcePath diff --git a/Sources/PixarUSD/Imaging/Hd/AovTokens.swift b/Sources/PixarUSD/Imaging/Hd/AovTokens.swift new file mode 100644 index 000000000..4344188ca --- /dev/null +++ b/Sources/PixarUSD/Imaging/Hd/AovTokens.swift @@ -0,0 +1,83 @@ +/* ---------------------------------------------------------------- + * :: : M E T A V E R S E : :: + * ---------------------------------------------------------------- + * Licensed under the terms set forth in the LICENSE.txt file, this + * file is available at https://openusd.org/license. + * + * Copyright (C) 2016 Pixar. + * Copyright (C) 2024 Wabi Foundation. All Rights Reserved. + * ---------------------------------------------------------------- + * . x x x . o o o . x x x . : : : . o x o . : : : . + * ---------------------------------------------------------------- */ + +import Hd + +private extension Hd +{ + /** + * Private struct to hold the static + * data for the Hd library's AOV tokens. */ + struct AovStaticData + { + static let shared = AovStaticData() + private init() + {} + + let tokens = Pixar.HdAovTokens_StaticTokenType() + } +} + +public extension Hd +{ + /** + * # Hd.AovTokens + * + * ## Overview + * + * Public, client facing api to access + * the static Hd AOV tokens. */ + enum AovTokens: String, CaseIterable + { + case color + case depth + case depthStencil + case cameraDepth + case primId + case instanceId + case elementId + case edgeId + case pointId + case pEye + case nEye + case patchCoord + case primitiveParam + case normal + case primvars = "primvars:" + case lpe = "lpe:" + case shader = "shader:" + + public var token: Tf.Token + { + switch self + { + case .color: AovStaticData.shared.tokens.color + case .depth: AovStaticData.shared.tokens.depth + case .depthStencil: AovStaticData.shared.tokens.depthStencil + case .cameraDepth: AovStaticData.shared.tokens.cameraDepth + case .primId: AovStaticData.shared.tokens.primId + case .instanceId: AovStaticData.shared.tokens.instanceId + case .elementId: AovStaticData.shared.tokens.elementId + case .edgeId: AovStaticData.shared.tokens.edgeId + case .pointId: AovStaticData.shared.tokens.pointId + case .pEye: AovStaticData.shared.tokens.Peye + case .nEye: AovStaticData.shared.tokens.Neye + case .patchCoord: AovStaticData.shared.tokens.patchCoord + case .primitiveParam: AovStaticData.shared.tokens.primitiveParam + case .normal: AovStaticData.shared.tokens.normal + case .primvars: AovStaticData.shared.tokens.primvars + case .lpe: AovStaticData.shared.tokens.lpe + case .shader: AovStaticData.shared.tokens.shader + } + } + } +} diff --git a/Sources/PixarUSD/Imaging/Hgi/HgiTokens.swift b/Sources/PixarUSD/Imaging/Hgi/HgiTokens.swift index f63656eef..4c82d1b88 100644 --- a/Sources/PixarUSD/Imaging/Hgi/HgiTokens.swift +++ b/Sources/PixarUSD/Imaging/Hgi/HgiTokens.swift @@ -38,13 +38,21 @@ public extension Hgi * the static ``Hgi`` tokens. */ enum Tokens: CaseIterable { + case taskDriver case renderDriver + case openGL + case metal + case vulkan public var token: Tf.Token { switch self { + case .taskDriver: StaticData.shared.tokens.taskDriver case .renderDriver: StaticData.shared.tokens.renderDriver + case .openGL: StaticData.shared.tokens.OpenGL + case .metal: StaticData.shared.tokens.Metal + case .vulkan: StaticData.shared.tokens.Vulkan } } } diff --git a/Sources/PixarUSD/Imaging/HgiMetal/HgiMetal.swift b/Sources/PixarUSD/Imaging/HgiMetal/HgiMetal.swift index f1c62b673..123ab8398 100644 --- a/Sources/PixarUSD/Imaging/HgiMetal/HgiMetal.swift +++ b/Sources/PixarUSD/Imaging/HgiMetal/HgiMetal.swift @@ -38,6 +38,11 @@ { GetPrimaryDeviceCopy() } + + func getValue(_ ptr: Pixar.HgiMetalPtr) -> VtValue + { + GetValue(ptr) + } } public extension Pixar.HgiMetalPtr @@ -51,5 +56,10 @@ { pointee.device } + + var value: VtValue + { + pointee.getValue(self) + } } #endif /* canImport(Metal) */ diff --git a/Sources/PixarUSD/Usd/Sdf/Path.swift b/Sources/PixarUSD/Usd/Sdf/Path.swift index 6ba25eae7..ce5d446e9 100644 --- a/Sources/PixarUSD/Usd/Sdf/Path.swift +++ b/Sources/PixarUSD/Usd/Sdf/Path.swift @@ -28,6 +28,21 @@ public extension Sdf.Path self.init(std.string(path)) } + static func emptyPath() -> Sdf.Path + { + Sdf.Path.EmptyPath().pointee + } + + static func absoluteRootPath() -> Sdf.Path + { + Sdf.Path.AbsoluteRootPath().pointee + } + + static func reflexiveRelativePath() -> Sdf.Path + { + Sdf.Path.ReflexiveRelativePath().pointee + } + private borrowing func GetNameCopy() -> std.string { __GetNameUnsafe().pointee diff --git a/Sources/PixarUSD/UsdImaging/UsdImagingGLEngine/UsdImagingGLEngine.swift b/Sources/PixarUSD/Usd/Sdf/PathVector.swift similarity index 80% rename from Sources/PixarUSD/UsdImaging/UsdImagingGLEngine/UsdImagingGLEngine.swift rename to Sources/PixarUSD/Usd/Sdf/PathVector.swift index 3394082da..eda36ff34 100644 --- a/Sources/PixarUSD/UsdImaging/UsdImagingGLEngine/UsdImagingGLEngine.swift +++ b/Sources/PixarUSD/Usd/Sdf/PathVector.swift @@ -10,9 +10,13 @@ * . x x x . o o o . x x x . : : : . o x o . : : : . * ---------------------------------------------------------------- */ -#if canImport(UsdImagingGLEngine) - import UsdImagingGLEngine +import CxxStdlib +import Foundation +import Sdf - public enum UsdImagingGLEngine - {} -#endif // canImport(UsdImagingGLEngine) +public typealias SdfPathVector = Pixar.SdfPathVector + +public extension Sdf +{ + typealias PathVector = SdfPathVector +} diff --git a/Sources/PixarUSD/Usd/Usd/Stage.swift b/Sources/PixarUSD/Usd/Usd/Stage.swift index 8ddd1c1c9..5860a06fa 100644 --- a/Sources/PixarUSD/Usd/Usd/Stage.swift +++ b/Sources/PixarUSD/Usd/Usd/Stage.swift @@ -170,6 +170,56 @@ public extension Usd.Stage Usd.Stage.CreateNew(std.string(identifier), load.rawValue) } + /** + * Creates a new stage only in memory, analogous to creating an anonymous + * ``Pixar/Sdf/Layer``. + * + * If `pathResolverContext` is provided it will be bound when creating the + * root layer at `identifier` and whenever asset path resolution is done + * for this stage, regardless of what other context may be bound at that + * time. Otherwise Usd will create the root layer with no context bound, + * then create a context for all future asset path resolution for the stage + * by calling ``ArResolver/createDefaultContext``. + * + * The initial set of prims to load on the stage can be specified + * using the `load` parameter. see ``InitialLoadingSet`` for more + * options. + * + * Invoking an overload that does not take a `sessionLayer` argument will + * create a stage with an anonymous in-memory session layer. To create a + * stage without a session layer, pass `Tf/NullPtr` (or None in python) as + * the `sessionLayer` argument. */ + @discardableResult + static func createInMemory(load: InitialLoadingSet = .all) -> UsdStageRefPtr + { + Usd.Stage.CreateInMemory(load.rawValue) + } + + /** + * Creates a new stage only in memory, analogous to creating an anonymous + * ``Pixar/Sdf/Layer``. + * + * If `pathResolverContext` is provided it will be bound when creating the + * root layer at `identifier` and whenever asset path resolution is done + * for this stage, regardless of what other context may be bound at that + * time. Otherwise Usd will create the root layer with no context bound, + * then create a context for all future asset path resolution for the stage + * by calling ``ArResolver/createDefaultContext``. + * + * The initial set of prims to load on the stage can be specified + * using the `load` parameter. see ``InitialLoadingSet`` for more + * options. + * + * Invoking an overload that does not take a `sessionLayer` argument will + * create a stage with an anonymous in-memory session layer. To create a + * stage without a session layer, pass `Tf/NullPtr` (or None in python) as + * the `sessionLayer` argument. */ + @discardableResult + static func createInMemory(_ identifier: String, load: InitialLoadingSet = .all) -> UsdStageRefPtr + { + Usd.Stage.CreateInMemory(std.string(identifier), load.rawValue) + } + /** * Attempt to find a matching existing stage in a cache if * ``UsdStageCacheContext`` objects exist on the stack. Failing that, create @@ -177,7 +227,8 @@ public extension Usd.Stage * the layer at `filePath`, which must already exist. * * The initial set of prims to load on the stage can be specified - * using the `load` parameter. ``UsdStage.InitialLoadingSet``. + * using the `load` parameter. see ``InitialLoadingSet`` for more + * options. * * If `pathResolverContext` is provided it will be bound when opening the * root layer at `filePath` and whenever asset path resolution is done for @@ -199,7 +250,8 @@ public extension Usd.Stage * the layer at `filePath`, which must already exist. * * The initial set of prims to load on the stage can be specified - * using the `load` parameter. ``UsdStage.InitialLoadingSet``. + * using the `load` parameter. see ``InitialLoadingSet`` for more + * options. * * If `pathResolverContext` is provided it will be bound when opening the * root layer at `filePath` and whenever asset path resolution is done for diff --git a/Sources/PixarUSD/UsdImaging/UsdImagingGL/Engine.swift b/Sources/PixarUSD/UsdImaging/UsdImagingGL/Engine.swift new file mode 100644 index 000000000..0c2b49e2f --- /dev/null +++ b/Sources/PixarUSD/UsdImaging/UsdImagingGL/Engine.swift @@ -0,0 +1,85 @@ +/* ---------------------------------------------------------------- + * :: : M E T A V E R S E : :: + * ---------------------------------------------------------------- + * Licensed under the terms set forth in the LICENSE.txt file, this + * file is available at https://openusd.org/license. + * + * Copyright (C) 2016 Pixar. + * Copyright (C) 2024 Wabi Foundation. All Rights Reserved. + * ---------------------------------------------------------------- + * . x x x . o o o . x x x . : : : . o x o . : : : . + * ---------------------------------------------------------------- */ + +#if canImport(UsdImagingGL) + import UsdImagingGL + + public typealias UsdImagingGLEngine = Pixar.UsdImagingGLEngine + public typealias UsdImagingGLEngineSharedPtr = Pixar.UsdImagingGLEngineSharedPtr + + public enum UsdImagingGL + { + public typealias Engine = UsdImagingGLEngine + public typealias EngineSharedPtr = UsdImagingGLEngineSharedPtr + } + + public extension UsdImagingGL.Engine + { + static func createEngine(params: Parameters) -> UsdImagingGL.EngineSharedPtr + { + UsdImagingGL.Engine.CreateEngine(params) + } + + static func createEngine(driver: HdDriver = HdDriver(name: Tf.Token(), driver: VtValue()), + rendererPluginId: Tf.Token = Tf.Token(), + gpuEnabled: Bool = true) -> UsdImagingGL.EngineSharedPtr + { + UsdImagingGL.Engine.CreateEngine(driver, rendererPluginId, gpuEnabled) + } + + static func createEngine(rootPath: Sdf.Path, + excludedPaths: Sdf.PathVector, + invisedPaths: Sdf.PathVector = Sdf.PathVector(), + sceneDelegateId: Sdf.Path = Sdf.Path.absoluteRootPath(), + driver: HdDriver = HdDriver(name: Tf.Token(), driver: VtValue()), + rendererPluginId: Tf.Token = Tf.Token(), + gpuEnabled: Bool = true, + displayUnloadedPrimsWithBounds: Bool = false, + allowAsynchronousSceneProcessing: Bool = false) -> UsdImagingGL.EngineSharedPtr + { + UsdImagingGL.Engine.CreateEngine( + rootPath, + excludedPaths, + invisedPaths, + sceneDelegateId, + driver, + rendererPluginId, + gpuEnabled, + displayUnloadedPrimsWithBounds, + allowAsynchronousSceneProcessing + ) + } + + func setEnablePresentation(_ value: Bool) + { + SetEnablePresentation(value) + } + + func setRenderer(aov: Hd.AovTokens) + { + SetRendererAov(aov.token) + } + } + + public extension UsdImagingGL.EngineSharedPtr + { + func setEnablePresentation(_ value: Bool) + { + pointee.setEnablePresentation(value) + } + + func setRenderer(aov token: Hd.AovTokens) + { + pointee.setRenderer(aov: token) + } + } +#endif // canImport(UsdImagingGLEngine) diff --git a/Sources/UsdImagingGL/engine.cpp b/Sources/UsdImagingGL/engine.cpp index 4b0d2e574..36033e64d 100644 --- a/Sources/UsdImagingGL/engine.cpp +++ b/Sources/UsdImagingGL/engine.cpp @@ -183,6 +183,56 @@ UsdImagingGLEngine::UsdImagingGLEngine(const SdfPath &rootPath, } } +// static. +UsdImagingGLEngineSharedPtr UsdImagingGLEngine::CreateEngine(const Parameters ¶ms) +{ + UsdImagingGLEngineSharedPtr engine = std::make_shared(); + + engine.reset(new UsdImagingGLEngine(params)); + + return engine; +} + +// static. +UsdImagingGLEngineSharedPtr UsdImagingGLEngine::CreateEngine(const HdDriver &driver, + const TfToken &rendererPluginId, + const bool gpuEnabled) +{ + UsdImagingGLEngineSharedPtr engine = std::make_shared(); + + engine.reset(new UsdImagingGLEngine(driver, rendererPluginId, gpuEnabled)); + + return engine; +} + +// static. +UsdImagingGLEngineSharedPtr UsdImagingGLEngine::CreateEngine(const SdfPath &rootPath, + const SdfPathVector &excludedPaths, + const SdfPathVector &invisedPaths, + const SdfPath &sceneDelegateID, + const HdDriver &driver, + const TfToken &rendererPluginId, + const bool gpuEnabled, + const bool displayUnloadedPrimsWithBounds, + const bool allowAsynchronousSceneProcessing) +{ + UsdImagingGLEngineSharedPtr engine = std::make_shared(); + + engine.reset(new UsdImagingGLEngine( + rootPath, + excludedPaths, + invisedPaths, + sceneDelegateID, + driver, + rendererPluginId, + gpuEnabled, + displayUnloadedPrimsWithBounds, + allowAsynchronousSceneProcessing + )); + + return engine; +} + void UsdImagingGLEngine::_DestroyHydraObjects() { // Destroy objects in opposite order of construction. diff --git a/Sources/UsdImagingGL/include/UsdImagingGL/engine.h b/Sources/UsdImagingGL/include/UsdImagingGL/engine.h index d675ee08c..24885fc99 100644 --- a/Sources/UsdImagingGL/include/UsdImagingGL/engine.h +++ b/Sources/UsdImagingGL/include/UsdImagingGL/engine.h @@ -10,6 +10,8 @@ #ifndef PXR_USD_IMAGING_USD_IMAGING_GL_ENGINE_H #define PXR_USD_IMAGING_USD_IMAGING_GL_ENGINE_H +#include "Arch/swiftInterop.h" + #include "UsdImaging/version.h" #include "UsdImagingGL/api.h" #include "UsdImagingGL/version.h" @@ -144,6 +146,32 @@ class UsdImagingGLEngine { /// @} + // --------------------------------------------------------------------- + /// \name Swift Creation + /// @{ + // --------------------------------------------------------------------- + + USDIMAGINGGL_API + static UsdImagingGLEngineSharedPtr CreateEngine(const Parameters ¶ms); + + USDIMAGINGGL_API + static UsdImagingGLEngineSharedPtr CreateEngine(const HdDriver &driver = HdDriver(), + const TfToken &rendererPluginId = TfToken(), + bool gpuEnabled = true); + + USDIMAGINGGL_API + static UsdImagingGLEngineSharedPtr CreateEngine(const SdfPath &rootPath, + const SdfPathVector &excludedPaths, + const SdfPathVector &invisedPaths = SdfPathVector(), + const SdfPath &sceneDelegateID = SdfPath::AbsoluteRootPath(), + const HdDriver &driver = HdDriver(), + const TfToken &rendererPluginId = TfToken(), + bool gpuEnabled = true, + bool displayUnloadedPrimsWithBounds = false, + bool allowAsynchronousSceneProcessing = false); + + /// @} + // --------------------------------------------------------------------- /// \name Rendering /// @{ @@ -775,7 +803,7 @@ class UsdImagingGLEngine { std::unique_ptr _engine; bool _allowAsynchronousSceneProcessing = false; -}; +} SWIFT_IMMORTAL_REFERENCE; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/UsdView/Hydra+MTLRenderer.swift b/Sources/UsdView/Hydra+MTLRenderer.swift index 28eb32e3c..991be45de 100644 --- a/Sources/UsdView/Hydra+MTLRenderer.swift +++ b/Sources/UsdView/Hydra+MTLRenderer.swift @@ -31,26 +31,36 @@ import PixarUSD class MTLRenderer: NSObject, MTKViewDelegate { let hgi: Pixar.HgiMetalPtr - // let engine: UsdImagingGLEngineSharedPtr - // let stage: UsdStageRefPtr + var device: MTLDevice! - public init?(device _: MTLDevice) + var stage: UsdStageRefPtr + var engine: UsdImagingGL.EngineSharedPtr + + public init(metalView: MTKView) { hgi = HgiMetal.createHgi() + device = hgi.device + stage = Usd.Stage.createInMemory() + + let driver = HdDriver(name: .renderDriver, driver: hgi.value) + engine = UsdImagingGL.Engine.createEngine( + rootPath: stage.getPseudoRoot().getPath(), + excludedPaths: Sdf.PathVector(), + invisedPaths: Sdf.PathVector(), + sceneDelegateId: Sdf.Path.absoluteRootPath(), + driver: driver + ) - // let excludedPaths = SdfPathVector() - let driver = HdDriver(name: .renderDriver, driver: VtValue(hgi)) + metalView.device = hgi.device + } - // engine.reset(UsdImagingGLEngineSharedPtr( - // stage.getPseudoRoot().getPath(), - // excludedPaths, - // SdfPathVector(), - // SdfPath.AbsoluteRootPath(), - // driver - // )) + public convenience init(stage: UsdStageRefPtr) + { + self.init(metalView: MTKView()) + self.stage = stage - // engine.SetEnablePresentation(false) - // engine.SetRendererAov(false) + engine.setEnablePresentation(false) + engine.setRenderer(aov: .color) } public func info() diff --git a/Sources/UsdView/UsdView.swift b/Sources/UsdView/UsdView.swift index 3a4b3d629..3adce4474 100644 --- a/Sources/UsdView/UsdView.swift +++ b/Sources/UsdView/UsdView.swift @@ -39,6 +39,8 @@ import PixarUSD @main struct UsdView: PixarApp { + let stage: UsdStageRefPtr + #if canImport(Metal) && !os(visionOS) let hydra: Hydra.MTLRenderer #endif /* canImport(Metal) && !os(visionOS) */ @@ -64,8 +66,10 @@ struct UsdView: PixarApp PyBundler.shared.pyInfo() #endif /* canImport(PyBundle) */ + stage = Usd.Stage.createNew("\(documentsDirPath())/HelloPixarUSD", ext: .usda) + #if canImport(Metal) && !os(visionOS) - hydra = Hydra.MTLRenderer(device: MTLCreateSystemDefaultDevice()!)! + hydra = Hydra.MTLRenderer(stage: stage) #endif /* canImport(Metal) && !os(visionOS) */ #if canImport(SwiftUI) @@ -109,8 +113,6 @@ struct UsdView: PixarApp /* Create stage with a sphere, capsule, cylinder, cube, and cone on a transform. */ - let stage = Usd.Stage.createNew("\(documentsDirPath())/HelloPixarUSD", ext: .usda) - let xform = UsdGeom.Xform.define(stage, path: "/Geometry") xform.addXformOp(type: .translate).set(GfVec3d(0.0, 5.0, 0.0)) xform.addXformOp(type: .scale, precision: .float).set(GfVec3f(5, 5, 5))