1 //
2 // Copyright 2019 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef EXT_RMANPKG_24_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_CONTEXT_H
25 #define EXT_RMANPKG_24_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_CONTEXT_H
26 
27 #include "pxr/pxr.h"
28 #include "hdPrman/api.h"
29 #include "hdPrman/xcpt.h"
30 #include "pxr/base/gf/matrix4d.h"
31 #include "pxr/base/tf/token.h"
32 #include "pxr/usd/sdf/path.h"
33 #include "pxr/imaging/hd/sceneDelegate.h"
34 #include "pxr/imaging/hd/coordSys.h"
35 
36 #include "Riley.h"
37 #include <thread>
38 #include <unordered_map>
39 #include <mutex>
40 
41 // Compile-time limit on max time samples.
42 // The idea is to avoid heap allocation of sample buffers in the Sync()
43 // calls by using fixed-size stack arrays with configured capacity.
44 // The capacity is indicated to the scene delegate when requesting
45 // time samples.
46 #define HDPRMAN_MAX_TIME_SAMPLES 4
47 
48 class RixRiCtl;
49 
50 PXR_NAMESPACE_OPEN_SCOPE
51 
52 class SdfPath;
53 class HdSceneDelegate;
54 class HdPrmanCamera;
55 class HdPrmanRenderDelegate;
56 
57 // Context for HdPrman to communicate with an instance of PRMan.
58 struct HdPrman_Context
59 {
60     HDPRMAN_API
61     HdPrman_Context();
62 
63     virtual ~HdPrman_Context();
64 
65     // Convert any Hydra primvars that should be Riley instance attributes.
66     HDPRMAN_API
67     RtParamList
68     ConvertAttributes(HdSceneDelegate *sceneDelegate, SdfPath const& id);
69 
70     // A vector of Riley coordinate system id's.
71     typedef std::vector<riley::CoordinateSystemId> RileyCoordSysIdVec;
72     // A ref-counting ptr to a vector of coordinate systems.
73     typedef std::shared_ptr<RileyCoordSysIdVec> RileyCoordSysIdVecRefPtr;
74 
75     /// Convert any coordinate system bindings for the given rprim id
76     /// into a Riley equivalent form.  Retain the result internally
77     /// in a cache, so that we may re-use the result with other
78     /// rprims with the same set of bindings.
79     HDPRMAN_API
80     RileyCoordSysIdVecRefPtr ConvertAndRetainCoordSysBindings(
81         HdSceneDelegate *sceneDelegate,
82         SdfPath const& id);
83 
84     /// Convert a list of categories returned by Hydra to
85     /// equivalent Prman grouping attributes.
86     HDPRMAN_API
87     void ConvertCategoriesToAttributes(
88         SdfPath const& id,
89         VtArray<TfToken> const& categories,
90         RtParamList& attrs);
91 
92     /// Release any coordinate system bindings cached for the given
93     /// rprim id.
94     HDPRMAN_API
95     void ReleaseCoordSysBindings(SdfPath const& id);
96 
97     HDPRMAN_API
98     void IncrementLightLinkCount(TfToken const& name);
99 
100     HDPRMAN_API
101     void DecrementLightLinkCount(TfToken const& name);
102 
103     HDPRMAN_API
104     bool IsLightLinkUsed(TfToken const& name);
105 
106     HDPRMAN_API
107     void IncrementLightFilterCount(TfToken const& name);
108 
109     HDPRMAN_API
110     void DecrementLightFilterCount(TfToken const& name);
111 
112     HDPRMAN_API
113     bool IsLightFilterUsed(TfToken const& name);
114 
115     HDPRMAN_API
116     void SetOptionsFromRenderSettings(HdPrmanRenderDelegate *renderDelegate,
117                                       RtParamList& options);
118 
119     // Set integrator params from the HdRenderSettingsMap
120     HDPRMAN_API
121     void SetIntegratorParamsFromRenderSettings(
122                         HdPrmanRenderDelegate *renderDelegate,
123                         std::string& integratorName,
124                         RtParamList& params);
125 
126     // Set integrator params from the camera.
127     // This invokes any callbacks registered with
128     // RegisterIntegratorCallbackForCamera().
129     HDPRMAN_API
130     void SetIntegratorParamsFromCamera(
131                         HdPrmanRenderDelegate *renderDelegate,
132                         HdPrmanCamera *camera,
133                         std::string const& integratorName,
134                         RtParamList& params);
135 
136     // Callback to convert any camera settings that should become
137     // parameters on the integrator.
138     using IntegratorCameraCallback = void (*)
139         (HdPrmanRenderDelegate *renderDelegate,
140          HdPrmanCamera *camera,
141          std::string const& integratorName,
142          RtParamList &integratorParams);
143 
144     // Register a callback to process integrator settings
145     HDPRMAN_API
146     static void
147     RegisterIntegratorCallbackForCamera(
148         IntegratorCameraCallback const& callback);
149 
150     HDPRMAN_API
151     bool IsShutterInstantaneous() const;
152 
153     HDPRMAN_API
154     void SetInstantaneousShutter(bool instantaneousShutter);
155 
156     // Get RIX vs XPU
IsXpuHdPrman_Context157     bool IsXpu() const { return _xpu; }
158 
159     // Top-level entrypoint to PRMan.
160     // Singleton used to access RixInterfaces.
161     RixContext *rix;
162 
163     // RixInterface for PRManBegin/End.
164     RixRiCtl *ri;
165 
166     // RixInterface for Riley.
167     RixRileyManager *mgr;
168 
169     // Riley instance.
170     riley::Riley *riley;
171 
172     // Xcpt Handler
173     HdPrman_Xcpt xcpt;
174 
175     // A fallback material to use for any geometry that
176     // does not have a bound material.
177     riley::MaterialId fallbackMaterial;
178 
179     // Fallback material for volumes that don't have materials.
180     riley::MaterialId fallbackVolumeMaterial;
181 
182 protected:
183     void _InitializePrman();
184 
185 private:
186     // Refcounts for each category mentioned by a light link.
187     // This is used to convey information from lights back to the
188     // geometry -- in Renderman, geometry must subscribe
189     // to the linked lights.
190     std::unordered_map<TfToken, size_t, TfToken::HashFunctor> _lightLinkRefs;
191 
192     // Mutex protecting lightLinkRefs.
193     std::mutex _lightLinkMutex;
194 
195     std::unordered_map<TfToken, size_t, TfToken::HashFunctor> _lightFilterRefs;
196 
197     // Mutex protecting lightFilterRefs.
198     std::mutex _lightFilterMutex;
199 
200     // Map from Hydra coordinate system vector pointer to Riley equivalent.
201     typedef std::unordered_map<
202         HdIdVectorSharedPtr, RileyCoordSysIdVecRefPtr>
203         _HdToRileyCoordSysMap;
204     // Map from Hydra id to cached, converted coordinate systems.
205     typedef std::unordered_map<
206         SdfPath, HdIdVectorSharedPtr, SdfPath::Hash>
207         _GeomToHdCoordSysMap;
208 
209     // Coordinate system conversion cache.
210     _GeomToHdCoordSysMap _geomToHdCoordSysMap;
211     _HdToRileyCoordSysMap _hdToRileyCoordSysMap;
212     std::mutex _coordSysMutex;
213 
214     // A quick way to disable motion blur, making shutter close same as open
215     bool _instantaneousShutter;
216 
217     // RIX or XPU
218     bool _xpu;
219 };
220 
221 // Helper to convert matrix types, handling double->float conversion.
222 inline RtMatrix4x4
HdPrman_GfMatrixToRtMatrix(const GfMatrix4d & m)223 HdPrman_GfMatrixToRtMatrix(const GfMatrix4d &m)
224 {
225     const double *d = m.GetArray();
226     return RtMatrix4x4(
227         d[0], d[1], d[2], d[3],
228         d[4], d[5], d[6], d[7],
229         d[8], d[9], d[10], d[11],
230         d[12], d[13], d[14], d[15]);
231 }
232 
233 // Helper to convert matrix types, handling float->double conversion.
234 inline GfMatrix4d
HdPrman_RtMatrixToGfMatrix(const RtMatrix4x4 & m)235 HdPrman_RtMatrixToGfMatrix(const RtMatrix4x4 &m)
236 {
237     return GfMatrix4d(
238         m.m[0][0], m.m[0][1], m.m[0][2], m.m[0][3],
239         m.m[1][0], m.m[1][1], m.m[1][2], m.m[1][3],
240         m.m[2][0], m.m[2][1], m.m[2][2], m.m[2][3],
241         m.m[3][0], m.m[3][1], m.m[3][2], m.m[3][3]);
242 }
243 
244 // Convert any Hydra primvars that should be Riley primvars.
245 void
246 HdPrman_ConvertPrimvars(HdSceneDelegate *sceneDelegate, SdfPath const& id,
247                         RtPrimVarList& primvars, int numUniform, int numVertex,
248                         int numVarying, int numFaceVarying);
249 
250 // Check for any primvar opinions on the material that should be Riley primvars.
251 void
252 HdPrman_TransferMaterialPrimvarOpinions(HdSceneDelegate *sceneDelegate,
253                                         SdfPath const& hdMaterialId,
254                                         RtPrimVarList& primvars);
255 
256 // Resolve Hd material ID to the corresponding Riley material & displacement
257 bool
258 HdPrman_ResolveMaterial(HdSceneDelegate *sceneDelegate,
259                         SdfPath const& hdMaterialId,
260                         riley::MaterialId *materialId,
261                         riley::DisplacementId *dispId);
262 
263 
264 /// Update the supplied list of options using searchpaths
265 /// pulled from envrionment variables:
266 ///
267 /// - RMAN_SHADERPATH
268 /// - RMAN_TEXTUREPATH
269 /// - RMAN_RIXPLUGINPATH
270 /// - RMAN_PROCEDURALPATH
271 ///
272 HDPRMAN_API
273 void
274 HdPrman_UpdateSearchPathsFromEnvironment(RtParamList& options);
275 
276 PXR_NAMESPACE_CLOSE_SCOPE
277 
278 #endif // EXT_RMANPKG_24_0_PLUGIN_RENDERMAN_PLUGIN_HD_PRMAN_CONTEXT_H
279