Edit

kc3-lang/angle/src/compiler/translator/glslang_wrapper.cpp

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2021-04-07 15:23:32
    Hash : 81f03cc0
    Message : Allow translator to use headers from common/spirv Bug: angleproject:4889 Change-Id: Ia297888a97c0ba9cec1283db7f94f2e5b362c27e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2815179 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • src/compiler/translator/glslang_wrapper.cpp
  • //
    // Copyright 2021 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // glslang_wrapper:
    //   A wrapper to compile GLSL strings to SPIR-V blobs.  glslang here refers to the Khronos
    //   compiler.
    //
    //   This file is separated as glslang's header contains conflicting macro definitions with ANGLE's.
    //
    
    #include "compiler/translator/glslang_wrapper.h"
    
    // glslang has issues with some specific warnings.
    ANGLE_DISABLE_SHADOWING_WARNING
    ANGLE_DISABLE_SUGGEST_OVERRIDE_WARNINGS
    
    // glslang's version of ShaderLang.h, not to be confused with ANGLE's.
    #include <glslang/Public/ShaderLang.h>
    
    // Other glslang includes.
    #include <SPIRV/GlslangToSpv.h>
    #include <StandAlone/ResourceLimits.h>
    
    // SPIR-V tools include for disassembly
    #include <spirv-tools/libspirv.hpp>
    
    // Enable this for debug logging of pre-transform SPIR-V:
    #if !defined(ANGLE_DEBUG_SPIRV_TRANSFORMER)
    #    define ANGLE_DEBUG_SPIRV_TRANSFORMER 0
    #endif  // !defined(ANGLE_DEBUG_SPIRV_TRANSFORMER)
    
    ANGLE_REENABLE_SUGGEST_OVERRIDE_WARNINGS
    ANGLE_REENABLE_SHADOWING_WARNING
    
    namespace sh
    {
    namespace
    {
    // Run at startup to warm up glslang's internals to avoid hitches on first shader compile.
    void Warmup()
    {
        EShMessages messages = static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
    
        const TBuiltInResource builtInResources(glslang::DefaultTBuiltInResource);
        glslang::TShader warmUpShader(EShLangVertex);
    
        const char *kShaderString = R"(#version 450 core
            void main(){}
        )";
        const int kShaderLength   = static_cast<int>(strlen(kShaderString));
    
        warmUpShader.setStringsWithLengths(&kShaderString, &kShaderLength, 1);
        warmUpShader.setEntryPoint("main");
    
        bool result = warmUpShader.parse(&builtInResources, 450, ECoreProfile, false, false, messages);
        ASSERT(result);
    }
    
    // Generate glslang resources from ANGLE translator resources.
    void GetBuiltInResources(const ShBuiltInResources &resources, TBuiltInResource *outResources)
    {
        outResources->maxDrawBuffers                   = resources.MaxDrawBuffers;
        outResources->maxAtomicCounterBindings         = resources.MaxAtomicCounterBindings;
        outResources->maxAtomicCounterBufferSize       = resources.MaxAtomicCounterBufferSize;
        outResources->maxCombinedAtomicCounterBuffers  = resources.MaxCombinedAtomicCounterBuffers;
        outResources->maxCombinedAtomicCounters        = resources.MaxCombinedAtomicCounters;
        outResources->maxCombinedImageUniforms         = resources.MaxCombinedImageUniforms;
        outResources->maxCombinedTextureImageUnits     = resources.MaxCombinedTextureImageUnits;
        outResources->maxCombinedShaderOutputResources = resources.MaxCombinedShaderOutputResources;
        outResources->maxComputeWorkGroupCountX        = resources.MaxComputeWorkGroupCount[0];
        outResources->maxComputeWorkGroupCountY        = resources.MaxComputeWorkGroupCount[1];
        outResources->maxComputeWorkGroupCountZ        = resources.MaxComputeWorkGroupCount[2];
        outResources->maxComputeWorkGroupSizeX         = resources.MaxComputeWorkGroupSize[0];
        outResources->maxComputeWorkGroupSizeY         = resources.MaxComputeWorkGroupSize[1];
        outResources->maxComputeWorkGroupSizeZ         = resources.MaxComputeWorkGroupSize[2];
        outResources->minProgramTexelOffset            = resources.MinProgramTexelOffset;
        outResources->maxFragmentUniformVectors        = resources.MaxFragmentUniformVectors;
        outResources->maxGeometryInputComponents       = resources.MaxGeometryInputComponents;
        outResources->maxGeometryOutputComponents      = resources.MaxGeometryOutputComponents;
        outResources->maxGeometryOutputVertices        = resources.MaxGeometryOutputVertices;
        outResources->maxGeometryTotalOutputComponents = resources.MaxGeometryTotalOutputComponents;
        outResources->maxPatchVertices                 = resources.MaxPatchVertices;
        outResources->maxProgramTexelOffset            = resources.MaxProgramTexelOffset;
        outResources->maxVaryingVectors                = resources.MaxVaryingVectors;
        outResources->maxVertexUniformVectors          = resources.MaxVertexUniformVectors;
        outResources->maxClipDistances                 = resources.MaxClipDistances;
        outResources->maxSamples                       = resources.MaxSamples;
        outResources->maxCullDistances                 = resources.MaxCullDistances;
        outResources->maxCombinedClipAndCullDistances  = resources.MaxCombinedClipAndCullDistances;
    }
    }  // anonymous namespace
    
    void GlslangInitialize()
    {
        int result = ShInitialize();
        ASSERT(result != 0);
        Warmup();
    }
    
    void GlslangFinalize()
    {
        int result = ShFinalize();
        ASSERT(result != 0);
    }
    
    ANGLE_NO_DISCARD bool GlslangCompileToSpirv(const ShBuiltInResources &resources,
                                                sh::GLenum shaderType,
                                                const std::string &shaderSource,
                                                angle::spirv::Blob *spirvBlobOut)
    {
        TBuiltInResource builtInResources(glslang::DefaultTBuiltInResource);
        GetBuiltInResources(resources, &builtInResources);
    
        EShLanguage language = EShLangVertex;
    
        switch (shaderType)
        {
            case GL_VERTEX_SHADER:
                language = EShLangVertex;
                break;
            case GL_TESS_CONTROL_SHADER:
                language = EShLangTessControl;
                break;
            case GL_TESS_EVALUATION_SHADER_EXT:
                language = EShLangTessEvaluation;
                break;
            case GL_GEOMETRY_SHADER:
                language = EShLangGeometry;
                break;
            case GL_FRAGMENT_SHADER:
                language = EShLangFragment;
                break;
            case GL_COMPUTE_SHADER:
                language = EShLangCompute;
                break;
            default:
                UNREACHABLE();
        }
    
        glslang::TShader shader(language);
        glslang::TProgram program;
    
        // Enable SPIR-V and Vulkan rules when parsing GLSL
        constexpr EShMessages messages = static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
    
        const char *shaderString = shaderSource.c_str();
        int shaderLength         = static_cast<int>(shaderSource.size());
    
        shader.setStringsWithLengths(&shaderString, &shaderLength, 1);
        shader.setEntryPoint("main");
    
        bool result = shader.parse(&builtInResources, 450, ECoreProfile, false, false, messages);
        if (!result)
        {
            WARN() << "Internal error parsing Vulkan shader corresponding to " << shaderType << ":\n"
                   << shader.getInfoLog() << "\n"
                   << shader.getInfoDebugLog() << "\n";
            return false;
        }
    
        program.addShader(&shader);
    
        bool linkResult = program.link(messages);
        if (!linkResult)
        {
            WARN() << "Internal error linking Vulkan shader:\n" << program.getInfoLog() << "\n";
        }
    
        glslang::TIntermediate *intermediate = program.getIntermediate(language);
        glslang::GlslangToSpv(*intermediate, *spirvBlobOut);
    
    #if ANGLE_DEBUG_SPIRV_TRANSFORMER
        spvtools::SpirvTools spirvTools(SPV_ENV_VULKAN_1_1);
        std::string readableSpirv;
        spirvTools.Disassemble(*spirvBlobOut, &readableSpirv, 0);
        fprintf(stderr, "%s\n%s\n", shaderString, readableSpirv.c_str());
    #endif  // ANGLE_DEBUG_SPIRV_TRANSFORMER
    
        return true;
    }
    }  // namespace sh