예제 #1
0
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;
}
예제 #2
0
 /** Bind a program
     Program have bindings globalVar->parameter
 */
 void GLEngine::setProgram(ProgramPtr program)
 {
     if(mCurrentProgram.get() == program.get())
         return;
     mCurrentProgram = program;
 }