| // |
| // Copyright 2015 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. |
| // |
| |
| // ShaderGL.cpp: Implements the class methods for ShaderGL. |
| |
| #include "libANGLE/renderer/gl/ShaderGL.h" |
| |
| #include "common/debug.h" |
| #include "libANGLE/Compiler.h" |
| #include "libANGLE/Context.h" |
| #include "libANGLE/renderer/ContextImpl.h" |
| #include "libANGLE/renderer/gl/FunctionsGL.h" |
| #include "libANGLE/renderer/gl/RendererGL.h" |
| #include "libANGLE/trace.h" |
| #include "platform/autogen/FeaturesGL_autogen.h" |
| |
| #include <iostream> |
| |
| namespace rx |
| { |
| namespace |
| { |
| class ShaderTranslateTaskGL final : public ShaderTranslateTask |
| { |
| public: |
| ShaderTranslateTaskGL(const FunctionsGL *functions, |
| GLuint shaderID, |
| bool hasNativeParallelCompile) |
| : mFunctions(functions), |
| mShaderID(shaderID), |
| mHasNativeParallelCompile(hasNativeParallelCompile) |
| {} |
| ~ShaderTranslateTaskGL() override = default; |
| |
| void postTranslate(ShHandle compiler, const gl::CompiledShaderState &compiledState) override |
| { |
| const char *source = compiledState.translatedSource.c_str(); |
| mFunctions->shaderSource(mShaderID, 1, &source, nullptr); |
| mFunctions->compileShader(mShaderID); |
| } |
| |
| bool isCompilingInternally() override |
| { |
| if (!mHasNativeParallelCompile) |
| { |
| return false; |
| } |
| |
| GLint status = GL_FALSE; |
| mFunctions->getShaderiv(mShaderID, GL_COMPLETION_STATUS, &status); |
| return status != GL_TRUE; |
| } |
| |
| angle::Result getResult(std::string &infoLog) override |
| { |
| // Check for compile errors from the native driver |
| GLint compileStatus = GL_FALSE; |
| mFunctions->getShaderiv(mShaderID, GL_COMPILE_STATUS, &compileStatus); |
| if (compileStatus != GL_FALSE) |
| { |
| return angle::Result::Continue; |
| } |
| |
| // Compilation failed, put the error into the info log |
| GLint infoLogLength = 0; |
| mFunctions->getShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); |
| |
| // Info log length includes the null terminator, so 1 means that the info log is an empty |
| // string. |
| if (infoLogLength > 1) |
| { |
| std::vector<char> buf(infoLogLength); |
| mFunctions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]); |
| |
| infoLog += buf.data(); |
| } |
| else |
| { |
| WARN() << std::endl << "Shader compilation failed with no info log."; |
| } |
| |
| return angle::Result::Stop; |
| } |
| |
| private: |
| const FunctionsGL *mFunctions; |
| GLuint mShaderID; |
| bool mHasNativeParallelCompile; |
| }; |
| } // anonymous namespace |
| |
| ShaderGL::ShaderGL(const gl::ShaderState &data, |
| GLuint shaderID, |
| MultiviewImplementationTypeGL multiviewImplementationType, |
| const std::shared_ptr<RendererGL> &renderer) |
| : ShaderImpl(data), |
| mShaderID(shaderID), |
| mMultiviewImplementationType(multiviewImplementationType), |
| mRenderer(renderer) |
| {} |
| |
| ShaderGL::~ShaderGL() |
| { |
| ASSERT(mShaderID == 0); |
| } |
| |
| void ShaderGL::destroy() |
| { |
| mRenderer->getFunctions()->deleteShader(mShaderID); |
| mShaderID = 0; |
| } |
| |
| std::shared_ptr<ShaderTranslateTask> ShaderGL::compile(const gl::Context *context, |
| ShCompileOptions *options) |
| { |
| options->initGLPosition = true; |
| |
| bool isWebGL = context->isWebGL(); |
| if (isWebGL && mState.getShaderType() != gl::ShaderType::Compute) |
| { |
| options->initOutputVariables = true; |
| } |
| |
| if (isWebGL && !context->getState().getEnableFeature(GL_TEXTURE_RECTANGLE_ANGLE)) |
| { |
| options->disableARBTextureRectangle = true; |
| } |
| |
| const angle::FeaturesGL &features = GetFeaturesGL(context); |
| |
| if (features.initFragmentOutputVariables.enabled) |
| { |
| options->initFragmentOutputVariables = true; |
| } |
| |
| if (features.doWhileGLSLCausesGPUHang.enabled) |
| { |
| options->rewriteDoWhileLoops = true; |
| } |
| |
| if (features.emulateAbsIntFunction.enabled) |
| { |
| options->emulateAbsIntFunction = true; |
| } |
| |
| if (features.addAndTrueToLoopCondition.enabled) |
| { |
| options->addAndTrueToLoopCondition = true; |
| } |
| |
| if (features.emulateIsnanFloat.enabled) |
| { |
| options->emulateIsnanFloatFunction = true; |
| } |
| |
| if (features.emulateAtan2Float.enabled) |
| { |
| options->emulateAtan2FloatFunction = true; |
| } |
| |
| if (features.useUnusedBlocksWithStandardOrSharedLayout.enabled) |
| { |
| options->useUnusedStandardSharedBlocks = true; |
| } |
| |
| if (features.removeInvariantAndCentroidForESSL3.enabled) |
| { |
| options->removeInvariantAndCentroidForESSL3 = true; |
| } |
| |
| if (features.rewriteFloatUnaryMinusOperator.enabled) |
| { |
| options->rewriteFloatUnaryMinusOperator = true; |
| } |
| |
| if (!features.dontInitializeUninitializedLocals.enabled) |
| { |
| options->initializeUninitializedLocals = true; |
| } |
| |
| if (features.clampPointSize.enabled) |
| { |
| options->clampPointSize = true; |
| } |
| |
| if (features.dontUseLoopsToInitializeVariables.enabled) |
| { |
| options->dontUseLoopsToInitializeVariables = true; |
| } |
| |
| if (features.clampFragDepth.enabled) |
| { |
| options->clampFragDepth = true; |
| } |
| |
| if (features.rewriteRepeatedAssignToSwizzled.enabled) |
| { |
| options->rewriteRepeatedAssignToSwizzled = true; |
| } |
| |
| if (mMultiviewImplementationType == MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2) |
| { |
| options->initializeBuiltinsForInstancedMultiview = true; |
| options->selectViewInNvGLSLVertexShader = true; |
| } |
| |
| if (features.clampArrayAccess.enabled || isWebGL) |
| { |
| options->clampIndirectArrayBounds = true; |
| } |
| |
| if (features.vertexIDDoesNotIncludeBaseVertex.enabled) |
| { |
| options->addBaseVertexToVertexID = true; |
| } |
| |
| if (features.unfoldShortCircuits.enabled) |
| { |
| options->unfoldShortCircuit = true; |
| } |
| |
| if (features.removeDynamicIndexingOfSwizzledVector.enabled) |
| { |
| options->removeDynamicIndexingOfSwizzledVector = true; |
| } |
| |
| if (features.preAddTexelFetchOffsets.enabled) |
| { |
| options->rewriteTexelFetchOffsetToTexelFetch = true; |
| } |
| |
| if (features.regenerateStructNames.enabled) |
| { |
| options->regenerateStructNames = true; |
| } |
| |
| if (features.rewriteRowMajorMatrices.enabled) |
| { |
| options->rewriteRowMajorMatrices = true; |
| } |
| |
| if (features.passHighpToPackUnormSnormBuiltins.enabled) |
| { |
| options->passHighpToPackUnormSnormBuiltins = true; |
| } |
| |
| if (features.emulateClipDistanceState.enabled) |
| { |
| options->emulateClipDistanceState = true; |
| } |
| |
| if (features.emulateClipOrigin.enabled) |
| { |
| options->emulateClipOrigin = true; |
| } |
| |
| if (features.scalarizeVecAndMatConstructorArgs.enabled) |
| { |
| options->scalarizeVecAndMatConstructorArgs = true; |
| } |
| |
| if (features.explicitFragmentLocations.enabled) |
| { |
| options->explicitFragmentLocations = true; |
| } |
| |
| if (mRenderer->getNativeExtensions().shaderPixelLocalStorageANGLE) |
| { |
| options->pls = mRenderer->getNativePixelLocalStorageOptions(); |
| } |
| |
| return std::shared_ptr<ShaderTranslateTask>(new ShaderTranslateTaskGL( |
| mRenderer->getFunctions(), mShaderID, mRenderer->hasNativeParallelCompile())); |
| } |
| |
| std::string ShaderGL::getDebugInfo() const |
| { |
| return mState.getCompiledState()->translatedSource; |
| } |
| |
| GLuint ShaderGL::getShaderID() const |
| { |
| return mShaderID; |
| } |
| |
| } // namespace rx |