Edit

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

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2018-09-18 17:23:28
    Hash : ab5fb5ed
    Message : Reland "Support EXT_blend_func_extended in the GLES2 context" This re-lands EXT_blend_func_extended implementation. A lot of the implementation has been rewritten on top of changes that have been done since the last attempt. For now we only expose the extension on desktop GL. To support GLES, we'd need to investigate what's the most robust way to handle the compiler output and make the binding of the fragment outputs conditional. The extension is disabled on AMD and Intel because of test failures. BUG=angleproject:1085 TEST=angle_end2end_tests Change-Id: I619ae3162769b90aad095ddec158ce6c57a114a8 Reviewed-on: https://chromium-review.googlesource.com/1233713 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>

  • src/libANGLE/Compiler.cpp
  • //
    // Copyright (c) 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/ContextState.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)
    {
        if (majorVersion >= 3)
        {
            if (minorVersion == 1)
            {
                return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
            }
            else
            {
                return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
            }
        }
    
        // 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 ContextState &state)
        : mImplementation(implFactory->createCompiler()),
          mSpec(SelectShaderSpec(state.getClientMajorVersion(),
                                 state.getClientMinorVersion(),
                                 state.getExtensions().webglCompatibility)),
          mOutputType(mImplementation->getTranslatorOutputType()),
          mResources()
    {
        ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 ||
               state.getClientMajorVersion() == 3);
    
        const gl::Caps &caps             = state.getCaps();
        const gl::Extensions &extensions = state.getExtensions();
    
        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.standardDerivatives;
        mResources.EXT_draw_buffers             = extensions.drawBuffers;
        mResources.EXT_shader_texture_lod       = extensions.shaderTextureLOD;
        mResources.OES_EGL_image_external       = extensions.eglImageExternal;
        mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3;
        mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal;
        mResources.ARB_texture_rectangle           = extensions.textureRectangle;
        mResources.OES_texture_storage_multisample_2d_array =
            extensions.textureStorageMultisample2DArray;
        // 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;
        mResources.MaxViewsOVR   = extensions.maxViews;
    
        // 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;
    
        // 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];
    }
    
    Compiler::~Compiler()
    {
        for (auto &pool : mPools)
        {
            for (ShCompilerInstance &instance : pool)
            {
                instance.destroy();
            }
        }
        --gActiveCompilers;
        if (gActiveCompilers == 0)
        {
            sh::Finalize();
        }
        ANGLE_SWALLOW_ERR(mImplementation->release());
    }
    
    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