blob: 616fb562908a10bd1b2c1e03b20c0c8ea888d6d0 [file] [log] [blame]
//
// 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