Edit

kc3-lang/angle/src/libANGLE/Compiler.cpp

Branch :

  • Show log

    Commit

  • Author : Mohan Maiya
    Date : 2021-02-24 09:49:42
    Hash : 550f2a3e
    Message : Vulkan: Shader support for EXT_shader_framebuffer_fetch_non_coherent Translator can accept gl_LastFragData and 'inout' variable to gain access to framebuffer attachment data. The Vulkan translator replaces it with the SubpassInput type variable. Note that this works only for the noncoherent version of the extension. Bug: angleproject:5454 Test: *EXTShaderFramebufferFetchNoncoherent*.* Change-Id: I392f84ee3ad3eb9fbd09d0b7ff83731a9a3f33f6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2598060 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>

  • src/libANGLE/Compiler.cpp
  • //
    // Copyright 2014 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.
    //
    
    // Compiler.cpp: implements the gl::Compiler class.
    
    #include "libANGLE/Compiler.h"
    
    #include "common/debug.h"
    #include "libANGLE/Context.h"
    #include "libANGLE/Display.h"
    #include "libANGLE/State.h"
    #include "libANGLE/renderer/CompilerImpl.h"
    #include "libANGLE/renderer/GLImplFactory.h"
    
    namespace gl
    {
    
    namespace
    {
    
    // To know when to call sh::Initialize and sh::Finalize.
    size_t gActiveCompilers = 0;
    
    ShShaderSpec SelectShaderSpec(GLint majorVersion,
                                  GLint minorVersion,
                                  bool isWebGL,
                                  EGLenum clientType)
    {
        // For Desktop GL
        if (clientType == EGL_OPENGL_API)
        {
            return SH_GL_COMPATIBILITY_SPEC;
        }
    
        if (majorVersion >= 3)
        {
            switch (minorVersion)
            {
                case 2:
                    ASSERT(!isWebGL);
                    return SH_GLES3_2_SPEC;
                case 1:
                    return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
                case 0:
                    return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
                default:
                    UNREACHABLE();
            }
        }
    
        // GLES1 emulation: Use GLES3 shader spec.
        if (!isWebGL && majorVersion == 1)
        {
            return SH_GLES3_SPEC;
        }
    
        return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
    }
    
    }  // anonymous namespace
    
    Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Display *display)
        : mImplementation(implFactory->createCompiler()),
          mSpec(SelectShaderSpec(state.getClientMajorVersion(),
                                 state.getClientMinorVersion(),
                                 state.getExtensions().webglCompatibility,
                                 state.getClientType())),
          mOutputType(mImplementation->getTranslatorOutputType()),
          mResources()
    {
        // TODO(http://anglebug.com/3819): Update for GL version specific validation
        ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 ||
               state.getClientMajorVersion() == 3 || state.getClientMajorVersion() == 4);
    
        const gl::Caps &caps             = state.getCaps();
        const gl::Extensions &extensions = state.getExtensions();
    
        {
            std::lock_guard<std::mutex> lock(display->getDisplayGlobalMutex());
            if (gActiveCompilers == 0)
            {
                sh::Initialize();
            }
            ++gActiveCompilers;
        }
    
        sh::InitBuiltInResources(&mResources);
        mResources.MaxVertexAttribs             = caps.maxVertexAttributes;
        mResources.MaxVertexUniformVectors      = caps.maxVertexUniformVectors;
        mResources.MaxVaryingVectors            = caps.maxVaryingVectors;
        mResources.MaxVertexTextureImageUnits   = caps.maxShaderTextureImageUnits[ShaderType::Vertex];
        mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
        mResources.MaxTextureImageUnits         = caps.maxShaderTextureImageUnits[ShaderType::Fragment];
        mResources.MaxFragmentUniformVectors    = caps.maxFragmentUniformVectors;
        mResources.MaxDrawBuffers               = caps.maxDrawBuffers;
        mResources.OES_standard_derivatives     = extensions.standardDerivativesOES;
        mResources.EXT_draw_buffers             = extensions.drawBuffers;
        mResources.EXT_shader_texture_lod       = extensions.shaderTextureLOD;
        mResources.EXT_shader_non_constant_global_initializers =
            extensions.shaderNonConstGlobalInitializersEXT;
        mResources.OES_EGL_image_external                = extensions.eglImageExternalOES;
        mResources.OES_EGL_image_external_essl3          = extensions.eglImageExternalEssl3OES;
        mResources.NV_EGL_stream_consumer_external       = extensions.eglStreamConsumerExternalNV;
        mResources.NV_shader_noperspective_interpolation = extensions.noperspectiveInterpolationNV;
        mResources.ARB_texture_rectangle                 = extensions.textureRectangle;
        mResources.EXT_gpu_shader5                       = extensions.gpuShader5EXT;
        mResources.OES_shader_io_blocks                  = extensions.shaderIoBlocksOES;
        mResources.EXT_shader_io_blocks                  = extensions.shaderIoBlocksEXT;
        mResources.OES_texture_storage_multisample_2d_array =
            extensions.textureStorageMultisample2DArrayOES;
        mResources.OES_texture_3D                  = extensions.texture3DOES;
        mResources.ANGLE_texture_multisample       = extensions.textureMultisample;
        mResources.ANGLE_multi_draw                = extensions.multiDraw;
        mResources.ANGLE_base_vertex_base_instance = extensions.baseVertexBaseInstance;
        mResources.APPLE_clip_distance             = extensions.clipDistanceAPPLE;
        // OES_shader_multisample_interpolation
        mResources.OES_shader_multisample_interpolation = extensions.multisampleInterpolationOES;
        mResources.OES_shader_image_atomic              = extensions.shaderImageAtomicOES;
        // TODO: use shader precision caps to determine if high precision is supported?
        mResources.FragmentPrecisionHigh = 1;
        mResources.EXT_frag_depth        = extensions.fragDepth;
    
        // OVR_multiview state
        mResources.OVR_multiview = extensions.multiview;
    
        // OVR_multiview2 state
        mResources.OVR_multiview2 = extensions.multiview2;
        mResources.MaxViewsOVR    = extensions.maxViews;
    
        // EXT_multisampled_render_to_texture and EXT_multisampled_render_to_texture2
        mResources.EXT_multisampled_render_to_texture  = extensions.multisampledRenderToTexture;
        mResources.EXT_multisampled_render_to_texture2 = extensions.multisampledRenderToTexture2;
    
        // WEBGL_video_texture
        mResources.WEBGL_video_texture = extensions.webglVideoTexture;
    
        // OES_texture_cube_map_array
        mResources.OES_texture_cube_map_array = extensions.textureCubeMapArrayOES;
        mResources.EXT_texture_cube_map_array = extensions.textureCubeMapArrayEXT;
    
        // EXT_shadow_samplers
        mResources.EXT_shadow_samplers = extensions.shadowSamplersEXT;
    
        // OES_texture_buffer
        mResources.OES_texture_buffer = extensions.textureBufferOES;
        mResources.EXT_texture_buffer = extensions.textureBufferEXT;
    
        // GL_EXT_YUV_target
        mResources.EXT_YUV_target = extensions.yuvTargetEXT;
    
        mResources.EXT_shader_framebuffer_fetch_non_coherent =
            extensions.shaderFramebufferFetchNonCoherentEXT;
    
        // GL_EXT_clip_cull_distance
        mResources.EXT_clip_cull_distance = extensions.clipCullDistanceEXT;
    
        // GLSL ES 3.0 constants
        mResources.MaxVertexOutputVectors  = caps.maxVertexOutputComponents / 4;
        mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
        mResources.MinProgramTexelOffset   = caps.minProgramTexelOffset;
        mResources.MaxProgramTexelOffset   = caps.maxProgramTexelOffset;
    
        // EXT_blend_func_extended
        mResources.EXT_blend_func_extended  = extensions.blendFuncExtended;
        mResources.MaxDualSourceDrawBuffers = extensions.maxDualSourceDrawBuffers;
    
        // APPLE_clip_distance/EXT_clip_cull_distance
        mResources.MaxClipDistances                = caps.maxClipDistances;
        mResources.MaxCullDistances                = caps.maxCullDistances;
        mResources.MaxCombinedClipAndCullDistances = caps.maxCombinedClipAndCullDistances;
    
        // OES_sample_variables
        mResources.OES_sample_variables = extensions.sampleVariablesOES;
        mResources.MaxSamples           = caps.maxSamples;
    
        // GLSL ES 3.1 constants
        mResources.MaxProgramTextureGatherOffset    = caps.maxProgramTextureGatherOffset;
        mResources.MinProgramTextureGatherOffset    = caps.minProgramTextureGatherOffset;
        mResources.MaxImageUnits                    = caps.maxImageUnits;
        mResources.MaxVertexImageUniforms           = caps.maxShaderImageUniforms[ShaderType::Vertex];
        mResources.MaxFragmentImageUniforms         = caps.maxShaderImageUniforms[ShaderType::Fragment];
        mResources.MaxComputeImageUniforms          = caps.maxShaderImageUniforms[ShaderType::Compute];
        mResources.MaxCombinedImageUniforms         = caps.maxCombinedImageUniforms;
        mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
        mResources.MaxUniformLocations              = caps.maxUniformLocations;
    
        for (size_t index = 0u; index < 3u; ++index)
        {
            mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
            mResources.MaxComputeWorkGroupSize[index]  = caps.maxComputeWorkGroupSize[index];
        }
    
        mResources.MaxComputeUniformComponents = caps.maxShaderUniformComponents[ShaderType::Compute];
        mResources.MaxComputeTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Compute];
    
        mResources.MaxComputeAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Compute];
        mResources.MaxComputeAtomicCounterBuffers =
            caps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
    
        mResources.MaxVertexAtomicCounters   = caps.maxShaderAtomicCounters[ShaderType::Vertex];
        mResources.MaxFragmentAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Fragment];
        mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters;
        mResources.MaxAtomicCounterBindings  = caps.maxAtomicCounterBufferBindings;
        mResources.MaxVertexAtomicCounterBuffers =
            caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
        mResources.MaxFragmentAtomicCounterBuffers =
            caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
        mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
        mResources.MaxAtomicCounterBufferSize      = caps.maxAtomicCounterBufferSize;
    
        mResources.MaxUniformBufferBindings       = caps.maxUniformBufferBindings;
        mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
    
        // Needed by point size clamping workaround
        mResources.MaxPointSize = caps.maxAliasedPointSize;
    
        if (state.getClientMajorVersion() == 2 && !extensions.drawBuffers)
        {
            mResources.MaxDrawBuffers = 1;
        }
    
        // Geometry Shader constants
        mResources.EXT_geometry_shader          = extensions.geometryShader;
        mResources.MaxGeometryUniformComponents = caps.maxShaderUniformComponents[ShaderType::Geometry];
        mResources.MaxGeometryUniformBlocks     = caps.maxShaderUniformBlocks[ShaderType::Geometry];
        mResources.MaxGeometryInputComponents   = caps.maxGeometryInputComponents;
        mResources.MaxGeometryOutputComponents  = caps.maxGeometryOutputComponents;
        mResources.MaxGeometryOutputVertices    = caps.maxGeometryOutputVertices;
        mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
        mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry];
    
        mResources.MaxGeometryAtomicCounterBuffers =
            caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
        mResources.MaxGeometryAtomicCounters      = caps.maxShaderAtomicCounters[ShaderType::Geometry];
        mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry];
        mResources.MaxGeometryShaderInvocations   = caps.maxGeometryShaderInvocations;
        mResources.MaxGeometryImageUniforms       = caps.maxShaderImageUniforms[ShaderType::Geometry];
    
        // Tessellation Shader constants
        mResources.EXT_tessellation_shader        = extensions.tessellationShaderEXT;
        mResources.MaxTessControlInputComponents  = caps.maxTessControlInputComponents;
        mResources.MaxTessControlOutputComponents = caps.maxTessControlOutputComponents;
        mResources.MaxTessControlTextureImageUnits =
            caps.maxShaderTextureImageUnits[ShaderType::TessControl];
        mResources.MaxTessControlUniformComponents =
            caps.maxShaderUniformComponents[ShaderType::TessControl];
        mResources.MaxTessControlTotalOutputComponents = caps.maxTessControlTotalOutputComponents;
        mResources.MaxTessControlImageUniforms  = caps.maxShaderImageUniforms[ShaderType::TessControl];
        mResources.MaxTessControlAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::TessControl];
        mResources.MaxTessControlAtomicCounterBuffers =
            caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl];
    
        mResources.MaxTessPatchComponents = caps.maxTessPatchComponents;
        mResources.MaxPatchVertices       = caps.maxPatchVertices;
        mResources.MaxTessGenLevel        = caps.maxTessGenLevel;
    
        mResources.MaxTessEvaluationInputComponents  = caps.maxTessEvaluationInputComponents;
        mResources.MaxTessEvaluationOutputComponents = caps.maxTessEvaluationOutputComponents;
        mResources.MaxTessEvaluationTextureImageUnits =
            caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation];
        mResources.MaxTessEvaluationUniformComponents =
            caps.maxShaderUniformComponents[ShaderType::TessEvaluation];
        mResources.MaxTessEvaluationImageUniforms =
            caps.maxShaderImageUniforms[ShaderType::TessEvaluation];
        mResources.MaxTessEvaluationAtomicCounters =
            caps.maxShaderAtomicCounters[ShaderType::TessEvaluation];
        mResources.MaxTessEvaluationAtomicCounterBuffers =
            caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation];
    
        // Subpixel bits.
        mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
    }
    
    Compiler::~Compiler() = default;
    
    void Compiler::onDestroy(const Context *context)
    {
        std::lock_guard<std::mutex> lock(context->getDisplay()->getDisplayGlobalMutex());
        for (auto &pool : mPools)
        {
            for (ShCompilerInstance &instance : pool)
            {
                instance.destroy();
            }
        }
        --gActiveCompilers;
        if (gActiveCompilers == 0)
        {
            sh::Finalize();
        }
    }
    
    ShCompilerInstance Compiler::getInstance(ShaderType type)
    {
        ASSERT(type != ShaderType::InvalidEnum);
        auto &pool = mPools[type];
        if (pool.empty())
        {
            ShHandle handle = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources);
            ASSERT(handle);
            return ShCompilerInstance(handle, mOutputType, type);
        }
        else
        {
            ShCompilerInstance instance = std::move(pool.back());
            pool.pop_back();
            return instance;
        }
    }
    
    void Compiler::putInstance(ShCompilerInstance &&instance)
    {
        static constexpr size_t kMaxPoolSize = 32;
        auto &pool                           = mPools[instance.getShaderType()];
        if (pool.size() < kMaxPoolSize)
        {
            pool.push_back(std::move(instance));
        }
        else
        {
            instance.destroy();
        }
    }
    
    ShCompilerInstance::ShCompilerInstance() : mHandle(nullptr) {}
    
    ShCompilerInstance::ShCompilerInstance(ShHandle handle,
                                           ShShaderOutput outputType,
                                           ShaderType shaderType)
        : mHandle(handle), mOutputType(outputType), mShaderType(shaderType)
    {}
    
    ShCompilerInstance::~ShCompilerInstance()
    {
        ASSERT(mHandle == nullptr);
    }
    
    void ShCompilerInstance::destroy()
    {
        if (mHandle != nullptr)
        {
            sh::Destruct(mHandle);
            mHandle = nullptr;
        }
    }
    
    ShCompilerInstance::ShCompilerInstance(ShCompilerInstance &&other)
        : mHandle(other.mHandle), mOutputType(other.mOutputType), mShaderType(other.mShaderType)
    {
        other.mHandle = nullptr;
    }
    
    ShCompilerInstance &ShCompilerInstance::operator=(ShCompilerInstance &&other)
    {
        mHandle       = other.mHandle;
        mOutputType   = other.mOutputType;
        mShaderType   = other.mShaderType;
        other.mHandle = nullptr;
        return *this;
    }
    
    ShHandle ShCompilerInstance::getHandle()
    {
        return mHandle;
    }
    
    ShaderType ShCompilerInstance::getShaderType() const
    {
        return mShaderType;
    }
    
    const std::string &ShCompilerInstance::getBuiltinResourcesString()
    {
        return sh::GetBuiltInResourcesString(mHandle);
    }
    
    ShShaderOutput ShCompilerInstance::getShaderOutputType() const
    {
        return mOutputType;
    }
    
    }  // namespace gl