blob: 37d824e511e3d310b8070c77ee35f587dceb2741 [file] [log] [blame]
//
// Copyright 2002 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.
//
// Shader.h: Defines the abstract gl::Shader class and its concrete derived
// classes VertexShader and FragmentShader. Implements GL shader objects and
// related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section
// 3.8 page 84.
#ifndef LIBANGLE_SHADER_H_
#define LIBANGLE_SHADER_H_
#include <list>
#include <memory>
#include <string>
#include <vector>
#include <GLSLANG/ShaderLang.h>
#include "angle_gl.h"
#include "common/Optional.h"
#include "common/angleutils.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Compiler.h"
#include "libANGLE/Debug.h"
#include "libANGLE/angletypes.h"
namespace rx
{
class GLImplFactory;
class ShaderImpl;
class ShaderSh;
class WaitableCompileEvent;
} // namespace rx
namespace angle
{
class WaitableEvent;
class WorkerThreadPool;
} // namespace angle
namespace gl
{
class CompileTask;
class Context;
class ShaderProgramManager;
class State;
// We defer the compile until link time, or until properties are queried.
enum class CompileStatus
{
NOT_COMPILED,
COMPILE_REQUESTED,
COMPILED,
};
class ShaderState final : angle::NonCopyable
{
public:
ShaderState(ShaderType shaderType);
~ShaderState();
const std::string &getLabel() const { return mLabel; }
const std::string &getSource() const { return mSource; }
bool isCompiledToBinary() const { return !mCompiledBinary.empty(); }
const std::string &getTranslatedSource() const { return mTranslatedSource; }
const sh::BinaryBlob &getCompiledBinary() const { return mCompiledBinary; }
ShaderType getShaderType() const { return mShaderType; }
int getShaderVersion() const { return mShaderVersion; }
const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; }
const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; }
const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
{
return mShaderStorageBlocks;
}
const std::vector<sh::ShaderVariable> &getActiveAttributes() const { return mActiveAttributes; }
const std::vector<sh::ShaderVariable> &getAllAttributes() const { return mAllAttributes; }
const std::vector<sh::ShaderVariable> &getActiveOutputVariables() const
{
return mActiveOutputVariables;
}
bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; }
const sh::WorkGroupSize &getLocalSize() const { return mLocalSize; }
bool getEarlyFragmentTestsOptimization() const { return mEarlyFragmentTestsOptimization; }
rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
int getNumViews() const { return mNumViews; }
Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType() const
{
return mGeometryShaderInputPrimitiveType;
}
Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType() const
{
return mGeometryShaderOutputPrimitiveType;
}
Optional<GLint> geoGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
Optional<GLint> getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
CompileStatus getCompileStatus() const { return mCompileStatus; }
private:
friend class Shader;
std::string mLabel;
ShaderType mShaderType;
int mShaderVersion;
std::string mTranslatedSource;
sh::BinaryBlob mCompiledBinary;
std::string mSource;
sh::WorkGroupSize mLocalSize;
std::vector<sh::ShaderVariable> mInputVaryings;
std::vector<sh::ShaderVariable> mOutputVaryings;
std::vector<sh::ShaderVariable> mUniforms;
std::vector<sh::InterfaceBlock> mUniformBlocks;
std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
std::vector<sh::ShaderVariable> mAllAttributes;
std::vector<sh::ShaderVariable> mActiveAttributes;
std::vector<sh::ShaderVariable> mActiveOutputVariables;
bool mEarlyFragmentTestsOptimization;
rx::SpecConstUsageBits mSpecConstUsageBits;
// ANGLE_multiview.
int mNumViews;
// Geometry Shader.
Optional<PrimitiveMode> mGeometryShaderInputPrimitiveType;
Optional<PrimitiveMode> mGeometryShaderOutputPrimitiveType;
Optional<GLint> mGeometryShaderMaxVertices;
int mGeometryShaderInvocations;
// Tessellation Shader
int mTessControlShaderVertices;
GLenum mTessGenMode;
GLenum mTessGenSpacing;
GLenum mTessGenVertexOrder;
GLenum mTessGenPointMode;
// Indicates if this shader has been successfully compiled
CompileStatus mCompileStatus;
};
class Shader final : angle::NonCopyable, public LabeledObject
{
public:
Shader(ShaderProgramManager *manager,
rx::GLImplFactory *implFactory,
const gl::Limitations &rendererLimitations,
ShaderType type,
ShaderProgramID handle);
void onDestroy(const Context *context);
void setLabel(const Context *context, const std::string &label) override;
const std::string &getLabel() const override;
ShaderType getType() const { return mType; }
ShaderProgramID getHandle() const;
rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
void setSource(GLsizei count, const char *const *string, const GLint *length);
int getInfoLogLength();
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
std::string getInfoLogString() const { return mInfoLog; }
int getSourceLength() const;
const std::string &getSourceString() const { return mState.getSource(); }
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
int getTranslatedSourceLength();
int getTranslatedSourceWithDebugInfoLength();
const std::string &getTranslatedSource();
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer);
void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer);
const sh::BinaryBlob &getCompiledBinary();
void compile(const Context *context);
bool isCompiled();
bool isCompleted();
void addRef();
void release(const Context *context);
unsigned int getRefCount() const;
bool isFlaggedForDeletion() const;
void flagForDeletion();
bool hasEarlyFragmentTestsOptimization() const
{
return mState.mEarlyFragmentTestsOptimization;
}
rx::SpecConstUsageBits getSpecConstUsageBits() const { return mState.mSpecConstUsageBits; }
int getShaderVersion();
const std::vector<sh::ShaderVariable> &getInputVaryings();
const std::vector<sh::ShaderVariable> &getOutputVaryings();
const std::vector<sh::ShaderVariable> &getUniforms();
const std::vector<sh::InterfaceBlock> &getUniformBlocks();
const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks();
const std::vector<sh::ShaderVariable> &getActiveAttributes();
const std::vector<sh::ShaderVariable> &getAllAttributes();
const std::vector<sh::ShaderVariable> &getActiveOutputVariables();
// Returns mapped name of a transform feedback varying. The original name may contain array
// brackets with an index inside, which will get copied to the mapped name. The varying must be
// known to be declared in the shader.
std::string getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName);
const sh::WorkGroupSize &getWorkGroupSize();
int getNumViews();
Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType();
Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType();
int getGeometryShaderInvocations();
Optional<GLint> getGeometryShaderMaxVertices();
int getTessControlShaderVertices();
GLenum getTessGenMode();
GLenum getTessGenSpacing();
GLenum getTessGenVertexOrder();
GLenum getTessGenPointMode();
const std::string &getCompilerResourcesString() const;
const ShaderState &getState() const { return mState; }
GLuint getCurrentMaxComputeWorkGroupInvocations() const
{
return mCurrentMaxComputeWorkGroupInvocations;
}
unsigned int getMaxComputeSharedMemory() const { return mMaxComputeSharedMemory; }
bool hasBeenDeleted() const { return mDeleteStatus; }
void resolveCompile();
private:
struct CompilingState;
~Shader() override;
static void GetSourceImpl(const std::string &source,
GLsizei bufSize,
GLsizei *length,
char *buffer);
ShaderState mState;
std::unique_ptr<rx::ShaderImpl> mImplementation;
const gl::Limitations mRendererLimitations;
const ShaderProgramID mHandle;
const ShaderType mType;
unsigned int mRefCount; // Number of program objects this shader is attached to
bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
std::string mInfoLog;
// We keep a reference to the translator in order to defer compiles while preserving settings.
BindingPointer<Compiler> mBoundCompiler;
std::unique_ptr<CompilingState> mCompilingState;
std::string mCompilerResourcesString;
ShaderProgramManager *mResourceManager;
GLuint mCurrentMaxComputeWorkGroupInvocations;
unsigned int mMaxComputeSharedMemory;
};
bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y);
const char *GetShaderTypeString(ShaderType type);
} // namespace gl
#endif // LIBANGLE_SHADER_H_