https://github.com/shader-slang/slang
Raw File
Tip revision: 21a14cb4e0d578bc4f8a460016269a1199cac0da authored by Tim Foley on 06 July 2017, 16:52:53 UTC
Merge pull request #53 from tfoleyNV/cross-compilation
Tip revision: 21a14cb
compiler.h
#ifndef RASTER_SHADER_COMPILER_H
#define RASTER_SHADER_COMPILER_H

#include "../core/basic.h"

#include "compiled-program.h"
#include "diagnostics.h"
#include "profile.h"
#include "syntax.h"
#include "type-layout.h"

#include "../../slang.h"

namespace Slang
{
    struct IncludeHandler;
    class CompileRequest;

    enum class CompilerMode
    {
        ProduceLibrary,
        ProduceShader,
        GenerateChoice
    };

    enum class StageTarget
    {
        Unknown,
        VertexShader,
        HullShader,
        DomainShader,
        GeometryShader,
        FragmentShader,
        ComputeShader,
    };

    enum class CodeGenTarget
    {
        Unknown             = SLANG_TARGET_UNKNOWN,
        GLSL                = SLANG_GLSL,
        GLSL_Vulkan         = SLANG_GLSL_VULKAN,
        GLSL_Vulkan_OneDesc = SLANG_GLSL_VULKAN_ONE_DESC,
        HLSL                = SLANG_HLSL,
        SPIRV               = SLANG_SPIRV,
        SPIRVAssembly       = SLANG_SPIRV_ASM,
        DXBytecode          = SLANG_DXBC,
        DXBytecodeAssembly  = SLANG_DXBC_ASM,
        ReflectionJSON      = SLANG_REFLECTION_JSON,
    };

    class CompileRequest;
    class TranslationUnitRequest;

    // Result of compiling an entry point
    struct EntryPointResult
    {
        String outputSource;
    };

    // Describes an entry point that we've been requested to compile
    class EntryPointRequest : public RefObject
    {
    public:
        // The parent compile request
        CompileRequest* compileRequest = nullptr;

        // The name of the entry point function (e.g., `main`)
        String name;

        // The profile that the entry point will be compiled for
        // (this is a combination of the target state, and also
        // a feature level that sets capabilities)
        Profile profile;

        // The index of the translation unit (within the parent
        // compile request) that the entry point function is
        // supposed to be defined in.
        int translationUnitIndex;

        // The resulting output for the enry point
        //
        // TODO: low-level code generation should be a distinct step
        EntryPointResult result;

        // The translation unit that this entry point came from
        TranslationUnitRequest* getTranslationUnit();
    };

    enum class PassThroughMode : SlangPassThrough
    {
        None = SLANG_PASS_THROUGH_NONE,	// don't pass through: use Slang compiler
        HLSL = SLANG_PASS_THROUGH_FXC,	// pass through HLSL to `D3DCompile` API
//			GLSL,	// pass through GLSL to `glslang` library
    };

    // Represents a single source file (either an on-disk file, or a
    // "virtual" file passed in as a string)
    class SourceFile : public RefObject
    {
    public:
        // The file path for a real file, or the nominal path for a virtual file
        String path;

        // The actual contents of the file
        String content;
    };

    // Result of compiling a translation unit
    struct TranslationUnitResult
    {
        String outputSource;
    };

    // A single translation unit requested to be compiled.
    //
    class TranslationUnitRequest : public RefObject
    {
    public:
        // The parent compile request
        CompileRequest* compileRequest = nullptr;

        // The language in which the source file(s)
        // are assumed to be written
        SourceLanguage sourceLanguage = SourceLanguage::Unknown;

        // The source file(s) that will be compiled to form this translation unit
        //
        // Usually, for HLSL or GLSL there will be only one file.
        List<RefPtr<SourceFile> > sourceFiles;

        // The entry points associated with this translation unit
        List<RefPtr<EntryPointRequest> > entryPoints;

        // Preprocessor definitions to use for this translation unit only
        // (whereas the ones on `CompileOptions` will be shared)
        Dictionary<String, String> preprocessorDefinitions;

        // Compile flags for this translation unit
        SlangCompileFlags compileFlags = 0;

        // The parsed syntax for the translation unit
        RefPtr<ProgramSyntaxNode>   SyntaxNode;

        // The resulting output for the translation unit
        //
        // TODO: low-level code generation should be a distinct step
        TranslationUnitResult result;
    };

    // A directory to be searched when looking for files (e.g., `#include`)
    struct SearchDirectory
    {
        SearchDirectory() = default;
        SearchDirectory(SearchDirectory const& other) = default;
        SearchDirectory(String const& path)
            : path(path)
        {}

        String  path;
    };

    class Session;

    class CompileRequest : public RefObject
    {
    public:
        // Pointer to parent session
        Session* mSession;

        // What target language are we compiling to?
        CodeGenTarget Target = CodeGenTarget::Unknown;

        // Directories to search for `#include` files or `import`ed modules
        List<SearchDirectory> searchDirectories;

        // Definitions to provide during preprocessing
        Dictionary<String, String> preprocessorDefinitions;

        // Translation units we are being asked to compile
        List<RefPtr<TranslationUnitRequest> > translationUnits;

        // Entry points we've been asked to compile (each
        // assocaited with a translation unit).
        List<RefPtr<EntryPointRequest> > entryPoints;

        // The code generation profile we've been asked to use.
        Profile profile;

        // Should we just pass the input to another compiler?
        PassThroughMode passThrough = PassThroughMode::None;

        // Compile flags to be shared by all translation units
        SlangCompileFlags compileFlags = 0;

        // Output stuff
        DiagnosticSink mSink;
        String mDiagnosticOutput;

        // Files that compilation depended on
        List<String> mDependencyFilePaths;

        // The resulting reflection layout information
        RefPtr<ProgramLayout> layout;

        // Modules that have been dynamically loaded via `import`
        //
        // This is a list of unique modules loaded, in the order they were encountered.
        List<RefPtr<ProgramSyntaxNode> > loadedModulesList;

        // Map from the logical name of a module to its definition
        Dictionary<String, RefPtr<ProgramSyntaxNode>> mapPathToLoadedModule;

        // Map from the path of a module file to its definition
        Dictionary<String, RefPtr<ProgramSyntaxNode>> mapNameToLoadedModules;


        CompileRequest(Session* session)
            : mSession(session)
        {}

        ~CompileRequest()
        {}

        void parseTranslationUnit(
            TranslationUnitRequest* translationUnit);

        void checkAllTranslationUnits();

        int executeActionsInner();
        int executeActions();

        int addTranslationUnit(SourceLanguage language, String const& name);

        void addTranslationUnitSourceString(
            int             translationUnitIndex,
            String const&   path,
            String const&   source);

        void addTranslationUnitSourceFile(
            int             translationUnitIndex,
            String const&   path);

        int addEntryPoint(
            int                     translationUnitIndex,
            String const&           name,
            Profile                 profile);

        RefPtr<ProgramSyntaxNode> loadModule(
            String const&       name,
            String const&       path,
            String const&       source,
            CodePosition const& loc);

        void handlePoundImport(
            String const&       path,
            TokenList const&    tokens);

        RefPtr<ProgramSyntaxNode> findOrImportModule(
            String const&       name,
            CodePosition const& loc);
    };

    void generateOutput(
        CompileRequest* compileRequest);
}

#endif
back to top