bool Compiler::CompileShaderPrimary( const ShaderInput& inputDesc, const ShaderOutput& outputDesc, Reflection::ReflectionData* reflectionData) { /* Validate arguments */ ValidateArguments(inputDesc, outputDesc); /* ----- Pre-processing ----- */ timePoints_.preprocessor = Time::now(); std::unique_ptr<IncludeHandler> stdIncludeHandler; if (!inputDesc.includeHandler) stdIncludeHandler = std::unique_ptr<IncludeHandler>(new IncludeHandler()); auto includeHandler = (inputDesc.includeHandler != nullptr ? inputDesc.includeHandler : stdIncludeHandler.get()); std::unique_ptr<PreProcessor> preProcessor; if (IsLanguageHLSL(inputDesc.shaderVersion)) preProcessor = MakeUnique<PreProcessor>(*includeHandler, log_); else if (IsLanguageGLSL(inputDesc.shaderVersion)) preProcessor = MakeUnique<GLSLPreProcessor>(*includeHandler, log_); const bool writeLineMarksInPP = (!outputDesc.options.preprocessOnly || outputDesc.formatting.lineMarks); const bool writeLineMarkFilenamesInPP = (!outputDesc.options.preprocessOnly || IsLanguageHLSL(inputDesc.shaderVersion)); auto processedInput = preProcessor->Process( std::make_shared<SourceCode>(inputDesc.sourceCode), inputDesc.filename, writeLineMarksInPP, writeLineMarkFilenamesInPP, ((inputDesc.warnings & Warnings::PreProcessor) != 0) ); if (reflectionData) reflectionData->macros = preProcessor->ListDefinedMacroIdents(); if (!processedInput) return ReturnWithError(R_PreProcessingSourceFailed); if (outputDesc.options.preprocessOnly) { (*outputDesc.sourceCode) << processedInput->rdbuf(); return true; } /* ----- Parsing ----- */ timePoints_.parser = Time::now(); std::unique_ptr<IntrinsicAdept> intrinsicAdpet; ProgramPtr program; if (IsLanguageHLSL(inputDesc.shaderVersion)) { /* Establish intrinsic adept */ intrinsicAdpet = MakeUnique<HLSLIntrinsicAdept>(); /* Parse HLSL input code */ HLSLParser parser(log_); program = parser.ParseSource( std::make_shared<SourceCode>(std::move(processedInput)), outputDesc.nameMangling, inputDesc.shaderVersion, outputDesc.options.rowMajorAlignment, ((inputDesc.warnings & Warnings::Syntax) != 0) ); } else if (IsLanguageGLSL(inputDesc.shaderVersion)) { /* Establish intrinsic adept */ #if 0 intrinsicAdpet = MakeUnique<GLSLIntrinsicAdept>(); #else //!!! intrinsicAdpet = MakeUnique<HLSLIntrinsicAdept>(); #endif /* Parse GLSL input code */ GLSLParser parser(log_); program = parser.ParseSource( std::make_shared<SourceCode>(std::move(processedInput)), outputDesc.nameMangling, inputDesc.shaderVersion, ((inputDesc.warnings & Warnings::Syntax) != 0) ); } if (!program) return ReturnWithError(R_ParsingSourceFailed); /* ----- Context analysis ----- */ timePoints_.analyzer = Time::now(); bool analyzerResult = false; if (IsLanguageHLSL(inputDesc.shaderVersion)) { /* Analyse HLSL program */ HLSLAnalyzer analyzer(log_); analyzerResult = analyzer.DecorateAST(*program, inputDesc, outputDesc); } /* Print AST */ if (outputDesc.options.showAST) { ASTPrinter printer; printer.PrintAST(program.get()); } if (!analyzerResult) return ReturnWithError(R_AnalyzingSourceFailed); /* Optimize AST */ timePoints_.optimizer = Time::now(); if (outputDesc.options.optimize) { Optimizer optimizer; optimizer.Optimize(*program); } /* ----- Code generation ----- */ timePoints_.generation = Time::now(); bool generatorResult = false; if (IsLanguageGLSL(outputDesc.shaderVersion) || IsLanguageESSL(outputDesc.shaderVersion) || IsLanguageVKSL(outputDesc.shaderVersion)) { /* Generate GLSL output code */ GLSLGenerator generator(log_); generatorResult = generator.GenerateCode(*program, inputDesc, outputDesc, log_); } if (!generatorResult) return ReturnWithError(R_GeneratingOutputCodeFailed); /* ----- Code reflection ----- */ timePoints_.reflection = Time::now(); if (reflectionData) { ReflectionAnalyzer reflectAnalyzer(log_); reflectAnalyzer.Reflect( *program, inputDesc.shaderTarget, *reflectionData, ((inputDesc.warnings & Warnings::CodeReflection) != 0) ); } return true; }
/** Bind a program Program have bindings globalVar->parameter */ void GLEngine::setProgram(ProgramPtr program) { if(mCurrentProgram.get() == program.get()) return; mCurrentProgram = program; }