// // Copyright Contributors to the MaterialX Project // SPDX-License-Identifier: Apache-2.0 // #ifndef GENSHADER_UTIL_H #define GENSHADER_UTIL_H #include #include #include #include #include #include #include #include #include #include #include namespace mx = MaterialX; namespace GenShaderUtil { /// An unordered map from light names to light indices. using LightIdMap = std::unordered_map; // // Get source content, source path and resolved paths for // an implementation // bool getShaderSource(mx::GenContext& context, const mx::ImplementationPtr implementation, mx::FilePath& sourcePath, mx::FilePath& resolvedPath, std::string& sourceContents); // Test code generation for a given element bool generateCode(mx::GenContext& context, const std::string& shaderName, mx::TypedElementPtr element, std::ostream& log, mx::StringVec testStages, mx::StringVec& sourceCode); // Check that implementations exist for all nodedefs supported per generator void checkImplementations(mx::GenContext& context, const mx::StringSet& generatorSkipNodeTypes, const mx::StringSet& generatorSkipNodeDefs); // Utility test to check unique name generation on a shader generator void testUniqueNames(mx::GenContext& context, const std::string& stage); // Utility to perform simple performance test to load, validate and generate shaders void shaderGenPerformanceTest(mx::GenContext& context); // // Render validation options. Reflects the _options.mtlx // file in the test suite area. // class TestSuiteOptions { public: // Print out options void print(std::ostream& output) const; // Option options from an options file bool readOptions(const std::string& optionFile); // Filter list of files to only run validation on. mx::StringVec overrideFiles; // List of target identifiers mx::StringSet targets; // Comma separated list of light setup files mx::StringVec lightFiles; // Set to true to always dump generated code to disk bool dumpGeneratedCode = false; // Check the count of number of implementations used bool checkImplCount = true; // Run using a set of interfaces: // - 3 = run complete + reduced. // - 2 = run complete only (default) // - 1 = run reduced only. int shaderInterfaces = 2; // Render size mx::Vector2 renderSize = { 512, 512 }; // Set this to be true if it is desired to dump out uniform and attribute information to the logging file. bool dumpUniformsAndAttributes = true; // Geometry file to be rendered MaterialX::FilePath renderGeometry; // Enable direct lighting. Default is true. bool enableDirectLighting; // Enable indirect lighting. Default is true. bool enableIndirectLighting; // Radiance IBL file. mx::FilePath radianceIBLPath; // Irradiance IBL file. mx::FilePath irradianceIBLPath; // Extra library paths mx::FileSearchPath extraLibraryPaths; // Render test paths mx::FileSearchPath renderTestPaths; // Enable reference quality rendering. Default is false. bool enableReferenceQuality; // Bake parameters struct BakeSetting { std::string bakeFile; bool hdr = false; unsigned int resolution = 512; mx::Vector2 uvmin = mx::Vector2(0.0f); mx::Vector2 uvmax = mx::Vector2(1.0f); }; std::vector bakeSettings; }; // Utility class to handle testing of shader generators. // Currently only tests source code generation. class ShaderGeneratorTester { public: ShaderGeneratorTester(mx::ShaderGeneratorPtr shaderGenerator, const mx::FilePathVec& testRootPaths, const mx::FileSearchPath& searchPath, const mx::FilePath& logFilePath, bool writeShadersToDisk) : _shaderGenerator(shaderGenerator), _targetString(shaderGenerator ? shaderGenerator->getTarget() : "NULL"), _testRootPaths(testRootPaths), _searchPath(searchPath), _logFilePath(logFilePath), _writeShadersToDisk(writeShadersToDisk) { } ~ShaderGeneratorTester() { } // Check if testing should be performed based in input options virtual bool runTest(const TestSuiteOptions& testOptions) { return (testOptions.targets.count(_targetString) > 0); } // Stages to test is required from derived class virtual void setTestStages() = 0; // Add files in to not examine virtual void addSkipFiles() { }; // Add nodedefs to not examine virtual void addSkipNodeDefs() { }; // Add files to be skipped while loading libraries virtual void addSkipLibraryFiles() { }; // Add color management virtual void addColorManagement(); // Add unit system virtual void addUnitSystem(); // Add user data void addUserData(const std::string& name, mx::GenUserDataPtr data) { _userData[name] = data; } // Load in dependent libraries virtual void setupDependentLibraries(); // TODO: Merge the methods below with equivalent methods in LightHandler. // From a set of nodes, create a mapping of nodedef identifiers to numbers virtual LightIdMap computeLightIdMap(const std::vector& nodes); // Find lights to use based on an input document virtual void findLights(mx::DocumentPtr doc, std::vector& lights); // Register light node definitions and light count with a given generation context virtual void registerLights(mx::DocumentPtr doc, const std::vector& lights, mx::GenContext& context); // Generate source code for a given element and check that code was produced. virtual bool generateCode(mx::GenContext& context, const std::string& shaderName, mx::TypedElementPtr element, std::ostream& log, mx::StringVec testStages, mx::StringVec& sourceCode); // Run test for source code generation void validate(const mx::GenOptions& generateOptions, const std::string& optionsFilePath); // Allow the tester to alter the document, e.g., by flattening file names. virtual void preprocessDocument(mx::DocumentPtr doc) {}; // Compile generated source code. Default implementation does nothing. virtual void compileSource(const std::vector& /*sourceCodePaths*/) {}; protected: // Check to see that all implementations have been tested for a given // language. void checkImplementationUsage(const mx::StringSet& usedImpls, const mx::GenContext& context, std::ostream& stream); // Get implementation "whitelist" for those implementations that have // been skipped for checking virtual void getImplementationWhiteList(mx::StringSet& /*whiteList*/) {}; mx::ShaderGeneratorPtr _shaderGenerator; const std::string _targetString; mx::DefaultColorManagementSystemPtr _colorManagementSystem; // Unit system mx::UnitSystemPtr _unitSystem; std::string _defaultDistanceUnit; mx::DocumentPtr _dependLib; const mx::FilePathVec _testRootPaths; const mx::FileSearchPath _searchPath; const mx::FilePath _logFilePath; bool _writeShadersToDisk; mx::StringSet _skipFiles; mx::StringSet _skipLibraryFiles; std::vector _documents; mx::StringVec _documentPaths; std::ofstream _logFile; mx::StringSet _skipNodeDefs; mx::StringVec _testStages; std::vector _lights; std::unordered_map _lightIdMap; std::unordered_map _userData; mx::StringSet _usedImplementations; }; } // namespace GenShaderUtil #endif