Skip to content

Commit

Permalink
Derive sdrContext for OSL shaders from the schemaBase defined in the …
Browse files Browse the repository at this point in the history
…node metadata, This came up as we found OSL-only display filters weren't working in Solaris because they didn't have the ri:displayFilter:shaderId defined in the schema. With this change, they will have that shaderId instead of ri:OSL:shaderId.

(Internal change: 2350062)
  • Loading branch information
sarahsunnysideup authored and pixar-oss committed Dec 6, 2024
1 parent 7437d0c commit 8119bec
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 8 deletions.
42 changes: 39 additions & 3 deletions pxr/usd/plugin/sdrOsl/oslParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ TF_DEFINE_PRIVATE_TOKENS(
((usdSchemaDefPrefix, "usdSchemaDef_"))
((sdrGlobalConfigPrefix, "sdrGlobalConfig_"))
(sdrDefinitionNameFallbackPrefix)
(schemaBase)


);

Expand Down Expand Up @@ -169,9 +171,8 @@ SdrOslParserPlugin::Parse(const NdrNodeDiscoveryResult& discoveryResult)
discoveryResult.version,
discoveryResult.name,
discoveryResult.family,
_tokens->sourceType,
_tokens->sourceType, // OSL shaders don't declare different types
// so use the same type as the source type
_getSdrContextFromSchemaBase(metadata),
_tokens->sourceType,
discoveryResult.resolvedUri,
discoveryResult.resolvedUri, // Definitive assertion that the
// implementation is the same asset
Expand All @@ -183,6 +184,41 @@ SdrOslParserPlugin::Parse(const NdrNodeDiscoveryResult& discoveryResult)
);
}

TfToken
SdrOslParserPlugin::_getSdrContextFromSchemaBase(
const NdrTokenMap& metadata) const
{
auto metaIt = metadata.find(_tokens->schemaBase);
if (metaIt == metadata.end()) {
return _tokens->sourceType;
}
std::string schemaBase = metaIt->second;

static const std::unordered_map<TfToken, TfToken, TfHash> contextMapping({
{ TfToken("displayfilter"), SdrNodeContext->DisplayFilter },
{ TfToken("lightfilter"), SdrNodeContext->LightFilter },
{ TfToken("samplefilter"), SdrNodeContext->SampleFilter },
{ TfToken("integrator"), TfToken("integrator")},
// must check for "light" after "lightfilter" otherwise a light filter
// could be mistakenly classified as a light
{ TfToken("light"), TfToken("light")} ,
{ TfToken("projection"), TfToken("projection")}
});

// Use the context mapping to determine the sdrContext for this schema.
// Test if the schema base name contains of the map keys
// for example, PxrDisplayFilterPluginBase contains "displayfilter"
std::unordered_map<TfToken, TfToken, TfHash>::const_iterator it;
for (it = contextMapping.begin(); it != contextMapping.end(); ++it) {
if (TfStringContains(TfStringToLower(schemaBase), it->first)) {
return it->second;
}
}

// fallback to sourceType as default context
return _tokens->sourceType;
}

NdrPropertyUniquePtrVec
SdrOslParserPlugin::_getNodeProperties(
const OSL::OSLQuery &query,
Expand Down
4 changes: 4 additions & 0 deletions pxr/usd/plugin/sdrOsl/oslParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ class SdrOslParserPlugin : public NdrParserPlugin
const TfToken& GetSourceType() const override;

private:
// Determines the sdrContext for the shader from the schema base defined
// in the node's metadata
TfToken _getSdrContextFromSchemaBase(const NdrTokenMap& metadata) const;

// Gets a vector of properties that are present on the specified OSL
// query object
NdrPropertyUniquePtrVec _getNodeProperties(const OSL::OSLQuery &query,
Expand Down
10 changes: 7 additions & 3 deletions pxr/usd/usdUtils/updateSchemaWithSdrNode.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,10 +503,14 @@ def UpdateSchemaWithSdrNode(schemaLayer, sdrNode, renderContext="",
shaderNodesForShaderIdAttrs = [
node for node in sdrRegistry.GetShaderNodesByIdentifier(
sdrNode.GetIdentifier())]
shaderIdAttrNames = set()
for node in shaderNodesForShaderIdAttrs:
shaderIdAttrName = Sdf.Path.JoinIdentifier( \

shaderIdAttrNames.add(Sdf.Path.JoinIdentifier( \
[renderContext, node.GetContext(),
PropertyDefiningKeys.SHADER_ID])
PropertyDefiningKeys.SHADER_ID]))

for shaderIdAttrName in shaderIdAttrNames:
shaderIdAttrSpec = Sdf.AttributeSpec(primSpec, shaderIdAttrName,
Sdf.ValueTypeNames.Token, Sdf.VariabilityUniform)

Expand All @@ -518,7 +522,7 @@ def UpdateSchemaWithSdrNode(schemaLayer, sdrNode, renderContext="",
# We are iterating on sdrNodes which are guaranteed to be registered
# with sdrRegistry and it only makes sense to add shaderId for these
# shader nodes, so directly get the identifier from the node itself.
shaderIdAttrSpec.default = node.GetIdentifier()
shaderIdAttrSpec.default = sdrNode.GetIdentifier()

# Extra attrSpec
schemaBasePrimDefinition = \
Expand Down
39 changes: 37 additions & 2 deletions third_party/renderman-26/plugin/rmanOslParser/rmanOslParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ TF_DEFINE_PRIVATE_TOKENS(
((usdSchemaDefPrefix, "usdSchemaDef_"))
((sdrGlobalConfigPrefix, "sdrGlobalConfig_"))
(sdrDefinitionNameFallbackPrefix)
(schemaBase)
);

const NdrTokenVec&
Expand Down Expand Up @@ -206,9 +207,8 @@ RmanOslParserPlugin::Parse(const NdrNodeDiscoveryResult& discoveryResult)
discoveryResult.version,
discoveryResult.name,
discoveryResult.family,
_getSdrContextFromSchemaBase(metadata),
_tokens->sourceType,
_tokens->sourceType, // OSL shaders don't declare different types
// so use the same type as the source type
discoveryResult.resolvedUri,
discoveryResult.resolvedUri, // Definitive assertion that the
// implementation is the same asset
Expand All @@ -220,6 +220,41 @@ RmanOslParserPlugin::Parse(const NdrNodeDiscoveryResult& discoveryResult)
);
}

TfToken
RmanOslParserPlugin::_getSdrContextFromSchemaBase(
const NdrTokenMap& metadata) const
{
auto metaIt = metadata.find(_tokens->schemaBase);
if (metaIt == metadata.end()) {
return _tokens->sourceType;
}
std::string schemaBase = metaIt->second;

static const std::unordered_map<TfToken, TfToken, TfHash> contextMapping({
{ TfToken("displayfilter"), SdrNodeContext->DisplayFilter },
{ TfToken("lightfilter"), SdrNodeContext->LightFilter },
{ TfToken("samplefilter"), SdrNodeContext->SampleFilter },
{ TfToken("integrator"), TfToken("integrator")},
// must check for "light" after "lightfilter" otherwise a light filter
// could be mistakenly classified as a light
{ TfToken("light"), TfToken("light")} ,
{ TfToken("projection"), TfToken("projection")}
});

// Use the context mapping to determine the sdrContext for this schema.
// Test if the schema base name contains of the map keys
// for example, PxrDisplayFilterPluginBase contains "displayfilter"
std::unordered_map<TfToken, TfToken, TfHash>::const_iterator it;
for (it = contextMapping.begin(); it != contextMapping.end(); ++it) {
if (TfStringContains(TfStringToLower(schemaBase), it->first)) {
return it->second;
}
}

// fallback to sourceType as default context
return _tokens->sourceType;
}

NdrPropertyUniquePtrVec
RmanOslParserPlugin::_getNodeProperties(
const RixShaderQuery* sq,
Expand Down
4 changes: 4 additions & 0 deletions third_party/renderman-26/plugin/rmanOslParser/rmanOslParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ class RmanOslParserPlugin : public NdrParserPlugin
const TfToken& GetSourceType() const override;

private:
// Determines the sdrContext for the shader from the schema base defined
// in the node's metadata
TfToken _getSdrContextFromSchemaBase(const NdrTokenMap& metadata) const;

// Gets a vector of properties that are present on the specified OSL
// query object
NdrPropertyUniquePtrVec _getNodeProperties(
Expand Down

0 comments on commit 8119bec

Please sign in to comment.