Skip to content

Commit c521391

Browse files
ppenenkoGitHub Enterprise
authored andcommitted
[hdSt] Early parallel MaterialX codegen, launched by a scene index
1 parent a7c0637 commit c521391

15 files changed

+748
-208
lines changed

pxr/imaging/hd/sceneIndexAdapterSceneDelegate.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,29 +1308,37 @@ _ToMaterialNetworkMap(
13081308
}
13091309

13101310
VtValue
1311-
HdSceneIndexAdapterSceneDelegate::GetMaterialResource(SdfPath const & id)
1311+
HdSceneIndexAdapterSceneDelegate::GetMaterialResourceFromSceneIndexPrim(
1312+
HdSceneIndexPrim& prim, const TfTokenVector& renderContexts)
13121313
{
1313-
TRACE_FUNCTION();
1314-
HF_MALLOC_TAG_FUNCTION();
1315-
HdSceneIndexPrim prim = _GetInputPrim(id);
1316-
13171314
HdMaterialSchema matSchema = HdMaterialSchema::GetFromParent(
13181315
prim.dataSource);
13191316
if (!matSchema.IsDefined()) {
13201317
return VtValue();
13211318
}
13221319

13231320
// Query for a material network to match the requested render contexts
1324-
const TfTokenVector renderContexts =
1325-
GetRenderIndex().GetRenderDelegate()->GetMaterialRenderContexts();
1326-
HdMaterialNetworkSchema netSchema = matSchema.GetMaterialNetwork(renderContexts);
1321+
HdMaterialNetworkSchema netSchema =
1322+
matSchema.GetMaterialNetwork(renderContexts);
13271323
if (!netSchema.IsDefined()) {
13281324
return VtValue();
13291325
}
13301326

13311327
return VtValue(_ToMaterialNetworkMap(netSchema, renderContexts));
13321328
}
13331329

1330+
VtValue
1331+
HdSceneIndexAdapterSceneDelegate::GetMaterialResource(SdfPath const & id)
1332+
{
1333+
TRACE_FUNCTION();
1334+
HF_MALLOC_TAG_FUNCTION();
1335+
1336+
HdSceneIndexPrim prim = _GetInputPrim(id);
1337+
return GetMaterialResourceFromSceneIndexPrim(
1338+
prim,
1339+
GetRenderIndex().GetRenderDelegate()->GetMaterialRenderContexts());
1340+
}
1341+
13341342
static
13351343
TfTokenVector
13361344
_ToTokenVector(const std::vector<std::string> &strings)

pxr/imaging/hd/sceneIndexAdapterSceneDelegate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ class HdSceneIndexAdapterSceneDelegate
133133
// ------------------------------------------------------------------------
134134
// Material API
135135

136+
static HD_API VtValue GetMaterialResourceFromSceneIndexPrim(
137+
HdSceneIndexPrim& prim, const TfTokenVector& renderContexts);
138+
136139
SdfPath GetMaterialId(SdfPath const &id) override;
137140
VtValue GetMaterialResource(SdfPath const &id) override;
138141
HdIdVectorSharedPtr GetCoordSysBindings(SdfPath const &id) override;

pxr/imaging/hdSt/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ if (${PXR_ENABLE_MATERIALX_SUPPORT})
2626
list(APPEND optionalPrivateClasses
2727
materialXFilter
2828
materialXShaderGen
29+
materialXSyncSceneIndex
2930
)
3031
endif()
3132
if (PXR_ENABLE_PTEX_SUPPORT)

pxr/imaging/hdSt/material.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
#include "pxr/imaging/hdSt/tokens.h"
2020
#include "pxr/imaging/hdSt/materialParam.h"
2121

22+
#ifdef PXR_MATERIALX_SUPPORT_ENABLED
23+
#include "pxr/imaging/hdSt/materialXSyncSceneIndex.h"
24+
#include "pxr/imaging/hdSt/renderDelegate.h"
25+
#endif
26+
2227
#include "pxr/imaging/hd/changeTracker.h"
2328
#include "pxr/imaging/hd/tokens.h"
2429

@@ -172,8 +177,8 @@ HdStMaterial::_ProcessTextureDescriptors(
172177
/* virtual */
173178
void
174179
HdStMaterial::Sync(HdSceneDelegate *sceneDelegate,
175-
HdRenderParam *renderParam,
176-
HdDirtyBits *dirtyBits)
180+
HdRenderParam *renderParam,
181+
HdDirtyBits *dirtyBits)
177182
{
178183
HD_TRACE_FUNCTION();
179184
HF_MALLOC_TAG_FUNCTION();
@@ -191,6 +196,19 @@ HdStMaterial::Sync(HdSceneDelegate *sceneDelegate,
191196

192197
bool markBatchesDirty = false;
193198

199+
#ifdef PXR_MATERIALX_SUPPORT_ENABLED
200+
{
201+
HdStRenderDelegate* stormDelegate = static_cast<HdStRenderDelegate*>(
202+
sceneDelegate->GetRenderIndex().GetRenderDelegate());
203+
204+
if (HdSt_MaterialXSyncSceneIndex* sceneIndex =
205+
stormDelegate->GetMaterialXSyncSceneIndex()) {
206+
207+
sceneIndex->Wait();
208+
}
209+
}
210+
#endif
211+
194212
std::string fragmentSource;
195213
std::string displacementSource;
196214
std::string volumeSource;
@@ -201,18 +219,19 @@ HdStMaterial::Sync(HdSceneDelegate *sceneDelegate,
201219

202220
VtValue vtMat = sceneDelegate->GetMaterialResource(GetId());
203221
if (vtMat.IsHolding<HdMaterialNetworkMap>()) {
222+
204223
HdMaterialNetworkMap const& hdNetworkMap =
205224
vtMat.UncheckedGet<HdMaterialNetworkMap>();
206225
if (!hdNetworkMap.terminals.empty() && !hdNetworkMap.map.empty()) {
207-
_networkProcessor.ProcessMaterialNetwork(GetId(), hdNetworkMap,
226+
_hdStMaterialNetwork.ProcessMaterialNetwork(GetId(), hdNetworkMap,
208227
resourceRegistry.get());
209-
fragmentSource = _networkProcessor.GetFragmentCode();
210-
volumeSource = _networkProcessor.GetVolumeCode();
211-
displacementSource = _networkProcessor.GetDisplacementCode();
212-
materialMetadata = _networkProcessor.GetMetadata();
213-
materialTag = _networkProcessor.GetMaterialTag();
214-
params = _networkProcessor.GetMaterialParams();
215-
textureDescriptors = _networkProcessor.GetTextureDescriptors();
228+
fragmentSource = _hdStMaterialNetwork.GetFragmentCode();
229+
volumeSource = _hdStMaterialNetwork.GetVolumeCode();
230+
displacementSource = _hdStMaterialNetwork.GetDisplacementCode();
231+
materialMetadata = _hdStMaterialNetwork.GetMetadata();
232+
materialTag = _hdStMaterialNetwork.GetMaterialTag();
233+
params = _hdStMaterialNetwork.GetMaterialParams();
234+
textureDescriptors = _hdStMaterialNetwork.GetTextureDescriptors();
216235
}
217236
}
218237

pxr/imaging/hdSt/material.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
#define PXR_IMAGING_HD_ST_MATERIAL_H
99

1010
#include "pxr/pxr.h"
11+
1112
#include "pxr/imaging/hdSt/api.h"
1213
#include "pxr/imaging/hdSt/materialNetwork.h"
1314
#include "pxr/imaging/hdSt/shaderCode.h"
15+
1416
#include "pxr/imaging/hd/material.h"
1517
#include "pxr/imaging/hf/perfLog.h"
1618

@@ -123,7 +125,7 @@ class HdStMaterial final: public HdMaterial
123125
TfToken _materialTag;
124126
size_t _textureHash;
125127

126-
HdStMaterialNetwork _networkProcessor;
128+
HdStMaterialNetwork _hdStMaterialNetwork;
127129
};
128130

129131
inline bool HdStMaterial::HasPtex() const

pxr/imaging/hdSt/materialNetwork.cpp

Lines changed: 70 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ _GetGlslfxForTerminal(
159159
}
160160
}
161161

162-
static HdMaterialNode2 const*
163-
_GetTerminalNode(
162+
HdMaterialNode2 const*
163+
HdSt_GetTerminalNode(
164164
HdMaterialNetwork2 const& network,
165165
TfToken const& terminalName,
166166
SdfPath * terminalNodePath)
@@ -1100,57 +1100,85 @@ HdStMaterialNetwork::ProcessMaterialNetwork(
11001100
{
11011101
HD_TRACE_FUNCTION();
11021102

1103-
_fragmentSource.clear();
1104-
_displacementSource.clear();
1105-
_materialMetadata.clear();
1106-
_materialParams.clear();
1107-
_textureDescriptors.clear();
1108-
_materialTag = HdStMaterialTagTokens->defaultMaterialTag;
1103+
bool isVolume = false;
1104+
1105+
auto filterTask = std::make_shared<HdSt_MaterialFilterTask>();
1106+
filterTask->hdNetwork =
1107+
HdConvertToHdMaterialNetwork2(hdNetworkMap, &isVolume);
11091108

11101109
// The fragment source comes from the 'surface' network or the
11111110
// 'volume' network.
1112-
bool isVolume = false;
11131111
HdMaterialNetwork2 surfaceNetwork =
11141112
HdConvertToHdMaterialNetwork2(hdNetworkMap, &isVolume);
11151113
const TfToken &terminalName = (isVolume) ? HdMaterialTerminalTokens->volume
11161114
: HdMaterialTerminalTokens->surface;
11171115

1118-
SdfPath surfTerminalPath;
1119-
if (HdMaterialNode2 const* surfTerminal =
1120-
_GetTerminalNode(surfaceNetwork, terminalName, &surfTerminalPath)) {
1116+
filterTask->terminalNode =
1117+
HdSt_GetTerminalNode(
1118+
filterTask->hdNetwork,
1119+
terminalName,
1120+
&filterTask->terminalNodePath);
1121+
1122+
if (!filterTask->terminalNode) {
1123+
return;
1124+
}
1125+
1126+
ProcessFilterTask(materialId, filterTask, isVolume, resourceRegistry);
1127+
}
1128+
1129+
void
1130+
HdStMaterialNetwork::ProcessFilterTask(
1131+
SdfPath const& materialId,
1132+
HdSt_MaterialFilterTaskSharedPtr filterTask,
1133+
bool isVolume,
1134+
HdStResourceRegistry *resourceRegistry)
1135+
{
1136+
HD_TRACE_FUNCTION();
1137+
1138+
_fragmentSource.clear();
1139+
_displacementSource.clear();
1140+
_materialMetadata.clear();
1141+
_materialParams.clear();
1142+
_textureDescriptors.clear();
1143+
1144+
_materialTag = HdStMaterialTagTokens->defaultMaterialTag;
1145+
1146+
if (!filterTask || !filterTask->terminalNode) {
1147+
return;
1148+
}
11211149

11221150
#ifdef PXR_MATERIALX_SUPPORT_ENABLED
1123-
if (!isVolume) {
1124-
_materialXGfx = HdSt_ApplyMaterialXFilter(&surfaceNetwork, materialId,
1125-
*surfTerminal, surfTerminalPath,
1126-
&_materialParams, resourceRegistry);
1127-
}
1151+
if (!isVolume) {
1152+
_materialXGfx = HdSt_ApplyMaterialXFilter(filterTask, materialId,
1153+
&_materialParams, resourceRegistry);
1154+
}
11281155
#endif
1129-
// Extract the glslfx and metadata for surface/volume.
1130-
_GetGlslfxForTerminal(_surfaceGfx, &_surfaceGfxHash,
1131-
surfTerminal->nodeTypeId, resourceRegistry);
1132-
if (_surfaceGfx) {
1133-
1134-
// If the glslfx file is not valid we skip parsing the network.
1135-
// This produces no fragmentSource which means Storm's material
1136-
// will use the fallback shader.
1137-
if (_surfaceGfx->IsValid()) {
1138-
1139-
_fragmentSource = _surfaceGfx->GetSurfaceSource();
1140-
_volumeSource = _surfaceGfx->GetVolumeSource();
1141-
1142-
_materialMetadata = _surfaceGfx->GetMetadata();
1143-
_materialTag = _GetMaterialTag(_materialMetadata, *surfTerminal);
1144-
_GatherMaterialParams(surfaceNetwork, *surfTerminal,
1145-
&_materialParams, &_textureDescriptors,
1146-
_materialTag);
1147-
1148-
// OSL networks have a displacement network in hdNetworkMap
1149-
// under terminal: HdMaterialTerminalTokens->displacement.
1150-
// For Storm however we expect the displacement shader to be
1151-
// provided via the surface glslfx / terminal.
1152-
_displacementSource = _surfaceGfx->GetDisplacementSource();
1153-
}
1156+
// Extract the glslfx and metadata for surface/volume.
1157+
_GetGlslfxForTerminal(_surfaceGfx, &_surfaceGfxHash,
1158+
filterTask->terminalNode->nodeTypeId, resourceRegistry);
1159+
if (_surfaceGfx) {
1160+
1161+
// If the glslfx file is not valid we skip parsing the network.
1162+
// This produces no fragmentSource which means Storm's material
1163+
// will use the fallback shader.
1164+
if (_surfaceGfx->IsValid()) {
1165+
_fragmentSource = _surfaceGfx->GetSurfaceSource();
1166+
_volumeSource = _surfaceGfx->GetVolumeSource();
1167+
1168+
_materialMetadata = _surfaceGfx->GetMetadata();
1169+
1170+
_materialTag = _GetMaterialTag(
1171+
_surfaceGfx->GetMetadata(), *filterTask->terminalNode);
1172+
_GatherMaterialParams(
1173+
filterTask->hdNetwork, *filterTask->terminalNode,
1174+
&_materialParams, &_textureDescriptors,
1175+
_materialTag);
1176+
1177+
// OSL networks have a displacement network in hdNetworkMap
1178+
// under terminal: HdMaterialTerminalTokens->displacement.
1179+
// For Storm however we expect the displacement shader to be
1180+
// provided via the surface glslfx / terminal.
1181+
_displacementSource = _surfaceGfx->GetDisplacementSource();
11541182
}
11551183
}
11561184
}

pxr/imaging/hdSt/materialNetwork.h

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,57 @@
2020

2121
PXR_NAMESPACE_OPEN_SCOPE
2222

23+
class SdrRegistry;
2324
class HdStResourceRegistry;
2425
using HioGlslfxSharedPtr = std::shared_ptr<class HioGlslfx>;
2526
using HdSt_MaterialParamVector = std::vector<class HdSt_MaterialParam>;
27+
struct HdSt_MaterialFilterTask;
28+
using HdSt_MaterialFilterTaskSharedPtr =
29+
std::shared_ptr<HdSt_MaterialFilterTask>;
30+
31+
extern HdMaterialNode2 const*
32+
HdSt_GetTerminalNode(
33+
HdMaterialNetwork2 const& network,
34+
TfToken const& terminalName,
35+
SdfPath * terminalNodePath);
36+
37+
/// Encapsulates the input data for MaterialX codegen as well as metadata
38+
/// necessary for completing `HdStMaterial::Sync` based on the result of the
39+
/// codegen.
40+
/// This object can either live on the stack, if MaterialX codegen happens
41+
/// synchronously, or on the heap, owned by the respective Sprim, if the
42+
/// codegen happens in parallel tasks.
43+
///
44+
struct ARCH_EXPORT_TYPE HdSt_MaterialFilterTask final
45+
{
46+
HdMaterialNetwork2 hdNetwork;
47+
HdMaterialNode2 const* terminalNode = nullptr; // pointer to a node
48+
// in the above network
49+
SdfPath terminalNodePath; // path to the above node
50+
51+
#ifdef PXR_MATERIALX_SUPPORT_ENABLED
52+
// Stores the mappings between the node paths in the original
53+
// HdMaterialNetwork to the corresponding anonymized node paths
54+
using OrigToAnonSdfPathMap =
55+
std::unordered_map<SdfPath, SdfPath, SdfPath::Hash>;
56+
OrigToAnonSdfPathMap origToAnonSdfPathMap;
57+
58+
/// Build the `anonNetwork`, equivalent to the given hdNetwork but anonymized
59+
/// and stripped of non-topological parameters to better re-use the generated
60+
/// shader.
61+
/// Returns the hash of the anonymized network.
62+
size_t BuildAnonymizedMaterialNetwork(
63+
HdMaterialNetwork2* anonNetwork);
64+
65+
void AddFallbackDomeLightTextureNode();
66+
67+
void AddMaterialXParams(
68+
MaterialX::Shader const& mxShader,
69+
HdSt_MaterialParamVector* materialParams);
70+
71+
bool IsMaterialX(SdrRegistry* sdrRegistry) const;
72+
#endif
73+
};
2674

2775
/// \class HdStMaterialNetwork
2876
///
@@ -37,6 +85,14 @@ class HdStMaterialNetwork final
3785
HDST_API
3886
~HdStMaterialNetwork();
3987

88+
/// Process the necessary network information cached in the filter task.
89+
HDST_API
90+
void ProcessFilterTask(
91+
SdfPath const& materialId,
92+
HdSt_MaterialFilterTaskSharedPtr filterTask,
93+
bool isVolume,
94+
HdStResourceRegistry *resourceRegistry);
95+
4096
/// Process a material network topology and extract all the information we
4197
/// need from it.
4298
HDST_API
@@ -67,7 +123,7 @@ class HdStMaterialNetwork final
67123
struct TextureDescriptor
68124
{
69125
// Name by which the texture will be accessed, i.e., the name
70-
// of the accesor for thexture will be HdGet_name(...).
126+
// of the accessor for the texture will be HdGet_name(...).
71127
// It is generated from the input name the corresponding texture
72128
// node is connected to.
73129
TfToken name;

0 commit comments

Comments
 (0)