Edit

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

Branch :

  • Show log

    Commit

  • Author : Martin Radev
    Date : 2016-08-04 12:25:34
    Hash : 4c4c8e72
    Message : Add compute program compilation and linking support Compute shaders can be now compiled and linked to create programs. Some tests are added to verify successful and unsuccessful compute shader linking. The patch also replaces std::array<int, 3> with a custom struct WorkGroupSize. BUG=angleproject:1442 TEST=angle_end2end_tests TEST=angle_unittests Change-Id: I4ab0ac05755d0167a6d2a798f8d7f1516cf54d84 Reviewed-on: https://chromium-review.googlesource.com/366740 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Olli Etuaho <oetuaho@nvidia.com> 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
    {
    
    // Global count of active shader compiler handles. Needed to know when to call ShInitialize and
    // ShFinalize.
    size_t activeCompilerHandles = 0;
    
    ShShaderSpec SelectShaderSpec(GLint majorVersion, GLint minorVersion)
    {
        if (majorVersion >= 3)
        {
            if (minorVersion == 1)
            {
                return SH_GLES3_1_SPEC;
            }
            else
            {
                return SH_GLES3_SPEC;
            }
        }
        return SH_GLES2_SPEC;
    }
    
    }  // anonymous namespace
    
    Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state)
        : mImplementation(implFactory->createCompiler()),
          mSpec(SelectShaderSpec(state.getClientMajorVersion(), state.getClientMinorVersion())),
          mOutputType(mImplementation->getTranslatorOutputType()),
          mResources(),
          mFragmentCompiler(nullptr),
          mVertexCompiler(nullptr),
          mComputeCompiler(nullptr)
    {
        ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3);
    
        const gl::Caps &caps             = state.getCaps();
        const gl::Extensions &extensions = state.getExtensions();
    
        ShInitBuiltInResources(&mResources);
        mResources.MaxVertexAttribs             = caps.maxVertexAttributes;
        mResources.MaxVertexUniformVectors      = caps.maxVertexUniformVectors;
        mResources.MaxVaryingVectors            = caps.maxVaryingVectors;
        mResources.MaxVertexTextureImageUnits   = caps.maxVertexTextureImageUnits;
        mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
        mResources.MaxTextureImageUnits         = caps.maxTextureImageUnits;
        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;
        // TODO: use shader precision caps to determine if high precision is supported?
        mResources.FragmentPrecisionHigh = 1;
        mResources.EXT_frag_depth        = extensions.fragDepth;
    
        // GLSL ES 3.0 constants
        mResources.MaxVertexOutputVectors  = caps.maxVertexOutputComponents / 4;
        mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
        mResources.MinProgramTexelOffset   = caps.minProgramTexelOffset;
        mResources.MaxProgramTexelOffset   = caps.maxProgramTexelOffset;
    
        // GLSL ES 3.1 compute shader constants
        mResources.MaxImageUnits                    = caps.maxImageUnits;
        mResources.MaxVertexImageUniforms           = caps.maxVertexImageUniforms;
        mResources.MaxFragmentImageUniforms         = caps.maxFragmentImageUniforms;
        mResources.MaxComputeImageUniforms          = caps.maxComputeImageUniforms;
        mResources.MaxCombinedImageUniforms         = caps.maxCombinedImageUniforms;
        mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
    
        for (size_t index = 0u; index < 3u; ++index)
        {
            mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
            mResources.MaxComputeWorkGroupSize[index]  = caps.maxComputeWorkGroupSize[index];
        }
    
        mResources.MaxComputeUniformComponents = caps.maxComputeUniformComponents;
        mResources.MaxComputeTextureImageUnits = caps.maxComputeTextureImageUnits;
    
        mResources.MaxComputeAtomicCounters       = caps.maxComputeAtomicCounters;
        mResources.MaxComputeAtomicCounterBuffers = caps.maxComputeAtomicCounterBuffers;
    
        mResources.MaxVertexAtomicCounters         = caps.maxVertexAtomicCounters;
        mResources.MaxFragmentAtomicCounters       = caps.maxFragmentAtomicCounters;
        mResources.MaxCombinedAtomicCounters       = caps.maxCombinedAtomicCounters;
        mResources.MaxAtomicCounterBindings        = caps.maxAtomicCounterBufferBindings;
        mResources.MaxVertexAtomicCounterBuffers   = caps.maxVertexAtomicCounterBuffers;
        mResources.MaxFragmentAtomicCounterBuffers = caps.maxFragmentAtomicCounterBuffers;
        mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
        mResources.MaxAtomicCounterBufferSize      = caps.maxAtomicCounterBufferSize;
    }
    
    Compiler::~Compiler()
    {
        release();
        SafeDelete(mImplementation);
    }
    
    Error Compiler::release()
    {
        if (mFragmentCompiler)
        {
            ShDestruct(mFragmentCompiler);
            mFragmentCompiler = nullptr;
    
            ASSERT(activeCompilerHandles > 0);
            activeCompilerHandles--;
        }
    
        if (mVertexCompiler)
        {
            ShDestruct(mVertexCompiler);
            mVertexCompiler = nullptr;
    
            ASSERT(activeCompilerHandles > 0);
            activeCompilerHandles--;
        }
    
        if (mComputeCompiler)
        {
            ShDestruct(mComputeCompiler);
            mComputeCompiler = nullptr;
    
            ASSERT(activeCompilerHandles > 0);
            activeCompilerHandles--;
        }
    
        if (activeCompilerHandles == 0)
        {
            ShFinalize();
        }
    
        mImplementation->release();
    
        return gl::Error(GL_NO_ERROR);
    }
    
    ShHandle Compiler::getCompilerHandle(GLenum type)
    {
        ShHandle *compiler = nullptr;
        switch (type)
        {
            case GL_VERTEX_SHADER:
                compiler = &mVertexCompiler;
                break;
    
            case GL_FRAGMENT_SHADER:
                compiler = &mFragmentCompiler;
                break;
            case GL_COMPUTE_SHADER:
                compiler = &mComputeCompiler;
                break;
            default:
                UNREACHABLE();
                return nullptr;
        }
    
        if (!(*compiler))
        {
            if (activeCompilerHandles == 0)
            {
                ShInitialize();
            }
    
            *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources);
            activeCompilerHandles++;
        }
    
        return *compiler;
    }
    
    }  // namespace gl