diff --git a/python/MaterialXTest/genshader.py b/python/MaterialXTest/genshader.py index 0b541df24d..c5f669c422 100644 --- a/python/MaterialXTest/genshader.py +++ b/python/MaterialXTest/genshader.py @@ -54,6 +54,7 @@ def test_ShaderInterface(self): self.assertTrue(foundTarget) context = mx_gen_shader.GenContext(shadergen) context.registerSourceCodeSearchPath(searchPath) + shadergen.registerTypeDefs(doc, context) # Test generator with complete mode context.getOptions().shaderInterfaceType = mx_gen_shader.ShaderInterfaceType.SHADER_INTERFACE_COMPLETE; diff --git a/python/Scripts/generateshader.py b/python/Scripts/generateshader.py index b00311eb2e..c40356db89 100644 --- a/python/Scripts/generateshader.py +++ b/python/Scripts/generateshader.py @@ -107,6 +107,7 @@ def main(): codeSearchPath.append(os.path.dirname(inputFilename)) context = mx_gen_shader.GenContext(shadergen) context.registerSourceCodeSearchPath(codeSearchPath) + shadergen.registerTypeDefs(doc, context) # If we're generating Vulkan-compliant GLSL then set the binding context if opts.vulkanCompliantGlsl: diff --git a/resources/Materials/TestSuite/stdlib/structs/struct_texcoord.mtlx b/resources/Materials/TestSuite/stdlib/structs/struct_texcoord.mtlx new file mode 100644 index 0000000000..3b1c69832e --- /dev/null +++ b/resources/Materials/TestSuite/stdlib/structs/struct_texcoord.mtlx @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/stdlib/structs/struct_texcoordGroup.mtlx b/resources/Materials/TestSuite/stdlib/structs/struct_texcoordGroup.mtlx new file mode 100644 index 0000000000..e86afa9c3d --- /dev/null +++ b/resources/Materials/TestSuite/stdlib/structs/struct_texcoordGroup.mtlx @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/JsMaterialX/JsMaterialXGenShader/JsTypeDesc.cpp b/source/JsMaterialX/JsMaterialXGenShader/JsTypeDesc.cpp index 92e1c27b69..4b7bf55bb2 100644 --- a/source/JsMaterialX/JsMaterialXGenShader/JsTypeDesc.cpp +++ b/source/JsMaterialX/JsMaterialXGenShader/JsTypeDesc.cpp @@ -4,6 +4,7 @@ // #include +#include #include diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index c648441c7e..2fc64ba7f1 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -614,7 +614,7 @@ void GlslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& c else { string outputValue = outputSocket->getValue() ? - _syntax->getValue(outputSocket->getType(), *outputSocket->getValue()) : + _syntax->getValue(outputSocket->getType(), *outputSocket->getValue(), context) : _syntax->getDefaultValue(outputSocket->getType()); if (!outputSocket->getType().isFloat4()) { @@ -689,7 +689,7 @@ void GlslShaderGenerator::toVec4(TypeDesc type, string& variable) } void GlslShaderGenerator::emitVariableDeclaration(const ShaderPort* variable, const string& qualifier, - GenContext&, ShaderStage& stage, + GenContext& context, ShaderStage& stage, bool assignValue) const { // A file texture input needs special handling on GLSL @@ -724,7 +724,7 @@ void GlslShaderGenerator::emitVariableDeclaration(const ShaderPort* variable, co if (assignValue) { const string valueStr = (variable->getValue() ? - _syntax->getValue(variable->getType(), *variable->getValue(), true) : + _syntax->getValue(variable->getType(), *variable->getValue(), context, true) : _syntax->getDefaultValue(variable->getType(), true)); str += valueStr.empty() ? EMPTY_STRING : " = " + valueStr; } @@ -756,7 +756,7 @@ ShaderNodeImplPtr GlslShaderGenerator::getImplementation(const NodeDef& nodedef, throw ExceptionShaderGenError("NodeDef '" + nodedef.getName() + "' has no outputs defined"); } - const TypeDesc outputType = TypeDesc::get(outputs[0]->getType()); + const TypeDesc outputType = context.getTypeDesc(outputs[0]->getType()); if (implElement->isA()) { diff --git a/source/MaterialXGenGlsl/GlslSyntax.cpp b/source/MaterialXGenGlsl/GlslSyntax.cpp index 7054725b76..6768df51b6 100644 --- a/source/MaterialXGenGlsl/GlslSyntax.cpp +++ b/source/MaterialXGenGlsl/GlslSyntax.cpp @@ -5,6 +5,7 @@ #include +#include #include MATERIALX_NAMESPACE_BEGIN @@ -20,7 +21,7 @@ class GlslStringTypeSyntax : public StringTypeSyntax GlslStringTypeSyntax() : StringTypeSyntax("int", "0", "0") { } - string getValue(const Value& /*value*/, bool /*uniform*/) const override + string getValue(const Value& /*value*/, const GenContext& /*context*/, bool /*uniform*/) const override { return "0"; } @@ -34,7 +35,7 @@ class GlslArrayTypeSyntax : public ScalarTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { size_t arraySize = getSize(value); if (arraySize > 0) @@ -388,7 +389,7 @@ StructTypeSyntaxPtr GlslSyntax::createStructSyntax(const string& structTypeName, typeDefinition); } -string GlslStructTypeSyntax::getValue(const Value& value, bool /* uniform */) const +string GlslStructTypeSyntax::getValue(const Value& value, const GenContext& context, bool /*uniform*/) const { const AggregateValue& aggValue = static_cast(value); @@ -401,10 +402,10 @@ string GlslStructTypeSyntax::getValue(const Value& value, bool /* uniform */) co separator = ","; const string& memberTypeName = memberValue->getTypeString(); - TypeDesc memberTypeDesc = TypeDesc::get(memberTypeName); + TypeDesc memberTypeDesc = context.getTypeDesc(memberTypeName); // Recursively use the syntax to generate the output, so we can supported nested structs. - result += _parentSyntax->getValue(memberTypeDesc, *memberValue, true); + result += _parentSyntax->getValue(memberTypeDesc, *memberValue, context, true); } result += ")"; diff --git a/source/MaterialXGenGlsl/GlslSyntax.h b/source/MaterialXGenGlsl/GlslSyntax.h index 1e82e354bd..d6874073be 100644 --- a/source/MaterialXGenGlsl/GlslSyntax.h +++ b/source/MaterialXGenGlsl/GlslSyntax.h @@ -58,7 +58,7 @@ class MX_GENGLSL_API GlslStructTypeSyntax : public StructTypeSyntax public: using StructTypeSyntax::StructTypeSyntax; - string getValue(const Value& value, bool uniform) const override; + string getValue(const Value& value, const GenContext& context, bool uniform) const override; }; MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/LightCompoundNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/LightCompoundNodeGlsl.cpp index 6f005766fd..ecfd2ac793 100644 --- a/source/MaterialXGenGlsl/Nodes/LightCompoundNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/LightCompoundNodeGlsl.cpp @@ -34,7 +34,7 @@ void LightCompoundNodeGlsl::initialize(const InterfaceElement& element, GenConte NodeDefPtr nodeDef = graph.getNodeDef(); for (InputPtr input : nodeDef->getActiveInputs()) { - _lightUniforms.add(TypeDesc::get(input->getType()), input->getName()); + _lightUniforms.add(context.getTypeDesc(input->getType()), input->getName()); } } diff --git a/source/MaterialXGenGlsl/Nodes/LightShaderNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/LightShaderNodeGlsl.cpp index c7b4df2bb6..e79a5d39bf 100644 --- a/source/MaterialXGenGlsl/Nodes/LightShaderNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/LightShaderNodeGlsl.cpp @@ -44,7 +44,7 @@ void LightShaderNodeGlsl::initialize(const InterfaceElement& element, GenContext NodeDefPtr nodeDef = impl.getNodeDef(); for (InputPtr input : nodeDef->getActiveInputs()) { - _lightUniforms.add(TypeDesc::get(input->getType()), input->getName(), input->getValue()); + _lightUniforms.add(context.getTypeDesc(input->getType()), input->getName(), input->getValue()); } } diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index 71db0d7cf4..97041f9702 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -176,7 +176,7 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G emitScopeBegin(stage, Syntax::PARENTHESES); // Emit shader inputs - emitShaderInputs(element->getDocument(), stage.getInputBlock(MDL::INPUTS), stage); + emitShaderInputs(element->getDocument(), stage.getInputBlock(MDL::INPUTS), context, stage); // End shader signature emitScopeEnd(stage); @@ -333,7 +333,7 @@ ShaderNodeImplPtr MdlShaderGenerator::getImplementation(const NodeDef& nodedef, throw ExceptionShaderGenError("NodeDef '" + nodedef.getName() + "' has no outputs defined"); } - const TypeDesc outputType = TypeDesc::get(outputs[0]->getType()); + const TypeDesc outputType = context.getTypeDesc(outputs[0]->getType()); if (implElement->isA()) { @@ -658,7 +658,7 @@ void emitInputAnnotations(const MdlShaderGenerator& _this, const DocumentPtr doc } // anonymous namespace -void MdlShaderGenerator::emitShaderInputs(const DocumentPtr doc, const VariableBlock& inputs, ShaderStage& stage) const +void MdlShaderGenerator::emitShaderInputs(const DocumentPtr doc, const VariableBlock& inputs, const GenContext& context, ShaderStage& stage) const { const string uniformPrefix = _syntax->getUniformQualifier() + " "; for (size_t i = 0; i < inputs.size(); ++i) @@ -668,7 +668,7 @@ void MdlShaderGenerator::emitShaderInputs(const DocumentPtr doc, const VariableB const string& qualifier = input->isUniform() || input->getType() == Type::FILENAME ? uniformPrefix : EMPTY_STRING; const string& type = _syntax->getTypeName(input->getType()); - string value = input->getValue() ? _syntax->getValue(input->getType(), *input->getValue(), true) : EMPTY_STRING; + string value = input->getValue() ? _syntax->getValue(input->getType(), *input->getValue(), context, true) : EMPTY_STRING; const string& geomprop = input->getGeomProp(); if (!geomprop.empty()) { @@ -753,6 +753,19 @@ void MdlShaderGenerator::emitMdlVersionFilenameSuffix(GenContext& context, Shade emitString(getMdlVersionFilenameSuffix(context), stage); } +void MdlShaderGenerator::registerBuiltinTypes(GenContext& context) +{ + ShaderGenerator::registerBuiltinTypes(context); + + // Custom types to handle enumeration output + context.registerTypeDesc(Type::MDL_COORDINATESPACE); + context.registerTypeDesc(Type::MDL_ADDRESSMODE); + context.registerTypeDesc(Type::MDL_FILTERLOOKUPMODE); + context.registerTypeDesc(Type::MDL_FILTERTYPE); + context.registerTypeDesc(Type::MDL_DISTRIBUTIONTYPE); + context.registerTypeDesc(Type::MDL_SCATTER_MODE); +} + namespace MDL { // Identifiers for MDL variable blocks diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.h b/source/MaterialXGenMdl/MdlShaderGenerator.h index ef88fbc453..090aa81c46 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.h +++ b/source/MaterialXGenMdl/MdlShaderGenerator.h @@ -90,12 +90,14 @@ class MX_GENMDL_API MdlShaderGenerator : public ShaderGenerator /// Get the version number suffix appended to MDL modules that use versions. const string& getMdlVersionFilenameSuffix(GenContext& context) const; + void registerBuiltinTypes(GenContext& context) override; + protected: // Create and initialize a new MDL shader for shader generation. ShaderPtr createShader(const string& name, ElementPtr element, GenContext& context) const; // Emit a block of shader inputs. - void emitShaderInputs(const DocumentPtr doc, const VariableBlock& inputs, ShaderStage& stage) const; + void emitShaderInputs(const DocumentPtr doc, const VariableBlock& inputs, const GenContext& context, ShaderStage& stage) const; }; namespace MDL diff --git a/source/MaterialXGenMdl/MdlSyntax.cpp b/source/MaterialXGenMdl/MdlSyntax.cpp index 0244a8352f..1369abf129 100644 --- a/source/MaterialXGenMdl/MdlSyntax.cpp +++ b/source/MaterialXGenMdl/MdlSyntax.cpp @@ -13,19 +13,6 @@ MATERIALX_NAMESPACE_BEGIN -// Custom types to handle enumeration output -namespace Type -{ - -TYPEDESC_REGISTER_TYPE(MDL_COORDINATESPACE, "coordinatespace") -TYPEDESC_REGISTER_TYPE(MDL_ADDRESSMODE, "addressmode") -TYPEDESC_REGISTER_TYPE(MDL_FILTERLOOKUPMODE, "filterlookup") -TYPEDESC_REGISTER_TYPE(MDL_FILTERTYPE, "filtertype") -TYPEDESC_REGISTER_TYPE(MDL_DISTRIBUTIONTYPE, "distributiontype") -TYPEDESC_REGISTER_TYPE(MDL_SCATTER_MODE, "scatter_mode") - -} // namespace Type - namespace { @@ -37,7 +24,7 @@ class MdlFilenameTypeSyntax : public ScalarTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { const string outputValue = value.getValueString(); if (outputValue.empty() || outputValue == "/") @@ -84,7 +71,7 @@ class MdlArrayTypeSyntax : public ScalarTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { if (!isEmpty(value)) { @@ -145,7 +132,7 @@ class MdlColor4TypeSyntax : public AggregateTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { StringStream ss; @@ -171,7 +158,7 @@ class MdlEnumSyntax : public AggregateTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { return _name + "_" + value.getValueString(); } diff --git a/source/MaterialXGenMdl/Nodes/BlurNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/BlurNodeMdl.cpp index ae10ca3fa8..31dad20f7a 100644 --- a/source/MaterialXGenMdl/Nodes/BlurNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/BlurNodeMdl.cpp @@ -153,7 +153,7 @@ void BlurNodeMdl::emitFunctionCall(const ShaderNode& node, GenContext& context, string emitValue = "\"" + GAUSSIAN_FILTER + "\""; if (syntax.remapEnumeration(GAUSSIAN_FILTER, Type::STRING, FILTER_LIST, result)) { - emitValue = syntax.getValue(result.first, *(result.second)); + emitValue = syntax.getValue(result.first, *(result.second), context); } shadergen.emitString(" == " + emitValue + " ? ", stage); { diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp index 5b187f80aa..d49f9f573f 100644 --- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp @@ -197,7 +197,7 @@ ShaderNodeImplPtr LayerableNodeMdl::create() return std::make_shared(); } -void LayerableNodeMdl::addInputs(ShaderNode& node, GenContext& /*context*/) const +void LayerableNodeMdl::addInputs(ShaderNode& node, GenContext&) const { // Add the input to hold base layer BSDF. node.addInput(StringConstantsMdl::BASE, Type::BSDF); diff --git a/source/MaterialXGenMdl/Nodes/CompoundNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/CompoundNodeMdl.cpp index 80c449e507..f981090d2b 100644 --- a/source/MaterialXGenMdl/Nodes/CompoundNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/CompoundNodeMdl.cpp @@ -236,7 +236,7 @@ void CompoundNodeMdl::emitFunctionSignature(const ShaderNode&, GenContext& conte const string& qualifier = input->isUniform() || input->getType() == Type::FILENAME ? uniformPrefix : EMPTY_STRING; const string& type = syntax.getTypeName(input->getType()); - string value = input->getValue() ? syntax.getValue(input->getType(), *input->getValue(), true) : EMPTY_STRING; + string value = input->getValue() ? syntax.getValue(input->getType(), *input->getValue(), context, true) : EMPTY_STRING; const string& geomprop = input->getGeomProp(); if (!geomprop.empty()) { diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 9511fac7ba..b206b480ed 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -1094,7 +1094,7 @@ void MslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& co else { string outputValue = outputSocket->getValue() ? - _syntax->getValue(outputSocket->getType(), *outputSocket->getValue()) : + _syntax->getValue(outputSocket->getType(), *outputSocket->getValue(), context) : _syntax->getDefaultValue(outputSocket->getType()); if (!outputSocket->getType().isFloat4()) { @@ -1201,7 +1201,7 @@ void MslShaderGenerator::toVec4(TypeDesc type, string& variable) } void MslShaderGenerator::emitVariableDeclaration(const ShaderPort* variable, const string& qualifier, - GenContext&, ShaderStage& stage, + GenContext& context, ShaderStage& stage, bool assignValue) const { // A file texture input needs special handling on MSL @@ -1238,7 +1238,7 @@ void MslShaderGenerator::emitVariableDeclaration(const ShaderPort* variable, con if (assignValue) { const string valueStr = (variable->getValue() ? - _syntax->getValue(variable->getType(), *variable->getValue(), true) : + _syntax->getValue(variable->getType(), *variable->getValue(), context, true) : _syntax->getDefaultValue(variable->getType(), true)); str += valueStr.empty() ? EMPTY_STRING : " = " + valueStr; } @@ -1270,7 +1270,7 @@ ShaderNodeImplPtr MslShaderGenerator::getImplementation(const NodeDef& nodedef, throw ExceptionShaderGenError("NodeDef '" + nodedef.getName() + "' has no outputs defined"); } - const TypeDesc outputType = TypeDesc::get(outputs[0]->getType()); + const TypeDesc outputType = context.getTypeDesc(outputs[0]->getType()); if (implElement->isA()) { diff --git a/source/MaterialXGenMsl/MslSyntax.cpp b/source/MaterialXGenMsl/MslSyntax.cpp index 30f44c5d1c..ed7800912a 100644 --- a/source/MaterialXGenMsl/MslSyntax.cpp +++ b/source/MaterialXGenMsl/MslSyntax.cpp @@ -20,7 +20,7 @@ class MslStringTypeSyntax : public StringTypeSyntax MslStringTypeSyntax() : StringTypeSyntax("int", "0", "0") { } - string getValue(const Value& /*value*/, bool /*uniform*/) const override + string getValue(const Value& /*value*/, const GenContext& /*context*/, bool /*uniform*/) const override { return "0"; } @@ -34,7 +34,7 @@ class MslArrayTypeSyntax : public ScalarTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { size_t arraySize = getSize(value); if (arraySize > 0) diff --git a/source/MaterialXGenMsl/Nodes/LightCompoundNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/LightCompoundNodeMsl.cpp index 1e5bd787a8..e801b543c2 100644 --- a/source/MaterialXGenMsl/Nodes/LightCompoundNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/LightCompoundNodeMsl.cpp @@ -34,7 +34,7 @@ void LightCompoundNodeMsl::initialize(const InterfaceElement& element, GenContex NodeDefPtr nodeDef = graph.getNodeDef(); for (InputPtr input : nodeDef->getActiveInputs()) { - _lightUniforms.add(TypeDesc::get(input->getType()), input->getName()); + _lightUniforms.add(context.getTypeDesc(input->getType()), input->getName()); } } diff --git a/source/MaterialXGenMsl/Nodes/LightShaderNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/LightShaderNodeMsl.cpp index b556415dae..0ccf1cd349 100644 --- a/source/MaterialXGenMsl/Nodes/LightShaderNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/LightShaderNodeMsl.cpp @@ -44,7 +44,7 @@ void LightShaderNodeMsl::initialize(const InterfaceElement& element, GenContext& NodeDefPtr nodeDef = impl.getNodeDef(); for (InputPtr input : nodeDef->getActiveInputs()) { - _lightUniforms.add(TypeDesc::get(input->getType()), input->getName(), input->getValue()); + _lightUniforms.add(context.getTypeDesc(input->getType()), input->getName(), input->getValue()); } } diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index ff8cad36f5..08e59a1e37 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -123,7 +123,7 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G const ShaderMetadata& data = metadata->at(j); const string& delim = (j == metadata->size() - 1) ? EMPTY_STRING : Syntax::COMMA; const string& dataType = _syntax->getTypeName(data.type); - const string dataValue = _syntax->getValue(data.type, *data.value, true); + const string dataValue = _syntax->getValue(data.type, *data.value, context, true); emitLine(dataType + " " + data.name + " = " + dataValue + delim, stage, false); } } @@ -133,8 +133,8 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G emitScopeBegin(stage, Syntax::PARENTHESES); // Emit shader inputs - emitShaderInputs(stage.getInputBlock(OSL::INPUTS), stage); - emitShaderInputs(stage.getUniformBlock(OSL::UNIFORMS), stage); + emitShaderInputs(stage.getInputBlock(OSL::INPUTS), context, stage); + emitShaderInputs(stage.getUniformBlock(OSL::UNIFORMS), context, stage); // Emit shader output const VariableBlock& outputs = stage.getOutputBlock(OSL::OUTPUTS); @@ -372,7 +372,7 @@ void OslShaderGenerator::emitLibraryIncludes(ShaderStage& stage, GenContext& con emitLineBreak(stage); } -void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderStage& stage) const +void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, const GenContext& context, ShaderStage& stage) const { static const std::unordered_map GEOMPROP_DEFINITIONS = { @@ -407,7 +407,7 @@ void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderSta // Add the file string input emitLineBegin(stage); emitString("string " + input->getVariable() + " = \"" + valueStr + "\"", stage); - emitMetadata(input, stage); + emitMetadata(input, context, stage); emitString(",", stage); emitLineEnd(stage, false); @@ -424,7 +424,7 @@ void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderSta emitLineBegin(stage); emitString(type + " " + input->getVariable(), stage); - string value = _syntax->getValue(input, true); + string value = _syntax->getValue(input, context, true); const string& geomprop = input->getGeomProp(); if (!geomprop.empty()) { @@ -440,7 +440,7 @@ void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderSta } emitString(" = " + value, stage); - emitMetadata(input, stage); + emitMetadata(input, context, stage); } if (i < inputs.size()) @@ -465,7 +465,7 @@ void OslShaderGenerator::emitShaderOutputs(const VariableBlock& outputs, ShaderS } } -void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage) const +void OslShaderGenerator::emitMetadata(const ShaderPort* port, const GenContext& context, ShaderStage& stage) const { static const std::unordered_map UI_WIDGET_METADATA = { @@ -500,7 +500,7 @@ void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage { const string& delim = (widgetMetadata || j < metadata->size() - 1) ? Syntax::COMMA : EMPTY_STRING; const string& dataType = _syntax->getTypeName(data.type); - const string dataValue = _syntax->getValue(data.type, *data.value, true); + const string dataValue = _syntax->getValue(data.type, *data.value, context, true); metadataLines.push_back(dataType + " " + data.name + " = " + dataValue + delim); } } @@ -508,7 +508,7 @@ void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage if (widgetMetadata) { const string& dataType = _syntax->getTypeName(widgetMetadata->type); - const string dataValue = _syntax->getValue(widgetMetadata->type, *widgetMetadata->value, true); + const string dataValue = _syntax->getValue(widgetMetadata->type, *widgetMetadata->value, context, true); metadataLines.push_back(dataType + " " + widgetMetadata->name + " = " + dataValue); } if (metadataLines.size()) diff --git a/source/MaterialXGenOsl/OslShaderGenerator.h b/source/MaterialXGenOsl/OslShaderGenerator.h index e5cf13977e..95bda2dd8c 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.h +++ b/source/MaterialXGenOsl/OslShaderGenerator.h @@ -55,13 +55,13 @@ class MX_GENOSL_API OslShaderGenerator : public ShaderGenerator virtual void emitLibraryIncludes(ShaderStage& stage, GenContext& context) const; /// Emit a block of shader inputs. - virtual void emitShaderInputs(const VariableBlock& inputs, ShaderStage& stage) const; + virtual void emitShaderInputs(const VariableBlock& inputs, const GenContext& context, ShaderStage& stage) const; /// Emit a block of shader outputs. virtual void emitShaderOutputs(const VariableBlock& inputs, ShaderStage& stage) const; /// Emit metadata for a shader parameter. - virtual void emitMetadata(const ShaderPort* port, ShaderStage& stage) const; + virtual void emitMetadata(const ShaderPort* port, const GenContext& context, ShaderStage& stage) const; }; namespace OSL diff --git a/source/MaterialXGenOsl/OslSyntax.cpp b/source/MaterialXGenOsl/OslSyntax.cpp index a85821c4fd..75a6da9707 100644 --- a/source/MaterialXGenOsl/OslSyntax.cpp +++ b/source/MaterialXGenOsl/OslSyntax.cpp @@ -22,7 +22,7 @@ class OslBooleanTypeSyntax : public ScalarTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { return value.asA() ? "1" : "0"; } @@ -36,7 +36,7 @@ class OslArrayTypeSyntax : public ScalarTypeSyntax { } - string getValue(const Value& value, bool uniform) const override + string getValue(const Value& value, const GenContext& /*context*/, bool uniform) const override { if (!isEmpty(value)) { @@ -98,7 +98,7 @@ class OslStructTypeSyntax : public AggregateTypeSyntax { } - string getValue(const Value& value, bool uniform) const override + string getValue(const Value& value, const GenContext& /*context*/, bool uniform) const override { if (uniform) { @@ -126,7 +126,7 @@ class OslColor4TypeSyntax : public OslStructTypeSyntax { } - string getValue(const Value& value, bool uniform) const override + string getValue(const Value& value, const GenContext& /*context*/, bool uniform) const override { StringStream ss; @@ -162,7 +162,7 @@ class OSLMatrix3TypeSyntax : public AggregateTypeSyntax { } - string getValue(const Value& value, bool /*uniform*/) const override + string getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const override { StringVec values = splitString(value.getValueString(), ","); if (values.empty()) @@ -200,7 +200,7 @@ class OSLFilenameTypeSyntax : public AggregateTypeSyntax { } - string getValue(const ShaderPort* port, bool uniform) const override + string getValue(const ShaderPort* port, const GenContext& /*context*/, bool uniform) const override { if (!port) { @@ -213,7 +213,7 @@ class OSLFilenameTypeSyntax : public AggregateTypeSyntax return prefix + "\"" + filename + "\", \"" + port->getColorSpace() + "\"" + suffix; } - string getValue(const Value& value, bool uniform) const override + string getValue(const Value& value, const GenContext& /*context*/, bool uniform) const override { const string prefix = uniform ? "{" : getName() + "("; const string suffix = uniform ? "}" : ")"; diff --git a/source/MaterialXGenShader/GenContext.cpp b/source/MaterialXGenShader/GenContext.cpp index b197246d8c..3e323c9208 100644 --- a/source/MaterialXGenShader/GenContext.cpp +++ b/source/MaterialXGenShader/GenContext.cpp @@ -109,6 +109,63 @@ void GenContext::getOutputSuffix(const ShaderOutput* output, string& suffix) con } } +// +// TypeDesc storage methods +// + +void GenContext::registerTypeDefs(const DocumentPtr doc) +{ + getShaderGenerator().registerTypeDefs(doc, *this); +} + +void GenContext::registerTypeDesc(TypeDesc typeDesc) +{ + const string& name = typeDesc.getName(); + _typeDescMap[name] = typeDesc; + + // TODO - decide if we need to make this more threadsafe + // typeID is just a hash of the string value - so while + // we might set this entry multiple times - it's always going to be + // the same value... + // TODO - consider using OIIO::ustring? + + // TODO - decide what it means to re-register the same type over again. + // We could... + // 1) Just blindly register this type on top of the existing type name. + // 2) Ignore any types where the names are already registered + // 3) When a type is re-registered we could go compare the existing registered type against the + // new candidate type, and raise an error if they differ. + + // It's important to record the order of the struct types and register their syntax entries in the order + // they were added (this is reflected in the struct index). This ensures that any struct + // types used for members of another struct are declared in the correct order in the + // generated shader code. + if (typeDesc.isStruct()) + { + _structTypeDescOrder.emplace_back(name); + } +} + +void GenContext::registerTypeDesc(const string& name, uint8_t basetype, uint8_t semantic, uint8_t size, ConstStructMemberDescVecPtr structMembers) +{ + ConstStringPtr typeNamePtr = std::make_shared(name); + _typeDescNameStorage.push_back(typeNamePtr); + + const TypeDesc typeDesc(typeNamePtr.get(), basetype, semantic, size, structMembers); + registerTypeDesc(typeDesc); +} + +TypeDesc GenContext::getTypeDesc(const string& name) const +{ + auto it = _typeDescMap.find(name); + return it != _typeDescMap.end() ? it->second : Type::NONE; +} + +const vector& GenContext::getStructTypeDescNames() const +{ + return _structTypeDescOrder; +} + ScopedSetClosureParams::ScopedSetClosureParams(const ClosureContext::ClosureParams* params, const ShaderNode* node, ClosureContext* cct) : _cct(cct), _node(node), diff --git a/source/MaterialXGenShader/GenContext.h b/source/MaterialXGenShader/GenContext.h index 0f565ded6e..45426fdaa6 100644 --- a/source/MaterialXGenShader/GenContext.h +++ b/source/MaterialXGenShader/GenContext.h @@ -21,6 +21,9 @@ MATERIALX_NAMESPACE_BEGIN class ClosureContext; +class Document; +using DocumentPtr = shared_ptr; + /// A standard function to allow for handling of application variables for a given node using ApplicationVariableHandler = std::function; @@ -220,6 +223,24 @@ class MX_GENSHADER_API GenContext return _applicationVariableHandler; } + // + // TypeDesc methods + // + + void registerTypeDefs(const DocumentPtr doc); + + /// Register an existing TypeDesc for this context. + void registerTypeDesc(TypeDesc typeDesc); + + /// Create and register a new TypeDesc with the given configuration. + void registerTypeDesc(const string& name, uint8_t basetype, uint8_t semantic = TypeDesc::SEMANTIC_NONE, uint8_t size = 1, ConstStructMemberDescVecPtr structMembers = nullptr); + + /// Return a TypeDesc for the given type name. + /// The TypeDesc must be registered in the context first. + TypeDesc getTypeDesc(const string& name) const; + + const StringVec& getStructTypeDescNames() const; + protected: GenContext() = delete; @@ -237,6 +258,22 @@ class MX_GENSHADER_API GenContext vector _parentNodes; ApplicationVariableHandler _applicationVariableHandler; + + private: + // Internal storage of registered type descriptors + using TypeDescMap = std::unordered_map; + TypeDescMap _typeDescMap; + + // Internal storage of name strings for type descriptors + // that are created by this context. + using ConstStringPtr = std::shared_ptr; + vector _typeDescNameStorage; + + // It's important to record the order of the struct types and register their syntax entries in the order + // they were added (this is reflected in the struct index). This ensures that any struct + // types used for members of another struct are declared in the correct order in the + // generated shader code. + StringVec _structTypeDescOrder; }; /// @class ClosureContext diff --git a/source/MaterialXGenShader/HwShaderGenerator.cpp b/source/MaterialXGenShader/HwShaderGenerator.cpp index 20f91d6985..b32a28755f 100644 --- a/source/MaterialXGenShader/HwShaderGenerator.cpp +++ b/source/MaterialXGenShader/HwShaderGenerator.cpp @@ -544,7 +544,7 @@ void HwShaderGenerator::emitFunctionCall(const ShaderNode& node, GenContext& con void HwShaderGenerator::bindLightShader(const NodeDef& nodeDef, unsigned int lightTypeId, GenContext& context) { - if (TypeDesc::get(nodeDef.getType()) != Type::LIGHTSHADER) + if (context.getTypeDesc(nodeDef.getType()) != Type::LIGHTSHADER) { throw ExceptionShaderGenError("Error binding light shader. Given nodedef '" + nodeDef.getName() + "' is not of lightshader type"); } diff --git a/source/MaterialXGenShader/Nodes/BlurNode.cpp b/source/MaterialXGenShader/Nodes/BlurNode.cpp index 5826370fd0..61d61ea27f 100644 --- a/source/MaterialXGenShader/Nodes/BlurNode.cpp +++ b/source/MaterialXGenShader/Nodes/BlurNode.cpp @@ -167,7 +167,7 @@ void BlurNode::emitFunctionCall(const ShaderNode& node, GenContext& context, Sha string emitValue = "\"" + GAUSSIAN_FILTER + "\""; if (syntax.remapEnumeration(GAUSSIAN_FILTER, Type::STRING, FILTER_LIST, result)) { - emitValue = syntax.getValue(result.first, *(result.second)); + emitValue = syntax.getValue(result.first, *(result.second), context); } shadergen.emitString(" == " + emitValue + ")", stage); shadergen.emitLineEnd(stage, false); diff --git a/source/MaterialXGenShader/Nodes/SourceCodeNode.cpp b/source/MaterialXGenShader/Nodes/SourceCodeNode.cpp index 936edf9b46..eb0e87264d 100644 --- a/source/MaterialXGenShader/Nodes/SourceCodeNode.cpp +++ b/source/MaterialXGenShader/Nodes/SourceCodeNode.cpp @@ -136,7 +136,7 @@ void SourceCodeNode::emitFunctionCall(const ShaderNode& node, GenContext& contex ShaderPort v(nullptr, input->getType(), variableName, input->getValue()); shadergen.emitLineBegin(stage); const Syntax& syntax = shadergen.getSyntax(); - const string valueStr = (v.getValue() ? syntax.getValue(v.getType(), *v.getValue()) : syntax.getDefaultValue(v.getType())); + const string valueStr = (v.getValue() ? syntax.getValue(v.getType(), *v.getValue(), context) : syntax.getDefaultValue(v.getType())); const string& qualifier = syntax.getConstantQualifier(); string str = qualifier.empty() ? EMPTY_STRING : qualifier + " "; str += syntax.getTypeName(v.getType()) + " " + v.getVariable(); diff --git a/source/MaterialXGenShader/ShaderGenerator.cpp b/source/MaterialXGenShader/ShaderGenerator.cpp index 398232bf39..b078372cfb 100644 --- a/source/MaterialXGenShader/ShaderGenerator.cpp +++ b/source/MaterialXGenShader/ShaderGenerator.cpp @@ -164,7 +164,7 @@ void ShaderGenerator::emitTypeDefinitions(GenContext&, ShaderStage& stage) const } void ShaderGenerator::emitVariableDeclaration(const ShaderPort* variable, const string& qualifier, - GenContext&, ShaderStage& stage, + GenContext& context, ShaderStage& stage, bool assignValue) const { string str = qualifier.empty() ? EMPTY_STRING : qualifier + " "; @@ -187,7 +187,7 @@ void ShaderGenerator::emitVariableDeclaration(const ShaderPort* variable, const if (assignValue) { const string valueStr = (variable->getValue() ? - _syntax->getValue(variable->getType(), *variable->getValue(), true) : + _syntax->getValue(variable->getType(), *variable->getValue(), context, true) : _syntax->getDefaultValue(variable->getType(), true)); str += valueStr.empty() ? EMPTY_STRING : " = " + valueStr; } @@ -243,7 +243,7 @@ string ShaderGenerator::getUpstreamResult(const ShaderInput* input, GenContext& { if (!input->getConnection()) { - return input->getValue() ? _syntax->getValue(input->getType(), *input->getValue()) : _syntax->getDefaultValue(input->getType()); + return input->getValue() ? _syntax->getValue(input->getType(), *input->getValue(), context) : _syntax->getDefaultValue(input->getType()); } string variable = input->getConnection()->getVariable(); @@ -300,7 +300,7 @@ ShaderNodeImplPtr ShaderGenerator::getImplementation(const NodeDef& nodedef, Gen throw ExceptionShaderGenError("NodeDef '" + nodedef.getName() + "' has no outputs defined"); } - const TypeDesc outputType = TypeDesc::get(outputs[0]->getType()); + const TypeDesc outputType = context.getTypeDesc(outputs[0]->getType()); if (implElement->isA()) { @@ -344,8 +344,48 @@ ShaderNodeImplPtr ShaderGenerator::getImplementation(const NodeDef& nodedef, Gen return impl; } +void ShaderGenerator::registerTypeDefs(const DocumentPtr& doc, GenContext& context) +{ + registerBuiltinTypes(context); + registerStructTypeDefs(doc, context); +} + +void ShaderGenerator::registerBuiltinTypes(GenContext& context) +{ + // TODO - revisit this once this is merged and make this list of types + // dynamically loaded from what is present in the document - making MaterialX + // more data driven. Initially this can just be a name matching against the + // in the document against the TypeDesc object in Type::, later + // we may consider fully specifying the type in the + + // Register type descriptors for standard types. + context.registerTypeDesc(Type::NONE); + context.registerTypeDesc(Type::BOOLEAN); + context.registerTypeDesc(Type::INTEGER); + context.registerTypeDesc(Type::INTEGERARRAY); + context.registerTypeDesc(Type::FLOAT); + context.registerTypeDesc(Type::FLOATARRAY); + context.registerTypeDesc(Type::VECTOR2); + context.registerTypeDesc(Type::VECTOR3); + context.registerTypeDesc(Type::VECTOR4); + context.registerTypeDesc(Type::COLOR3); + context.registerTypeDesc(Type::COLOR4); + context.registerTypeDesc(Type::MATRIX33); + context.registerTypeDesc(Type::MATRIX44); + context.registerTypeDesc(Type::STRING); + context.registerTypeDesc(Type::FILENAME); + context.registerTypeDesc(Type::BSDF); + context.registerTypeDesc(Type::EDF); + context.registerTypeDesc(Type::VDF); + context.registerTypeDesc(Type::SURFACESHADER); + context.registerTypeDesc(Type::VOLUMESHADER); + context.registerTypeDesc(Type::DISPLACEMENTSHADER); + context.registerTypeDesc(Type::LIGHTSHADER); + context.registerTypeDesc(Type::MATERIAL); +} + /// Load any struct type definitions from the document in to the type cache. -void ShaderGenerator::loadStructTypeDefs(const DocumentPtr& doc) +void ShaderGenerator::registerStructTypeDefs(const DocumentPtr& doc, GenContext& context) { for (const auto& mxTypeDef : doc->getTypeDefs()) { @@ -356,33 +396,23 @@ void ShaderGenerator::loadStructTypeDefs(const DocumentPtr& doc) if (members.empty()) continue; - StructTypeDesc newStructTypeDesc; + auto structMemberDescs = std::make_shared(); for (const auto& member : members) { auto memberName = member->getName(); auto memberTypeName = member->getType(); - auto memberType = TypeDesc::get(memberTypeName); + auto memberType = context.getTypeDesc(memberTypeName); auto memberDefaultValue = member->getValueString(); - newStructTypeDesc.addMember(memberName, memberType, memberDefaultValue); + // If the member type is a struct itself - then we need to collect the submember information + // this is to ensure we can access it later in a context where the GenContext isn't available, + // such as the MaterialXRender. + structMemberDescs->emplace_back( StructMemberDesc(memberName, memberType, memberTypeName, memberDefaultValue) ); } - - auto structIndex = StructTypeDesc::emplace_back(newStructTypeDesc); - - TypeDesc structTypeDesc(typeDefName, TypeDesc::BASETYPE_STRUCT, TypeDesc::SEMANTIC_NONE, 1, structIndex); - - TypeDescRegistry(structTypeDesc, typeDefName); - - StructTypeDesc::get(structIndex).setTypeDesc(TypeDesc::get(typeDefName)); + context.registerTypeDesc(typeDefName, TypeDesc::BASETYPE_STRUCT, TypeDesc::SEMANTIC_NONE, 1, structMemberDescs); } - _syntax->registerStructTypeDescSyntax(); -} - -/// Clear any struct type definitions loaded -void ShaderGenerator::clearStructTypeDefs() -{ - StructTypeDesc::clear(); + _syntax->registerStructTypeDescSyntax(context); } namespace @@ -436,7 +466,7 @@ void ShaderGenerator::registerShaderMetadata(const DocumentPtr& doc, GenContext& if (def->getExportable()) { const string& attrName = def->getAttrName(); - const TypeDesc type = TypeDesc::get(def->getType()); + const TypeDesc type = context.getTypeDesc(def->getType()); if (!attrName.empty() && type != Type::NONE) { registry->addMetadata(attrName, type, def->getValue()); diff --git a/source/MaterialXGenShader/ShaderGenerator.h b/source/MaterialXGenShader/ShaderGenerator.h index a2f54fec2e..1d8573374d 100644 --- a/source/MaterialXGenShader/ShaderGenerator.h +++ b/source/MaterialXGenShader/ShaderGenerator.h @@ -191,11 +191,9 @@ class MX_GENSHADER_API ShaderGenerator return _tokenSubstitutions; } - /// Load any struct type definitions from the document in to the type cache. - void loadStructTypeDefs(const DocumentPtr& doc); - - /// Clear any struct type definitions loaded - void clearStructTypeDefs(); + // TODO - revist const-ness here - i don't think we really mean "const DocumentPtr" I think we mean "ConstDocumentPtr" + // or perhaps even just "const Document&" + void registerTypeDefs(const DocumentPtr& doc, GenContext& context); /// Register metadata that should be exported to the generated shaders. /// Supported metadata includes standard UI attributes like "uiname", "uifolder", @@ -208,6 +206,14 @@ class MX_GENSHADER_API ShaderGenerator /// export of metadata. virtual void registerShaderMetadata(const DocumentPtr& doc, GenContext& context) const; + private: + /// Load any struct type definitions from the document in to the type cache. + void registerStructTypeDefs(const DocumentPtr& doc, GenContext& context); + + protected: + /// protected so that subclasses can add additional builtin types. (MDL needs this). + virtual void registerBuiltinTypes(GenContext& context); + protected: /// Protected constructor ShaderGenerator(SyntaxPtr syntax); diff --git a/source/MaterialXGenShader/ShaderGraph.cpp b/source/MaterialXGenShader/ShaderGraph.cpp index e9a3b50b79..c616c0b2fd 100644 --- a/source/MaterialXGenShader/ShaderGraph.cpp +++ b/source/MaterialXGenShader/ShaderGraph.cpp @@ -38,7 +38,7 @@ void ShaderGraph::addInputSockets(const InterfaceElement& elem, GenContext& cont const string& portValueString = portValue ? portValue->getValueString() : EMPTY_STRING; std::pair enumResult; const string& enumNames = input->getAttribute(ValueElement::ENUM_ATTRIBUTE); - const TypeDesc portType = TypeDesc::get(input->getType()); + const TypeDesc portType = context.getTypeDesc(input->getType()); if (context.getShaderGenerator().getSyntax().remapEnumeration(portValueString, portType, enumNames, enumResult)) { inputSocket = addInputSocket(input->getName(), enumResult.first); @@ -64,15 +64,15 @@ void ShaderGraph::addInputSockets(const InterfaceElement& elem, GenContext& cont } } -void ShaderGraph::addOutputSockets(const InterfaceElement& elem) +void ShaderGraph::addOutputSockets(const InterfaceElement& elem, const GenContext& context) { for (const OutputPtr& output : elem.getActiveOutputs()) { - addOutputSocket(output->getName(), TypeDesc::get(output->getType())); + addOutputSocket(output->getName(), context.getTypeDesc(output->getType())); } if (numOutputSockets() == 0) { - addOutputSocket("out", TypeDesc::get(elem.getType())); + addOutputSocket("out", context.getTypeDesc(elem.getType())); } } @@ -238,7 +238,7 @@ void ShaderGraph::addDefaultGeomNode(ShaderInput* input, const GeomPropDef& geom { std::pair enumResult; const string& enumNames = nodeDefSpaceInput->getAttribute(ValueElement::ENUM_ATTRIBUTE); - const TypeDesc portType = TypeDesc::get(nodeDefSpaceInput->getType()); + const TypeDesc portType = context.getTypeDesc(nodeDefSpaceInput->getType()); if (context.getShaderGenerator().getSyntax().remapEnumeration(space, portType, enumNames, enumResult)) { spaceInput->setValue(enumResult.second); @@ -444,7 +444,7 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const NodeGraph& n graph->addInputSockets(*nodeDef, context); // Create output sockets from the nodegraph - graph->addOutputSockets(nodeGraph); + graph->addOutputSockets(nodeGraph, context); // Traverse all outputs and create all internal nodes for (OutputPtr graphOutput : nodeGraph.getActiveOutputs()) @@ -503,7 +503,7 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name graph->addInputSockets(*interface, context); // Create the given output socket - ShaderGraphOutputSocket* outputSocket = graph->addOutputSocket(output->getName(), TypeDesc::get(output->getType())); + ShaderGraphOutputSocket* outputSocket = graph->addOutputSocket(output->getName(), context.getTypeDesc(output->getType())); outputSocket->setPath(output->getNamePath()); const string& outputUnit = output->getUnit(); if (!outputUnit.empty()) @@ -535,7 +535,7 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name graph->addInputSockets(*nodeDef, context); // Create output sockets - graph->addOutputSockets(*nodeDef); + graph->addOutputSockets(*nodeDef, context); // Create this shader node in the graph. ShaderNodePtr newNode = ShaderNode::create(graph.get(), node->getName(), *nodeDef, context); @@ -571,7 +571,7 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name { const string& valueString = value->getValueString(); std::pair enumResult; - const TypeDesc type = TypeDesc::get(nodedefInput->getType()); + const TypeDesc type = context.getTypeDesc(nodedefInput->getType()); const string& enumNames = nodedefInput->getAttribute(ValueElement::ENUM_ATTRIBUTE); if (context.getShaderGenerator().getSyntax().remapEnumeration(valueString, type, enumNames, enumResult)) { diff --git a/source/MaterialXGenShader/ShaderGraph.h b/source/MaterialXGenShader/ShaderGraph.h index 6320d04296..bf38c1a6dc 100644 --- a/source/MaterialXGenShader/ShaderGraph.h +++ b/source/MaterialXGenShader/ShaderGraph.h @@ -136,7 +136,7 @@ class MX_GENSHADER_API ShaderGraph : public ShaderNode void addInputSockets(const InterfaceElement& elem, GenContext& context); /// Add output sockets from an interface element (nodedef, nodegraph or node) - void addOutputSockets(const InterfaceElement& elem); + void addOutputSockets(const InterfaceElement& elem, const GenContext& context); /// Traverse from the given root element and add all dependencies upstream. /// The traversal is done in the context of a material, if given, to include diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp index d52810ffc4..ddede9b79e 100644 --- a/source/MaterialXGenShader/ShaderNode.cpp +++ b/source/MaterialXGenShader/ShaderNode.cpp @@ -179,7 +179,7 @@ ShaderNodePtr ShaderNode::create(const ShaderGraph* parent, const string& name, // Create interface from nodedef for (const ValueElementPtr& port : nodeDef.getActiveValueElements()) { - const TypeDesc portType = TypeDesc::get(port->getType()); + const TypeDesc portType = context.getTypeDesc(port->getType()); if (port->isA()) { newNode->addOutput(port->getName(), portType); @@ -216,7 +216,7 @@ ShaderNodePtr ShaderNode::create(const ShaderGraph* parent, const string& name, // Add a default output if needed if (newNode->numOutputs() == 0) { - newNode->addOutput("out", TypeDesc::get(nodeDef.getType())); + newNode->addOutput("out", context.getTypeDesc(nodeDef.getType())); } const string& nodeDefName = nodeDef.getName(); @@ -349,7 +349,7 @@ void ShaderNode::initialize(const Node& node, const NodeDef& nodeDef, GenContext const string& valueString = portValue ? portValue->getValueString() : EMPTY_STRING; std::pair enumResult; const string& enumNames = nodeDefInput->getAttribute(ValueElement::ENUM_ATTRIBUTE); - const TypeDesc type = TypeDesc::get(nodeDefInput->getType()); + const TypeDesc type = context.getTypeDesc(nodeDefInput->getType()); if (context.getShaderGenerator().getSyntax().remapEnumeration(valueString, type, enumNames, enumResult)) { input->setValue(enumResult.second); diff --git a/source/MaterialXGenShader/ShaderNode.h b/source/MaterialXGenShader/ShaderNode.h index 4f2f44e27b..daa244e611 100644 --- a/source/MaterialXGenShader/ShaderNode.h +++ b/source/MaterialXGenShader/ShaderNode.h @@ -246,6 +246,7 @@ class MX_GENSHADER_API ShaderPort : public std::enable_shared_from_thissecond]; } -string Syntax::getValue(const ShaderPort* port, bool uniform) const +string Syntax::getValue(const ShaderPort* port, const GenContext& context, bool uniform) const { const TypeSyntax& syntax = getTypeSyntax(port->getType()); - return syntax.getValue(port, uniform); + return syntax.getValue(port, context, uniform); } -string Syntax::getValue(TypeDesc type, const Value& value, bool uniform) const +string Syntax::getValue(TypeDesc type, const Value& value, const GenContext& context, bool uniform) const { const TypeSyntax& syntax = getTypeSyntax(type); - return syntax.getValue(value, uniform); + return syntax.getValue(value, context, uniform); } const string& Syntax::getDefaultValue(TypeDesc type, bool uniform) const @@ -190,24 +191,26 @@ bool Syntax::remapEnumeration(const string&, TypeDesc, const string&, std::pair< return false; } -void Syntax::registerStructTypeDescSyntax() +void Syntax::registerStructTypeDescSyntax(const GenContext& context) { - for (const auto& typeName : StructTypeDesc::getStructTypeNames()) + for (const auto& typeDescName : context.getStructTypeDescNames()) { - const auto& typeDesc = TypeDesc::get(typeName); - const auto& structTypeDesc = StructTypeDesc::get(typeDesc.getStructIndex()); + const TypeDesc& typeDesc = context.getTypeDesc(typeDescName); + auto structMemberDescs = typeDesc.getStructMembers(); + if (!typeDesc.isStruct() || !structMemberDescs) + continue; - string structTypeName = typeName; - string defaultValue = typeName + "( "; + string structTypeName = typeDesc.getName(); + string defaultValue = structTypeName + "( "; string uniformDefaultValue = EMPTY_STRING; string typeAlias = EMPTY_STRING; string typeDefinition = "struct " + structTypeName + " { "; - for (const auto& x : structTypeDesc.getMembers()) + for (const auto& structMemberDesc : *structMemberDescs) { - string memberName = x._name; - string memberType = x._typeDesc.getName(); - string memberDefaultValue = x._defaultValueStr; + string memberName = structMemberDesc.getName(); + string memberType = structMemberDesc.getTypeDesc().getName(); + string memberDefaultValue = structMemberDesc.getDefaultValueStr(); defaultValue += memberDefaultValue + ", "; typeDefinition += memberType + " " + memberName + "; "; @@ -233,13 +236,13 @@ TypeSyntax::TypeSyntax(const string& name, const string& defaultValue, const str { } -string TypeSyntax::getValue(const ShaderPort* port, bool uniform) const +string TypeSyntax::getValue(const ShaderPort* port, const GenContext& context, bool uniform) const { if (!port || !port->getValue()) { return getDefaultValue(uniform); } - return getValue(*port->getValue(), uniform); + return getValue(*port->getValue(), context, uniform); } ScalarTypeSyntax::ScalarTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue, @@ -248,7 +251,7 @@ ScalarTypeSyntax::ScalarTypeSyntax(const string& name, const string& defaultValu { } -string ScalarTypeSyntax::getValue(const Value& value, bool /*uniform*/) const +string ScalarTypeSyntax::getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const { return value.getValueString(); } @@ -259,7 +262,7 @@ StringTypeSyntax::StringTypeSyntax(const string& name, const string& defaultValu { } -string StringTypeSyntax::getValue(const Value& value, bool /*uniform*/) const +string StringTypeSyntax::getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const { return "\"" + value.getValueString() + "\""; } @@ -270,7 +273,7 @@ AggregateTypeSyntax::AggregateTypeSyntax(const string& name, const string& defau { } -string AggregateTypeSyntax::getValue(const Value& value, bool /*uniform*/) const +string AggregateTypeSyntax::getValue(const Value& value, const GenContext& /*context*/, bool /*uniform*/) const { const string valueString = value.getValueString(); return valueString.empty() ? valueString : getName() + "(" + valueString + ")"; @@ -282,7 +285,7 @@ StructTypeSyntax::StructTypeSyntax(const Syntax* parentSyntax, const string& nam { } -string StructTypeSyntax::getValue(const Value& value, bool /*uniform*/) const +string StructTypeSyntax::getValue(const Value& value, const GenContext& context, bool /*uniform*/) const { const AggregateValue& aggValue = static_cast(value); @@ -295,10 +298,10 @@ string StructTypeSyntax::getValue(const Value& value, bool /*uniform*/) const separator = ";"; const string& memberTypeName = memberValue->getTypeString(); - TypeDesc memberTypeDesc = TypeDesc::get(memberTypeName); + TypeDesc memberTypeDesc = context.getTypeDesc(memberTypeName); // Recursively use the syntax to generate the output, so we can support nested structs. - const string valueStr = _parentSyntax->getValue(memberTypeDesc, *memberValue, true); + const string valueStr = _parentSyntax->getValue(memberTypeDesc, *memberValue, context, true); result += valueStr; } diff --git a/source/MaterialXGenShader/Syntax.h b/source/MaterialXGenShader/Syntax.h index 6f16633b59..c087ee40d3 100644 --- a/source/MaterialXGenShader/Syntax.h +++ b/source/MaterialXGenShader/Syntax.h @@ -70,7 +70,7 @@ class MX_GENSHADER_API Syntax /// Multiple calls will add to the internal set of tokens. void registerInvalidTokens(const StringMap& tokens); - virtual void registerStructTypeDescSyntax(); + virtual void registerStructTypeDescSyntax(const GenContext& context); /// Returns a set of names that are reserved words for this language syntax. const StringSet& getReservedWords() const { return _reservedWords; } @@ -109,11 +109,11 @@ class MX_GENSHADER_API Syntax [[deprecated]] const string& getDefaultValue(const TypeDesc* type, bool uniform = false) const { return getDefaultValue(*type, uniform); } /// Returns the value string for a given type and value object - virtual string getValue(TypeDesc type, const Value& value, bool uniform = false) const; - [[deprecated]] string getValue(const TypeDesc* type, const Value& value, bool uniform = false) const { return getValue(*type, value, uniform); } + virtual string getValue(TypeDesc type, const Value& value, const GenContext& context, bool uniform = false) const; + [[deprecated]] string getValue(const TypeDesc* type, const Value& value, const GenContext& context, bool uniform = false) const { return getValue(*type, value, context, uniform); } /// Returns the value string for a given shader port object - virtual string getValue(const ShaderPort* port, bool uniform = false) const; + virtual string getValue(const ShaderPort* port, const GenContext& context, bool uniform = false) const; /// Returns a type qualifier to be used when declaring types for input variables. /// Default implementation returns empty string and derived syntax classes should @@ -258,11 +258,11 @@ class MX_GENSHADER_API TypeSyntax /// Returns a value formatted according to this type syntax. /// The value is constructed from the given shader port object. - virtual string getValue(const ShaderPort* port, bool uniform) const; + virtual string getValue(const ShaderPort* port, const GenContext& context, bool uniform) const; /// Returns a value formatted according to this type syntax. /// The value is constructed from the given value object. - virtual string getValue(const Value& value, bool uniform) const = 0; + virtual string getValue(const Value& value, const GenContext& context, bool uniform) const = 0; protected: /// Protected constructor @@ -286,7 +286,7 @@ class MX_GENSHADER_API ScalarTypeSyntax : public TypeSyntax ScalarTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue, const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING); - string getValue(const Value& value, bool uniform) const override; + string getValue(const Value& value, const GenContext& context, bool uniform) const override; }; /// Specialization of TypeSyntax for string types. @@ -296,7 +296,7 @@ class MX_GENSHADER_API StringTypeSyntax : public ScalarTypeSyntax StringTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue, const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING); - string getValue(const Value& value, bool uniform) const override; + string getValue(const Value& value, const GenContext& context, bool uniform) const override; }; /// Specialization of TypeSyntax for aggregate types. @@ -307,7 +307,7 @@ class MX_GENSHADER_API AggregateTypeSyntax : public TypeSyntax const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING, const StringVec& members = EMPTY_MEMBERS); - string getValue(const Value& value, bool uniform) const override; + string getValue(const Value& value, const GenContext& context, bool uniform) const override; }; /// Specialization of TypeSyntax for aggregate types. @@ -318,7 +318,7 @@ class MX_GENSHADER_API StructTypeSyntax : public TypeSyntax const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING, const StringVec& members = EMPTY_MEMBERS); - string getValue(const Value& value, bool uniform) const override; + string getValue(const Value& value, const GenContext& context, bool uniform) const override; protected: const Syntax* _parentSyntax; diff --git a/source/MaterialXGenShader/TypeDesc.cpp b/source/MaterialXGenShader/TypeDesc.cpp index 5d51680211..2ff035de56 100644 --- a/source/MaterialXGenShader/TypeDesc.cpp +++ b/source/MaterialXGenShader/TypeDesc.cpp @@ -6,74 +6,17 @@ #include #include +#include MATERIALX_NAMESPACE_BEGIN -namespace -{ - -using TypeDescMap = std::unordered_map; -using TypeDescNameMap = std::unordered_map; - -// Internal storage of registered type descriptors -TypeDescMap& typeMap() -{ - static TypeDescMap map; - return map; -} - -TypeDescNameMap& typeNameMap() -{ - static TypeDescNameMap map; - return map; -} - -using StructTypeDescStorage = vector; -StructTypeDescStorage& structTypeStorage() -{ - // TODO: Our use of the singleton pattern for TypeDescMap and StructTypeDestStorage - // is not thread-safe, and we should consider replacing this with thread-local - // data in the GenContext object. - static StructTypeDescStorage storage; - return storage; -} - -} // anonymous namespace - const string TypeDesc::NONE_TYPE_NAME = "none"; -const string& TypeDesc::getName() const -{ - TypeDescNameMap& typenames = typeNameMap(); - auto it = typenames.find(_id); - return it != typenames.end() ? it->second : NONE_TYPE_NAME; -} - -TypeDesc TypeDesc::get(const string& name) -{ - TypeDescMap& types = typeMap(); - auto it = types.find(name); - return it != types.end() ? it->second : Type::NONE; -} - -void TypeDesc::remove(const string& name) -{ - TypeDescNameMap& typenames = typeNameMap(); - - TypeDescMap& types = typeMap(); - - auto it = types.find(name); - if (it == types.end()) - return; - - typenames.erase(it->second.typeId()); - types.erase(it); -} - ValuePtr TypeDesc::createValueFromStrings(const string& value) const { ValuePtr newValue = Value::createValueFromStrings(value, getName()); - if (!isStruct()) + auto structMemberDescs = getStructMembers(); + if (!isStruct() || !structMemberDescs) return newValue; // Value::createValueFromStrings() can only create a valid Value for a struct if it is passed @@ -81,134 +24,21 @@ ValuePtr TypeDesc::createValueFromStrings(const string& value) const // So if this is a struct type we need to create a new AggregateValue. StringVec subValues = parseStructValueString(value); + AggregateValuePtr result = AggregateValue::createAggregateValue(getName()); - AggregateValuePtr result = AggregateValue::createAggregateValue(getName()); - auto structTypeDesc = StructTypeDesc::get(getStructIndex()); - const auto& members = structTypeDesc.getMembers(); - - if (subValues.size() != members.size()) + if (subValues.size() != structMemberDescs->size()) { std::stringstream ss; - ss << "Wrong number of initializers - expect " << members.size(); + ss << "Wrong number of initializers - expect " << structMemberDescs->size(); throw ExceptionShaderGenError(ss.str()); } - for (size_t i = 0; i < members.size(); ++i) + for (size_t i = 0; i < structMemberDescs->size(); ++i) { - result->appendValue( members[i]._typeDesc.createValueFromStrings(subValues[i])); + result->appendValue( structMemberDescs->at(i).getTypeDesc().createValueFromStrings(subValues[i])); } return result; } -TypeDescRegistry::TypeDescRegistry(TypeDesc type, const string& name) -{ - TypeDescMap& types = typeMap(); - TypeDescNameMap& typenames = typeNameMap(); - types[name] = type; - typenames[type.typeId()] = name; -} - -namespace Type -{ - -/// -/// Register type descriptors for standard types. -/// -TYPEDESC_REGISTER_TYPE(NONE, "none") -TYPEDESC_REGISTER_TYPE(BOOLEAN, "boolean") -TYPEDESC_REGISTER_TYPE(INTEGER, "integer") -TYPEDESC_REGISTER_TYPE(INTEGERARRAY, "integerarray") -TYPEDESC_REGISTER_TYPE(FLOAT, "float") -TYPEDESC_REGISTER_TYPE(FLOATARRAY, "floatarray") -TYPEDESC_REGISTER_TYPE(VECTOR2, "vector2") -TYPEDESC_REGISTER_TYPE(VECTOR3, "vector3") -TYPEDESC_REGISTER_TYPE(VECTOR4, "vector4") -TYPEDESC_REGISTER_TYPE(COLOR3, "color3") -TYPEDESC_REGISTER_TYPE(COLOR4, "color4") -TYPEDESC_REGISTER_TYPE(MATRIX33, "matrix33") -TYPEDESC_REGISTER_TYPE(MATRIX44, "matrix44") -TYPEDESC_REGISTER_TYPE(STRING, "string") -TYPEDESC_REGISTER_TYPE(FILENAME, "filename") -TYPEDESC_REGISTER_TYPE(BSDF, "BSDF") -TYPEDESC_REGISTER_TYPE(EDF, "EDF") -TYPEDESC_REGISTER_TYPE(VDF, "VDF") -TYPEDESC_REGISTER_TYPE(SURFACESHADER, "surfaceshader") -TYPEDESC_REGISTER_TYPE(VOLUMESHADER, "volumeshader") -TYPEDESC_REGISTER_TYPE(DISPLACEMENTSHADER, "displacementshader") -TYPEDESC_REGISTER_TYPE(LIGHTSHADER, "lightshader") -TYPEDESC_REGISTER_TYPE(MATERIAL, "material") - -} // namespace Type - -// -// StructTypeDesc methods -// - -void StructTypeDesc::addMember(const string& name, TypeDesc type, string defaultValueStr) -{ - _members.emplace_back(StructTypeDesc::StructMemberTypeDesc(name, type, defaultValueStr)); -} - -vector StructTypeDesc::getStructTypeNames() -{ - StructTypeDescStorage& structs = structTypeStorage(); - vector structNames; - for (const auto& x : structs) - { - structNames.emplace_back(x.typeDesc().getName()); - } - return structNames; -} - -StructTypeDesc& StructTypeDesc::get(unsigned int index) -{ - StructTypeDescStorage& structs = structTypeStorage(); - return structs[index]; -} - -uint16_t StructTypeDesc::emplace_back(StructTypeDesc structTypeDesc) -{ - StructTypeDescStorage& structs = structTypeStorage(); - if (structs.size() >= std::numeric_limits::max()) - { - throw ExceptionShaderGenError("Maximum number of custom struct types has been exceeded."); - } - uint16_t index = static_cast(structs.size()); - structs.emplace_back(structTypeDesc); - return index; -} - -void StructTypeDesc::clear() -{ - StructTypeDescStorage& structs = structTypeStorage(); - for (const auto& structType: structs) - { - // Need to add typeID to structTypeDesc - and use it here to reference back to typeDesc obj and remove it. - TypeDesc::remove(structType.typeDesc().getName()); - } - structs.clear(); -} - -const string& StructTypeDesc::getName() const -{ - return _typedesc.getName(); -} - -const vector& StructTypeDesc::getMembers() const -{ - return _members; -} - -TypeDesc createStructTypeDesc(std::string_view name) -{ - return {name, TypeDesc::BASETYPE_STRUCT}; -} - -void registerStructTypeDesc(std::string_view name) -{ - auto structTypeDesc = createStructTypeDesc(name); - TypeDescRegistry register_struct(structTypeDesc, string(name)); -} - MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenShader/TypeDesc.h b/source/MaterialXGenShader/TypeDesc.h index 95d2851915..1ec8d10b04 100644 --- a/source/MaterialXGenShader/TypeDesc.h +++ b/source/MaterialXGenShader/TypeDesc.h @@ -12,10 +12,14 @@ #include #include -#include - MATERIALX_NAMESPACE_BEGIN +class StructMemberDesc; +using StructMemberDescVec = vector; +using ConstStructMemberDescVecPtr = shared_ptr; + +// TODO - update this documentation once the code has been reviewed... + /// @class TypeDesc /// A type descriptor for MaterialX data types. /// @@ -29,7 +33,7 @@ MATERIALX_NAMESPACE_BEGIN /// must be done in order to access the type's name later using getName() and to find the /// type by name using TypeDesc::get(). /// -/// The class is a POD type of 64-bits and can efficiently be stored and passed by value. +/// The class is a POD type and can efficiently be stored and passed by value. /// Type compare operations and hash operations are done using a precomputed hash value. /// class MX_GENSHADER_API TypeDesc @@ -61,22 +65,24 @@ class MX_GENSHADER_API TypeDesc }; /// Empty constructor. - constexpr TypeDesc() noexcept : + TypeDesc() noexcept : _id(0), _basetype(BASETYPE_NONE), _semantic(SEMANTIC_NONE), _size(0), - _structIndex(0) + _name(nullptr), + _structMembers(nullptr) { } /// Constructor. - constexpr TypeDesc(std::string_view name, uint8_t basetype, uint8_t semantic = SEMANTIC_NONE, uint16_t size = 1, uint16_t structIndex = 0) noexcept : - _id(constexpr_hash(name)), // Note: We only store the hash to keep the class size minimal. + TypeDesc(const string* name, uint8_t basetype, uint8_t semantic = SEMANTIC_NONE, uint8_t size = 1, ConstStructMemberDescVecPtr structMembers = nullptr) noexcept : + _id(string_hash(*name)), _basetype(basetype), _semantic(semantic), _size(size), - _structIndex(structIndex) + _name(name), + _structMembers(structMembers) { } @@ -85,7 +91,7 @@ class MX_GENSHADER_API TypeDesc uint32_t typeId() const { return _id; } /// Return the name of the type. - const string& getName() const; + const string& getName() const { return *_name; } /// Return the basetype for the type. unsigned char getBaseType() const { return _basetype; } @@ -123,8 +129,7 @@ class MX_GENSHADER_API TypeDesc /// Return true if the type represents a struct. bool isStruct() const { return _basetype == BASETYPE_STRUCT; } - /// Return the index for the struct member information in StructTypeDesc, the result is invalid if `isStruct()` returns false. - uint16_t getStructIndex() const { return _structIndex; } + ConstStructMemberDescVecPtr getStructMembers() const { return _structMembers; } /// Equality operator bool operator==(TypeDesc rhs) const @@ -153,49 +158,31 @@ class MX_GENSHADER_API TypeDesc } }; - /// Return a type description by name. - /// If no type is found Type::NONE is returned. - static TypeDesc get(const string& name); - - /// Remove a type description by name, if it exists. - static void remove(const string& name); - static const string NONE_TYPE_NAME; - /// Create a Value from a string for a given typeDesc + /// Create a Value from a string for this TypeDesc ValuePtr createValueFromStrings(const string& value) const; private: - /// Simple constexpr hash function, good enough for the small set of short strings that + /// Simple hash function, good enough for the small set of short strings that /// are used for our data type names. - constexpr uint32_t constexpr_hash(std::string_view str, uint32_t n = 0, uint32_t h = 2166136261) + uint32_t string_hash(const string& str, uint32_t n = 0, uint32_t h = 2166136261) { - return n == uint32_t(str.size()) ? h : constexpr_hash(str, n + 1, (h * 16777619) ^ (str[n])); + return n == uint32_t(str.size()) ? h : string_hash(str, n + 1, (h * 16777619) ^ (str[n])); } uint32_t _id; uint8_t _basetype; uint8_t _semantic; uint16_t _size; - uint16_t _structIndex; -}; - -/// @class TypeDescRegistry -/// Helper class for type registration. -class MX_GENSHADER_API TypeDescRegistry -{ - public: - TypeDescRegistry(TypeDesc type, const string& name); + const string* _name; + ConstStructMemberDescVecPtr _structMembers; }; /// Macro to define global type descriptions for commonly used types. #define TYPEDESC_DEFINE_TYPE(T, name, basetype, semantic, size) \ - static constexpr TypeDesc T(name, basetype, semantic, size); - -/// Macro to register a previously defined type in the type registry. -/// Registration must be done in order for the type to be searchable by name. -#define TYPEDESC_REGISTER_TYPE(T, name) \ - TypeDescRegistry register_##T(T, name); + inline const string* T##_typeName() { static const string _typeNameStorage = name; return &_typeNameStorage; } \ + static const TypeDesc T(T##_typeName(), basetype, semantic, size); namespace Type { @@ -229,6 +216,7 @@ TYPEDESC_DEFINE_TYPE(MATERIAL, "material", TypeDesc::BASETYPE_NONE, TypeDesc::SE } // namespace Type +// TODO - update this documentation once the code has been reviewed. /// @class StructTypeDesc /// A type descriptor for MaterialX struct types. @@ -238,47 +226,27 @@ TYPEDESC_DEFINE_TYPE(MATERIAL, "material", TypeDesc::BASETYPE_NONE, TypeDesc::SE /// the type also needs to have an associated StructTypeDesc that describes the members /// of the struct. /// -class MX_GENSHADER_API StructTypeDesc + +class StructMemberDesc { public: - struct StructMemberTypeDesc + StructMemberDesc(string name, TypeDesc typeDesc, string typeName, string defaultValueStr): + _name(name), + _typeDesc(typeDesc), + _typeName(typeName), + _defaultValueStr(defaultValueStr) { - StructMemberTypeDesc(string name, TypeDesc typeDesc, string defaultValueStr) : - _name(name), _typeDesc(typeDesc), _defaultValueStr(defaultValueStr) - { - } - string _name; - TypeDesc _typeDesc; - string _defaultValueStr; - }; - - /// Empty constructor. - StructTypeDesc() noexcept{} - - void addMember(const string& name, TypeDesc type, string defaultValueStr); - void setTypeDesc(TypeDesc typedesc) { _typedesc = typedesc; } - - /// Return a type description by index. - static StructTypeDesc& get(unsigned int index); - static vector getStructTypeNames(); - static uint16_t emplace_back(StructTypeDesc structTypeDesc); - static void clear(); - - TypeDesc typeDesc() const { return _typedesc; } - - const string& getName() const; - - const vector& getMembers() const; + } + const string& getName() const { return _name; } + TypeDesc getTypeDesc() const { return _typeDesc; } + const string& getTypeName() const { return _typeName; } + const string& getDefaultValueStr() const { return _defaultValueStr; } private: - TypeDesc _typedesc; - vector _members; -}; - -class MX_GENSHADER_API StructTypeDescRegistry -{ - public: - StructTypeDescRegistry(); + string _name; + TypeDesc _typeDesc; + string _typeName; + string _defaultValueStr; }; MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenShader/UnitSystem.cpp b/source/MaterialXGenShader/UnitSystem.cpp index 232351b526..62e9522f24 100644 --- a/source/MaterialXGenShader/UnitSystem.cpp +++ b/source/MaterialXGenShader/UnitSystem.cpp @@ -38,7 +38,7 @@ ShaderNodeImplPtr ScalarUnitNode::create(LinearUnitConverterPtr scalarUnitConver return std::make_shared(scalarUnitConverter); } -void ScalarUnitNode::initialize(const InterfaceElement& element, GenContext& /*context*/) +void ScalarUnitNode::initialize(const InterfaceElement& element, GenContext&) { _name = element.getName(); diff --git a/source/MaterialXGenShader/Util.cpp b/source/MaterialXGenShader/Util.cpp index af34fa1b2a..63ab8cc6c0 100644 --- a/source/MaterialXGenShader/Util.cpp +++ b/source/MaterialXGenShader/Util.cpp @@ -228,8 +228,7 @@ bool isTransparentShaderGraph(OutputPtr output, const string& target, NodePtr in NodeDefPtr nodeDef = node->getNodeDef(); if (nodeDef) { - const TypeDesc nodeDefType = TypeDesc::get(nodeDef->getType()); - if (nodeDefType == Type::BSDF) + if (nodeDef->getType() == Type::BSDF.getName()) { InterfaceElementPtr impl = nodeDef->getImplementation(target); if (impl && impl->isA()) diff --git a/source/MaterialXGraphEditor/RenderView.cpp b/source/MaterialXGraphEditor/RenderView.cpp index 92cd8f07c7..2c7f977bbb 100644 --- a/source/MaterialXGraphEditor/RenderView.cpp +++ b/source/MaterialXGraphEditor/RenderView.cpp @@ -632,7 +632,7 @@ void RenderView::initContext(mx::GenContext& context) context.getOptions().targetDistanceUnit = "meter"; // Register struct type definitions - context.getShaderGenerator().loadStructTypeDefs(_document); + context.registerTypeDefs(_document); } void RenderView::drawContents() diff --git a/source/MaterialXRender/LightHandler.cpp b/source/MaterialXRender/LightHandler.cpp index 0b841e5dc8..46f77c98cb 100644 --- a/source/MaterialXRender/LightHandler.cpp +++ b/source/MaterialXRender/LightHandler.cpp @@ -41,8 +41,7 @@ void LightHandler::findLights(DocumentPtr doc, vector& lights) lights.clear(); for (NodePtr node : doc->getNodes()) { - const TypeDesc type = TypeDesc::get(node->getType()); - if (type == Type::LIGHTSHADER) + if (node->getType() == Type::LIGHTSHADER.getName()) { lights.push_back(node); } diff --git a/source/MaterialXRender/TextureBaker.inl b/source/MaterialXRender/TextureBaker.inl index ff05cb49e7..94140ec965 100644 --- a/source/MaterialXRender/TextureBaker.inl +++ b/source/MaterialXRender/TextureBaker.inl @@ -498,6 +498,7 @@ DocumentPtr TextureBaker::bakeMaterialToDoc(DocumentPtr doc DefaultColorManagementSystemPtr cms = DefaultColorManagementSystem::create(genContext.getShaderGenerator().getTarget()); cms->loadLibrary(doc); genContext.registerSourceCodeSearchPath(searchPath); + genContext.registerTypeDefs(doc); genContext.getShaderGenerator().setColorManagementSystem(cms); // Compute the material tag set. diff --git a/source/MaterialXRender/Util.cpp b/source/MaterialXRender/Util.cpp index c206514412..d3cdaafa0a 100644 --- a/source/MaterialXRender/Util.cpp +++ b/source/MaterialXRender/Util.cpp @@ -157,12 +157,23 @@ unsigned int getUIProperties(InputPtr input, const string& target, UIProperties& if (!enumValuesAttr.empty()) { const string COMMA_SEPARATOR = ","; - const TypeDesc typeDesc = TypeDesc::get(input->getType()); string valueString; size_t index = 0; - for (const string& val : splitString(enumValuesAttr, COMMA_SEPARATOR)) + vector enumValuesParts = splitString(enumValuesAttr, COMMA_SEPARATOR); + + // Infer the size of the type by making an assumption the correct number of elements + // are provided in the value. + // TODO - This assumption can ultimately be avoided if we move to a more complete description + // of the base types in the data library. + // ie. + // which might allow us to move away from the hardcoded internal definition found in + // TypeDesc.h + // TYPEDESC_DEFINE_TYPE(COLOR3, "color3", TypeDesc::BASETYPE_FLOAT, TypeDesc::SEMANTIC_COLOR, 3) + auto typeDescSize = enumValuesParts.size() / uiProperties.enumeration.size(); + + for (const string& val : enumValuesParts) { - if (index < typeDesc.getSize() - 1) + if (index < typeDescSize - 1) { valueString += val + COMMA_SEPARATOR; index++; @@ -170,7 +181,7 @@ unsigned int getUIProperties(InputPtr input, const string& target, UIProperties& else { valueString += val; - uiProperties.enumerationValues.push_back(typeDesc.createValueFromStrings(valueString)); + uiProperties.enumerationValues.push_back(Value::createValueFromStrings(valueString, input->getType())); valueString.clear(); index = 0; } diff --git a/source/MaterialXRenderGlsl/GlslMaterial.cpp b/source/MaterialXRenderGlsl/GlslMaterial.cpp index 064ab898ff..788af713b2 100644 --- a/source/MaterialXRenderGlsl/GlslMaterial.cpp +++ b/source/MaterialXRenderGlsl/GlslMaterial.cpp @@ -360,7 +360,7 @@ void GlslMaterial::modifyUniform(const std::string& path, ConstValuePtr value, s { valueString = value->getValueString(); } - uniform->setValue(uniform->getType().createValueFromStrings(valueString)); + uniform->setValue(Value::createValueFromStrings(valueString, uniform->getType().getName())); if (_doc) { ElementPtr element = _doc->getDescendant(uniform->getPath()); diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp index b63e1faecc..9bf222024b 100644 --- a/source/MaterialXRenderGlsl/GlslProgram.cpp +++ b/source/MaterialXRenderGlsl/GlslProgram.cpp @@ -924,7 +924,7 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() continue; } - // TODO: Shoud we really create new ones here each update? + // TODO: Should we really create new ones here each update? InputPtr inputPtr = std::make_shared(-1, -1, int(v->getType().getSize()), EMPTY_STRING); _uniformList[v->getVariable()] = inputPtr; inputPtr->isConstant = true; @@ -954,16 +954,18 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() const auto populateUniformInput = [this, variablePath, variableUnit, variableColorspace, variableSemantic, &errors, uniforms, &uniformTypeMismatchFound] - (TypeDesc typedesc, const string& variableName, ConstValuePtr variableValue) -> void + (TypeDesc variableTypeDesc, const string& variableTypeName, const string& variableName, ConstValuePtr variableValue) -> void { auto populateUniformInput_impl = [this, variablePath, variableUnit, variableColorspace, variableSemantic, &errors, uniforms, &uniformTypeMismatchFound] - (TypeDesc typedesc, const string& variableName, ConstValuePtr variableValue, auto& populateUniformInput_ref) -> void + (TypeDesc variableTypeDesc, const string& variableTypeName, const string& variableName, ConstValuePtr variableValue, auto& populateUniformInput_ref) -> void { - if (!typedesc.isStruct()) + + auto variableStructMembers = variableTypeDesc.getStructMembers(); + if (!variableTypeDesc.isStruct() || !variableStructMembers) { // Handle non-struct types - int glType = mapTypeToOpenGLType(typedesc); + int glType = mapTypeToOpenGLType(variableTypeDesc); // There is no way to match with an unnamed variable if (variableName.empty()) @@ -987,14 +989,14 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() input->value = variableValue; if (input->gltype == glType) { - input->typeString = typedesc.getName(); + input->typeString = variableTypeName; } else { errors.push_back( "Pixel shader uniform block type mismatch [" + uniforms.getName() + "]. " + "Name: \"" + variableName - + "\". Type: \"" + typedesc.getName() + + "\". Type: \"" + variableTypeName + "\". Semantic: \"" + variableSemantic + "\". Value: \"" + (variableValue ? variableValue->getValueString() : "") + "\". Unit: \"" + (!variableUnit.empty() ? variableUnit : "") @@ -1007,26 +1009,22 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() else { // If we're a struct - we need to loop over each member - auto structTypeDesc = StructTypeDesc::get(typedesc.getStructIndex()); auto aggregateValue = std::static_pointer_cast(variableValue); - - const auto& members = structTypeDesc.getMembers(); - for (size_t i = 0, n = members.size(); i < n; ++i) + for (size_t i = 0, n = variableStructMembers->size(); i < n; ++i) { - const auto& member = members[i]; - auto memberTypeDesc = member._typeDesc; - auto memberVariableName = variableName + "." + member._name; + const auto& structMember = variableStructMembers->at(i); + auto memberVariableName = variableName + "." + structMember.getName(); auto memberVariableValue = aggregateValue->getMemberValue(i); - populateUniformInput_ref(memberTypeDesc, memberVariableName, memberVariableValue, populateUniformInput_ref); + populateUniformInput_ref(structMember.getTypeDesc(), structMember.getTypeName(), memberVariableName, memberVariableValue, populateUniformInput_ref); } } }; - return populateUniformInput_impl(typedesc, variableName, variableValue, populateUniformInput_impl); + return populateUniformInput_impl(variableTypeDesc, variableTypeName, variableName, variableValue, populateUniformInput_impl); }; - populateUniformInput(v->getType(), v->getVariable(), v->getValue()); + populateUniformInput(v->getType(), v->getType().getName(), v->getVariable(), v->getValue()); } } @@ -1140,12 +1138,12 @@ const GlslProgram::InputMap& GlslProgram::updateAttributesList() if (string::npos != sattributeName.find(colorSet)) { string setNumber = sattributeName.substr(colorSet.size(), sattributeName.size()); - inputPtr->value = Type::INTEGER.createValueFromStrings(setNumber); + inputPtr->value = Value::createValueFromStrings(setNumber, getTypeString()); } else if (string::npos != sattributeName.find(uvSet)) { string setNumber = sattributeName.substr(uvSet.size(), sattributeName.size()); - inputPtr->value = Type::INTEGER.createValueFromStrings(setNumber); + inputPtr->value = Value::createValueFromStrings(setNumber, getTypeString()); } _attributeList[sattributeName] = inputPtr; diff --git a/source/MaterialXRenderMsl/MslMaterial.mm b/source/MaterialXRenderMsl/MslMaterial.mm index eb13ea7900..311d84acee 100644 --- a/source/MaterialXRenderMsl/MslMaterial.mm +++ b/source/MaterialXRenderMsl/MslMaterial.mm @@ -318,7 +318,7 @@ { valueString = value->getValueString(); } - uniform->setValue(uniform->getType().createValueFromStrings(valueString)); + uniform->setValue(Value::createValueFromStrings(valueString, uniform->getType().getName())); if (_doc) { ElementPtr element = _doc->getDescendant(uniform->getPath()); diff --git a/source/MaterialXRenderMsl/MslPipelineStateObject.mm b/source/MaterialXRenderMsl/MslPipelineStateObject.mm index 470fa549b2..943c7987b7 100644 --- a/source/MaterialXRenderMsl/MslPipelineStateObject.mm +++ b/source/MaterialXRenderMsl/MslPipelineStateObject.mm @@ -265,12 +265,12 @@ int GetStrideOfMetalType(MTLDataType type) if (string::npos != sattributeName.find(colorSet)) { string setNumber = sattributeName.substr(colorSet.size(), sattributeName.size()); - inputPtr->value = Type::INTEGER.createValueFromStrings(setNumber); + inputPtr->value = Value::createValueFromStrings(setNumber, getTypeString()); } else if (string::npos != sattributeName.find(uvSet)) { string setNumber = sattributeName.substr(uvSet.size(), sattributeName.size()); - inputPtr->value = Type::INTEGER.createValueFromStrings(setNumber); + inputPtr->value = Value::createValueFromStrings(setNumber, getTypeString()); } _attributeList[sattributeName] = inputPtr; @@ -1035,11 +1035,11 @@ int GetStrideOfMetalType(MTLDataType type) const auto populateUniformInput = [this, uniforms, variablePath, variableSemantic, &errors, &uniformTypeMismatchFound] - (TypeDesc variableTypeDesc, const string& variableName, ConstValuePtr variableValue) -> void + (TypeDesc variableTypeDesc, const string& variableTypeName, const string& variableName, ConstValuePtr variableValue) -> void { auto populateUniformInput_impl = [this, uniforms, variablePath, variableSemantic, &errors, &uniformTypeMismatchFound] - (TypeDesc variableTypeDesc, const string& variableName, ConstValuePtr variableValue, auto& populateUniformInput_ref) -> void + (TypeDesc variableTypeDesc, const string& variableTypeName, const string& variableName, ConstValuePtr variableValue, auto& populateUniformInput_ref) -> void { // There is no way to match with an unnamed variable if (variableName.empty()) @@ -1054,7 +1054,8 @@ int GetStrideOfMetalType(MTLDataType type) return; } - if (!variableTypeDesc.isStruct()) + auto variableStructMembers = variableTypeDesc.getStructMembers(); + if (!variableTypeDesc.isStruct() || !variableStructMembers) { auto inputIt = _uniformList.find(variableName); @@ -1076,14 +1077,14 @@ int GetStrideOfMetalType(MTLDataType type) input->value = variableValue; if (input->resourceType == resourceType) { - input->typeString = variableTypeDesc.getName(); + input->typeString = variableTypeName; } else { errors.push_back( "Pixel shader uniform block type mismatch [" + uniforms.getName() + "]. " + "Name: \"" + variableName - + "\". Type: \"" + variableTypeDesc.getName() + + "\". Type: \"" + variableTypeName + "\". Semantic: \"" + variableSemantic + "\". Value: \"" + (variableValue ? variableValue->getValueString() : "") + "\". resourceType: " + std::to_string(mapTypeToMetalType(variableTypeDesc)) @@ -1094,25 +1095,22 @@ int GetStrideOfMetalType(MTLDataType type) } else { - auto structTypeDesc = StructTypeDesc::get(variableTypeDesc.getStructIndex()); auto aggregateValue = std::static_pointer_cast(variableValue); - - const auto& members = structTypeDesc.getMembers(); - for (size_t i = 0, n = members.size(); i < n; ++i) + for (size_t i = 0, n = variableStructMembers->size(); i < n; ++i) { - const auto& structMember = members[i]; - auto memberVariableName = variableName+"."+structMember._name; + const auto& structMember = variableStructMembers->at(i); + auto memberVariableName = variableName+"."+structMember.getName(); auto memberVariableValue = aggregateValue->getMemberValue(i); - populateUniformInput_ref(structMember._typeDesc, memberVariableName, memberVariableValue, populateUniformInput_ref); + populateUniformInput_ref(structMember.getTypeDesc(), structMember.getTypeName(), memberVariableName, memberVariableValue, populateUniformInput_ref); } } }; - return populateUniformInput_impl(variableTypeDesc, variableName, variableValue, populateUniformInput_impl); + return populateUniformInput_impl(variableTypeDesc, variableTypeName, variableName, variableValue, populateUniformInput_impl); }; - populateUniformInput(v->getType(), v->getVariable(), v->getValue()); + populateUniformInput(v->getType(), v->getType().getName(), v->getVariable(), v->getValue()); } } diff --git a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp index 979320bd91..eeb197cc4d 100644 --- a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp +++ b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp @@ -18,6 +18,12 @@ namespace mx = MaterialX; TEST_CASE("GenShader: GLSL Syntax Check", "[genglsl]") { + mx::GenContext context(mx::GlslShaderGenerator::create()); + mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); + mx::DocumentPtr libraries = mx::createDocument(); + mx::loadLibraries({ "libraries" }, searchPath, libraries); + context.registerTypeDefs(libraries); + mx::SyntaxPtr syntax = mx::GlslSyntax::create(); REQUIRE(syntax->getTypeName(mx::Type::FLOAT) == "float"); @@ -47,31 +53,31 @@ TEST_CASE("GenShader: GLSL Syntax Check", "[genglsl]") REQUIRE(value.empty()); mx::ValuePtr floatValue = mx::Value::createValue(42.0f); - value = syntax->getValue(mx::Type::FLOAT, *floatValue); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context); REQUIRE(value == "42.0"); - value = syntax->getValue(mx::Type::FLOAT, *floatValue, true); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context, true); REQUIRE(value == "42.0"); mx::ValuePtr color3Value = mx::Value::createValue(mx::Color3(1.0f, 2.0f, 3.0f)); - value = syntax->getValue(mx::Type::COLOR3, *color3Value); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context); REQUIRE(value == "vec3(1.0, 2.0, 3.0)"); - value = syntax->getValue(mx::Type::COLOR3, *color3Value, true); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context, true); REQUIRE(value == "vec3(1.0, 2.0, 3.0)"); mx::ValuePtr color4Value = mx::Value::createValue(mx::Color4(1.0f, 2.0f, 3.0f, 4.0f)); - value = syntax->getValue(mx::Type::COLOR4, *color4Value); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context); REQUIRE(value == "vec4(1.0, 2.0, 3.0, 4.0)"); - value = syntax->getValue(mx::Type::COLOR4, *color4Value, true); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context, true); REQUIRE(value == "vec4(1.0, 2.0, 3.0, 4.0)"); std::vector floatArray = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f }; mx::ValuePtr floatArrayValue = mx::Value::createValue>(floatArray); - value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue); + value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue, context); REQUIRE(value == "float[7](0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7)"); std::vector intArray = { 1, 2, 3, 4, 5, 6, 7 }; mx::ValuePtr intArrayValue = mx::Value::createValue>(intArray); - value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue); + value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue, context); REQUIRE(value == "int[7](1, 2, 3, 4, 5, 6, 7)"); } @@ -105,6 +111,7 @@ TEST_CASE("GenShader: GLSL Light Shaders", "[genglsl]") mx::GenContext context(mx::GlslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(doc); mx::HwShaderGenerator::bindLightShader(*pointLightShader, 42, context); REQUIRE_THROWS(mx::HwShaderGenerator::bindLightShader(*spotLightShader, 42, context)); diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index 4bec0016de..fd55932c12 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -23,6 +23,12 @@ namespace mx = MaterialX; TEST_CASE("GenShader: MDL Syntax", "[genmdl]") { + mx::GenContext context(mx::MdlShaderGenerator::create()); + mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); + mx::DocumentPtr libraries = mx::createDocument(); + mx::loadLibraries({ "libraries" }, searchPath, libraries); + context.registerTypeDefs(libraries); + mx::SyntaxPtr syntax = mx::MdlSyntax::create(); REQUIRE(syntax->getTypeName(mx::Type::FLOAT) == "float"); @@ -56,31 +62,31 @@ TEST_CASE("GenShader: MDL Syntax", "[genmdl]") REQUIRE(value.empty()); mx::ValuePtr floatValue = mx::Value::createValue(42.0f); - value = syntax->getValue(mx::Type::FLOAT, *floatValue); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context); REQUIRE(value == "42.0"); - value = syntax->getValue(mx::Type::FLOAT, *floatValue, true); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context, true); REQUIRE(value == "42.0"); mx::ValuePtr color3Value = mx::Value::createValue(mx::Color3(1.0f, 2.0f, 3.0f)); - value = syntax->getValue(mx::Type::COLOR3, *color3Value); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context); REQUIRE(value == "color(1.0, 2.0, 3.0)"); - value = syntax->getValue(mx::Type::COLOR3, *color3Value, true); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context, true); REQUIRE(value == "color(1.0, 2.0, 3.0)"); mx::ValuePtr color4Value = mx::Value::createValue(mx::Color4(1.0f, 2.0f, 3.0f, 4.0f)); - value = syntax->getValue(mx::Type::COLOR4, *color4Value); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context); REQUIRE(value == "mk_color4(1.0, 2.0, 3.0, 4.0)"); - value = syntax->getValue(mx::Type::COLOR4, *color4Value, true); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context, true); REQUIRE(value == "mk_color4(1.0, 2.0, 3.0, 4.0)"); std::vector floatArray = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f }; mx::ValuePtr floatArrayValue = mx::Value::createValue>(floatArray); - value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue); + value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue, context); REQUIRE(value == "float[](0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7)"); std::vector intArray = { 1, 2, 3, 4, 5, 6, 7 }; mx::ValuePtr intArrayValue = mx::Value::createValue>(intArray); - value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue); + value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue, context); REQUIRE(value == "int[](1, 2, 3, 4, 5, 6, 7)"); } diff --git a/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp b/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp index 32baaec5f0..3be738bb4f 100644 --- a/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp +++ b/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp @@ -21,6 +21,12 @@ namespace mx = MaterialX; TEST_CASE("GenShader: MSL Syntax Check", "[genmsl]") { + mx::GenContext context(mx::MslShaderGenerator::create()); + mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); + mx::DocumentPtr libraries = mx::createDocument(); + mx::loadLibraries({ "libraries" }, searchPath, libraries); + context.registerTypeDefs(libraries); + mx::SyntaxPtr syntax = mx::MslSyntax::create(); REQUIRE(syntax->getTypeName(mx::Type::FLOAT) == "float"); @@ -50,31 +56,31 @@ TEST_CASE("GenShader: MSL Syntax Check", "[genmsl]") REQUIRE(value.empty()); mx::ValuePtr floatValue = mx::Value::createValue(42.0f); - value = syntax->getValue(mx::Type::FLOAT, *floatValue); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context); REQUIRE(value == "42.0"); - value = syntax->getValue(mx::Type::FLOAT, *floatValue, true); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context, true); REQUIRE(value == "42.0"); mx::ValuePtr color3Value = mx::Value::createValue(mx::Color3(1.0f, 2.0f, 3.0f)); - value = syntax->getValue(mx::Type::COLOR3, *color3Value); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context); REQUIRE(value == "vec3(1.0, 2.0, 3.0)"); - value = syntax->getValue(mx::Type::COLOR3, *color3Value, true); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context, true); REQUIRE(value == "vec3(1.0, 2.0, 3.0)"); mx::ValuePtr color4Value = mx::Value::createValue(mx::Color4(1.0f, 2.0f, 3.0f, 4.0f)); - value = syntax->getValue(mx::Type::COLOR4, *color4Value); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context); REQUIRE(value == "vec4(1.0, 2.0, 3.0, 4.0)"); - value = syntax->getValue(mx::Type::COLOR4, *color4Value, true); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context, true); REQUIRE(value == "vec4(1.0, 2.0, 3.0, 4.0)"); std::vector floatArray = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f }; mx::ValuePtr floatArrayValue = mx::Value::createValue>(floatArray); - value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue); + value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue, context); REQUIRE(value == "{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7}"); std::vector intArray = { 1, 2, 3, 4, 5, 6, 7 }; mx::ValuePtr intArrayValue = mx::Value::createValue>(intArray); - value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue); + value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue, context); REQUIRE(value == "{1, 2, 3, 4, 5, 6, 7}"); } @@ -107,6 +113,7 @@ TEST_CASE("GenShader: MSL Bind Light Shaders", "[genmsl]") mx::GenContext context(mx::MslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(doc); mx::HwShaderGenerator::bindLightShader(*pointLightShader, 42, context); REQUIRE_THROWS(mx::HwShaderGenerator::bindLightShader(*spotLightShader, 42, context)); diff --git a/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp b/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp index 6e613c85b8..37189a74b6 100644 --- a/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp +++ b/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp @@ -20,6 +20,12 @@ namespace mx = MaterialX; TEST_CASE("GenShader: OSL Syntax", "[genosl]") { + mx::GenContext context(mx::OslShaderGenerator::create()); + mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); + mx::DocumentPtr libraries = mx::createDocument(); + mx::loadLibraries({ "libraries" }, searchPath, libraries); + context.registerTypeDefs(libraries); + mx::SyntaxPtr syntax = mx::OslSyntax::create(); REQUIRE(syntax->getTypeName(mx::Type::FLOAT) == "float"); @@ -53,31 +59,31 @@ TEST_CASE("GenShader: OSL Syntax", "[genosl]") REQUIRE(value.empty()); mx::ValuePtr floatValue = mx::Value::createValue(42.0f); - value = syntax->getValue(mx::Type::FLOAT, *floatValue); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context); REQUIRE(value == "42.0"); - value = syntax->getValue(mx::Type::FLOAT, *floatValue, true); + value = syntax->getValue(mx::Type::FLOAT, *floatValue, context, true); REQUIRE(value == "42.0"); mx::ValuePtr color3Value = mx::Value::createValue(mx::Color3(1.0f, 2.0f, 3.0f)); - value = syntax->getValue(mx::Type::COLOR3, *color3Value); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context); REQUIRE(value == "color(1.0, 2.0, 3.0)"); - value = syntax->getValue(mx::Type::COLOR3, *color3Value, true); + value = syntax->getValue(mx::Type::COLOR3, *color3Value, context, true); REQUIRE(value == "color(1.0, 2.0, 3.0)"); mx::ValuePtr color4Value = mx::Value::createValue(mx::Color4(1.0f, 2.0f, 3.0f, 4.0f)); - value = syntax->getValue(mx::Type::COLOR4, *color4Value); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context); REQUIRE(value == "color4(color(1.0, 2.0, 3.0), 4.0)"); - value = syntax->getValue(mx::Type::COLOR4, *color4Value, true); + value = syntax->getValue(mx::Type::COLOR4, *color4Value, context, true); REQUIRE(value == "{color(1.0, 2.0, 3.0), 4.0}"); std::vector floatArray = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f }; mx::ValuePtr floatArrayValue = mx::Value::createValue>(floatArray); - value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue); + value = syntax->getValue(mx::Type::FLOATARRAY, *floatArrayValue, context); REQUIRE(value == "{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7}"); std::vector intArray = { 1, 2, 3, 4, 5, 6, 7 }; mx::ValuePtr intArrayValue = mx::Value::createValue>(intArray); - value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue); + value = syntax->getValue(mx::Type::INTEGERARRAY, *intArrayValue, context); REQUIRE(value == "{1, 2, 3, 4, 5, 6, 7}"); } @@ -167,6 +173,7 @@ TEST_CASE("GenShader: OSL Metadata", "[genosl]") mx::ShaderGeneratorPtr generator = mx::OslShaderGenerator::create(); mx::GenContext context(mx::OslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(doc); // Metadata to export must be registered in the context before shader generation starts. // Custom generators can override this method to customize which metadata gets registered. diff --git a/source/MaterialXTest/MaterialXGenShader/GenShader.cpp b/source/MaterialXTest/MaterialXGenShader/GenShader.cpp index a959283aad..a0c154a84e 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShader.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShader.cpp @@ -73,35 +73,77 @@ TEST_CASE("GenShader: Valid Libraries", "[genshader]") TEST_CASE("GenShader: TypeDesc Check", "[genshader]") { - // Make sure the standard types are registered - const mx::TypeDesc floatType = mx::TypeDesc::get("float"); - REQUIRE(floatType != mx::Type::NONE); - REQUIRE(floatType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT); - const mx::TypeDesc integerType = mx::TypeDesc::get("integer"); - REQUIRE(integerType != mx::Type::NONE); - REQUIRE(integerType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER); - const mx::TypeDesc booleanType = mx::TypeDesc::get("boolean"); - REQUIRE(booleanType != mx::Type::NONE); - REQUIRE(booleanType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN); - const mx::TypeDesc color3Type = mx::TypeDesc::get("color3"); - REQUIRE(color3Type != mx::Type::NONE); - REQUIRE(color3Type.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT); - REQUIRE(color3Type.getSemantic() == mx::TypeDesc::SEMANTIC_COLOR); - REQUIRE(color3Type.isFloat3()); - const mx::TypeDesc color4Type = mx::TypeDesc::get("color4"); - REQUIRE(color4Type != mx::Type::NONE); - REQUIRE(color4Type.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT); - REQUIRE(color4Type.getSemantic() == mx::TypeDesc::SEMANTIC_COLOR); - REQUIRE(color4Type.isFloat4()); - - // Make sure we can register a new custom type - const std::string fooTypeName = "foo"; - mx::TypeDescRegistry reg(mx::TypeDesc(fooTypeName, mx::TypeDesc::BASETYPE_FLOAT, mx::TypeDesc::SEMANTIC_COLOR, 5), fooTypeName); - const mx::TypeDesc fooType = mx::TypeDesc::get(fooTypeName); - REQUIRE(fooType != mx::Type::NONE); - - // Make sure we can't request an unknown type - REQUIRE(mx::TypeDesc::get("bar") == mx::Type::NONE); + + auto testTypeDescTypes = [](mx::GenContext& context) -> void + { + // Make sure the standard types are registered + const mx::TypeDesc floatType = context.getTypeDesc("float"); + REQUIRE(floatType != mx::Type::NONE); + REQUIRE(floatType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT); + const mx::TypeDesc integerType = context.getTypeDesc("integer"); + REQUIRE(integerType != mx::Type::NONE); + REQUIRE(integerType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER); + const mx::TypeDesc booleanType = context.getTypeDesc("boolean"); + REQUIRE(booleanType != mx::Type::NONE); + REQUIRE(booleanType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN); + const mx::TypeDesc color3Type = context.getTypeDesc("color3"); + REQUIRE(color3Type != mx::Type::NONE); + REQUIRE(color3Type.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT); + REQUIRE(color3Type.getSemantic() == mx::TypeDesc::SEMANTIC_COLOR); + REQUIRE(color3Type.isFloat3()); + const mx::TypeDesc color4Type = context.getTypeDesc("color4"); + REQUIRE(color4Type != mx::Type::NONE); + REQUIRE(color4Type.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT); + REQUIRE(color4Type.getSemantic() == mx::TypeDesc::SEMANTIC_COLOR); + REQUIRE(color4Type.isFloat4()); + + // Make sure we can register a new custom type + const std::string fooTypeName = "foo"; + context.registerTypeDesc(fooTypeName, mx::TypeDesc::BASETYPE_FLOAT, mx::TypeDesc::SEMANTIC_COLOR, 5); + const mx::TypeDesc fooType = context.getTypeDesc(fooTypeName); + REQUIRE(fooType != mx::Type::NONE); + + // Make sure we can't request an unknown type + REQUIRE(context.getTypeDesc("bar") == mx::Type::NONE); + }; + + mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); + mx::DocumentPtr libraries = mx::createDocument(); + mx::loadLibraries({ "libraries" }, searchPath, libraries); + +#ifdef MATERIALX_BUILD_GEN_GLSL + { + mx::GenContext context(mx::GlslShaderGenerator::create()); + context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); + testTypeDescTypes(context); + } +#endif +#ifdef MATERIALX_BUILD_GEN_OSL + { + mx::GenContext context(mx::OslShaderGenerator::create()); + context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); + testTypeDescTypes(context); + } +#endif +#ifdef MATERIALX_BUILD_GEN_MDL + { + mx::GenContext context(mx::MdlShaderGenerator::create()); + context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); + testTypeDescTypes(context); + } +#endif +#ifdef MATERIALX_BUILD_GEN_MSL + { + mx::GenContext context(mx::MslShaderGenerator::create()); + context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); + testTypeDescTypes(context); + } +#endif + } TEST_CASE("GenShader: Shader Translation", "[translate]") @@ -209,6 +251,14 @@ void testDeterministicGeneration(mx::DocumentPtr libraries, mx::GenContext& cont mx::readFromXmlFile(testDoc, testFile); testDoc->setDataLibrary(libraries); + // TODO - decide what it means to re-register the same type over again. + // We could... + // 1) Just blindly register this type on top of the existing type name. + // 2) Ignore any types where the names are already registered + // 3) When a type is re-registered we could go compare the existing registered type against the + // new candidate type, and raise an error if they differ. + context.registerTypeDefs(testDoc); + // Keep the document alive to make sure // new memory is allocated for each run testDocs[i] = testDoc; @@ -238,6 +288,7 @@ TEST_CASE("GenShader: Deterministic Generation", "[genshader]") { mx::GenContext context(mx::GlslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); testDeterministicGeneration(libraries, context); } #endif @@ -245,6 +296,7 @@ TEST_CASE("GenShader: Deterministic Generation", "[genshader]") { mx::GenContext context(mx::OslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); testDeterministicGeneration(libraries, context); } #endif @@ -252,6 +304,7 @@ TEST_CASE("GenShader: Deterministic Generation", "[genshader]") { mx::GenContext context(mx::MdlShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); testDeterministicGeneration(libraries, context); } #endif @@ -259,6 +312,7 @@ TEST_CASE("GenShader: Deterministic Generation", "[genshader]") { mx::GenContext context(mx::MslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); testDeterministicGeneration(libraries, context); } #endif @@ -295,6 +349,7 @@ TEST_CASE("GenShader: Track Dependencies", "[genshader]") { mx::GenContext context(mx::GlslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); checkPixelDependencies(libraries, context); } #endif @@ -302,6 +357,7 @@ TEST_CASE("GenShader: Track Dependencies", "[genshader]") { mx::GenContext context(mx::OslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); checkPixelDependencies(libraries, context); } #endif @@ -309,6 +365,7 @@ TEST_CASE("GenShader: Track Dependencies", "[genshader]") { mx::GenContext context(mx::MdlShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); checkPixelDependencies(libraries, context); } #endif @@ -394,6 +451,7 @@ TEST_CASE("GenShader: Track Application Variables", "[genshader]") { mx::GenContext context(mx::GlslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); context.setApplicationVariableHandler(variableTracker); mx::ShaderPtr shader = context.getShaderGenerator().generate(testElement, element, context); } @@ -402,6 +460,7 @@ TEST_CASE("GenShader: Track Application Variables", "[genshader]") { mx::GenContext context(mx::OslShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); context.setApplicationVariableHandler(variableTracker); mx::ShaderPtr shader = context.getShaderGenerator().generate(testElement, element, context); } @@ -410,6 +469,7 @@ TEST_CASE("GenShader: Track Application Variables", "[genshader]") { mx::GenContext context(mx::MdlShaderGenerator::create()); context.registerSourceCodeSearchPath(searchPath); + context.registerTypeDefs(libraries); context.setApplicationVariableHandler(variableTracker); mx::ShaderPtr shader = context.getShaderGenerator().generate(testElement, element, context); } diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 40f89c001f..f2134e4713 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -276,6 +276,8 @@ void testUniqueNames(mx::GenContext& context, const std::string& stage) mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); loadLibraries({ "libraries/targets", "libraries/stdlib" }, searchPath, doc); + context.registerTypeDefs(doc); + const std::string exampleName = "unique_names"; // Generate a shader with an internal node having the same name as the shader, @@ -576,8 +578,7 @@ void ShaderGeneratorTester::findLights(mx::DocumentPtr doc, std::vectorgetNodes()) { - const mx::TypeDesc type = mx::TypeDesc::get(node->getType()); - if (type == mx::Type::LIGHTSHADER) + if (node->getType() == mx::Type::LIGHTSHADER.getName()) { lights.push_back(node); } @@ -645,9 +646,6 @@ void ShaderGeneratorTester::validate(const mx::GenOptions& generateOptions, cons addColorManagement(); addUnitSystem(); - // Register struct typedefs from the library files. - _shaderGenerator->loadStructTypeDefs(_dependLib); - // Test suite setup addSkipFiles(); @@ -681,8 +679,9 @@ void ShaderGeneratorTester::validate(const mx::GenOptions& generateOptions, cons context.getOptions() = generateOptions; context.registerSourceCodeSearchPath(_searchPath); - // Register shader metadata defined in the libraries. + // Register shader metadata and types defined in the libraries. _shaderGenerator->registerShaderMetadata(_dependLib, context); + _shaderGenerator->registerTypeDefs(_dependLib, context); // Define working unit if required if (context.getOptions().targetDistanceUnit.empty()) @@ -703,8 +702,7 @@ void ShaderGeneratorTester::validate(const mx::GenOptions& generateOptions, cons // Apply optional preprocessing. preprocessDocument(doc); _shaderGenerator->registerShaderMetadata(doc, context); - - _shaderGenerator->loadStructTypeDefs(doc); + _shaderGenerator->registerTypeDefs(doc, context); // For each new file clear the implementation cache. // Since the new file might contain implementations with names diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp index e3e5e8033e..4c982b4c31 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp @@ -164,8 +164,9 @@ bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) // Set target unit space context.getOptions().targetDistanceUnit = "meter"; - // Register shader metadata defined in the libraries. + // Register shader metadata and types defined in the libraries. _shaderGenerator->registerShaderMetadata(dependLib, context); + _shaderGenerator->registerTypeDefs(dependLib, context); setupTime.endTimer(); diff --git a/source/MaterialXTest/MaterialXRenderOsl/GenReference.cpp b/source/MaterialXTest/MaterialXRenderOsl/GenReference.cpp index 05c83ae82e..b911a85f8a 100644 --- a/source/MaterialXTest/MaterialXRenderOsl/GenReference.cpp +++ b/source/MaterialXTest/MaterialXRenderOsl/GenReference.cpp @@ -50,6 +50,7 @@ TEST_CASE("GenReference: OSL Reference", "[genreference]") mx::GenContext context(generator); context.getOptions().addUpstreamDependencies = false; context.registerSourceCodeSearchPath(searchPath); + generator->registerTypeDefs(stdlib, context); context.getOptions().fileTextureVerticalFlip = true; // Create output directory. diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index aefdf2d401..2cc79647ae 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -1309,6 +1309,9 @@ void Viewer::loadDocument(const mx::FilePath& filename, mx::DocumentPtr librarie // Store data library reference. doc->setDataLibrary(libraries); + // Load any additional type defs in the document + _genContext.registerTypeDefs(doc); + // Apply direct lights. applyDirectLights(doc); @@ -1761,7 +1764,7 @@ void Viewer::initContext(mx::GenContext& context) context.getOptions().targetDistanceUnit = "meter"; // Initialize the struct typedefs from the stdlib - context.getShaderGenerator().loadStructTypeDefs(_stdLib); + context.registerTypeDefs(_stdLib); } void Viewer::loadStandardLibraries() diff --git a/source/PyMaterialX/PyMaterialXGenShader/PyGenContext.cpp b/source/PyMaterialX/PyMaterialXGenShader/PyGenContext.cpp index 11792f317c..4c3cbb40ab 100644 --- a/source/PyMaterialX/PyMaterialXGenShader/PyGenContext.cpp +++ b/source/PyMaterialX/PyMaterialXGenShader/PyGenContext.cpp @@ -24,7 +24,9 @@ void bindPyGenContext(py::module& mod) .def("resolveSourceFile", &mx::GenContext::resolveSourceFile) .def("pushUserData", &mx::GenContext::pushUserData) .def("setApplicationVariableHandler", &mx::GenContext::setApplicationVariableHandler) - .def("getApplicationVariableHandler", &mx::GenContext::getApplicationVariableHandler); + .def("getApplicationVariableHandler", &mx::GenContext::getApplicationVariableHandler) + .def("getTypeDesc", &mx::GenContext::getTypeDesc); + } void bindPyGenUserData(py::module& mod) diff --git a/source/PyMaterialX/PyMaterialXGenShader/PyShaderGenerator.cpp b/source/PyMaterialX/PyMaterialXGenShader/PyShaderGenerator.cpp index 0c8a086e58..fdf4b94aac 100644 --- a/source/PyMaterialX/PyMaterialXGenShader/PyShaderGenerator.cpp +++ b/source/PyMaterialX/PyMaterialXGenShader/PyShaderGenerator.cpp @@ -22,7 +22,6 @@ void bindPyShaderGenerator(py::module& mod) .def("setUnitSystem", &mx::ShaderGenerator::setUnitSystem) .def("getUnitSystem", &mx::ShaderGenerator::getUnitSystem) .def("getTokenSubstitutions", &mx::ShaderGenerator::getTokenSubstitutions) - .def("loadStructTypeDefs", &mx::ShaderGenerator::loadStructTypeDefs) - .def("clearStructTypeDefs", &mx::ShaderGenerator::clearStructTypeDefs) + .def("registerTypeDefs", &mx::ShaderGenerator::registerTypeDefs) .def("registerShaderMetadata", &mx::ShaderGenerator::registerShaderMetadata); } diff --git a/source/PyMaterialX/PyMaterialXGenShader/PyTypeDesc.cpp b/source/PyMaterialX/PyMaterialXGenShader/PyTypeDesc.cpp index dc0a6c9fe8..32d92c2823 100644 --- a/source/PyMaterialX/PyMaterialXGenShader/PyTypeDesc.cpp +++ b/source/PyMaterialX/PyMaterialXGenShader/PyTypeDesc.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace py = pybind11; namespace mx = MaterialX; @@ -16,7 +17,6 @@ void bindPyTypeDesc(py::module& mod) // by the container they are stored in and should not be destroyed when // garbage collected by the python interpreter py::class_>(mod, "TypeDesc") - .def_static("get", &mx::TypeDesc::get) .def("getName", &mx::TypeDesc::getName) .def("getBaseType", &mx::TypeDesc::getBaseType) .def("getSemantic", &mx::TypeDesc::getSemantic)