blob: cb64da28ebb7c6bd677a003d89e01ccad6a2c7a8 [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/BinaryStream.h"
#include "common/CompiledShaderState.h"
#include "common/MemoryBuffer.h"
#include "common/Optional.h"
#include "common/angleutils.h"
#include "libANGLE/BlobCache.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;
class BinaryInputStream;
class BinaryOutputStream;
// We defer the compile until link time, or until properties are queried.
enum class CompileStatus
{
// Compilation never done, or has failed.
NOT_COMPILED,
// Compile is in progress.
COMPILE_REQUESTED,
// Compilation job is done, but is being resolved. This enum value is there to allow access to
// compiled state during resolve without triggering threading-related assertions (which ensure
// no compile job is in progress).
IS_RESOLVING,
// Compilation was successful.
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 compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; }
CompileStatus getCompileStatus() const { return mCompileStatus; }
ShaderType getShaderType() const { return mCompiledState->shaderType; }
const SharedCompiledShaderState &getCompiledState() const
{
ASSERT(!compilePending());
return mCompiledState;
}
private:
friend class Shader;
std::string mLabel;
std::string mSource;
size_t mSourceHash = 0;
SharedCompiledShaderState mCompiledState;
// Indicates if this shader has been successfully compiled
CompileStatus mCompileStatus = CompileStatus::NOT_COMPILED;
};
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);
angle::Result setLabel(const Context *context, const std::string &label) override;
const std::string &getLabel() const override;
ShaderType getType() const { return mState.getShaderType(); }
ShaderProgramID getHandle() const;
rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
void setSource(const Context *context,
GLsizei count,
const char *const *string,
const GLint *length);
int getInfoLogLength(const Context *context);
void getInfoLog(const Context *context, 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(const Context *context);
int getTranslatedSourceWithDebugInfoLength(const Context *context);
const std::string &getTranslatedSource(const Context *context);
void getTranslatedSource(const Context *context,
GLsizei bufSize,
GLsizei *length,
char *buffer);
void getTranslatedSourceWithDebugInfo(const Context *context,
GLsizei bufSize,
GLsizei *length,
char *buffer);
size_t getSourceHash() const;
void compile(const Context *context);
bool isCompiled(const Context *context);
bool isCompleted();
// Return the compiled shader state for the program. The program holds a reference to this
// state, so the shader is free to recompile, get deleted, etc.
const SharedCompiledShaderState &getCompiledState() const { return mState.getCompiledState(); }
void addRef();
void release(const Context *context);
unsigned int getRefCount() const;
bool isFlaggedForDeletion() const;
void flagForDeletion();
const ShaderState &getState() const { return mState; }
GLuint getCurrentMaxComputeWorkGroupInvocations() const
{
return mCurrentMaxComputeWorkGroupInvocations;
}
unsigned int getMaxComputeSharedMemory() const { return mMaxComputeSharedMemory; }
bool hasBeenDeleted() const { return mDeleteStatus; }
// Block until compiling is finished and resolve it.
void resolveCompile(const Context *context);
// Writes a shader's binary to the output memory buffer.
angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
angle::Result deserialize(BinaryInputStream &stream);
// Load a binary from shader cache.
angle::Result loadBinary(const Context *context, const void *binary, GLsizei length);
// Load a binary from a glShaderBinary call.
angle::Result loadShaderBinary(const Context *context, const void *binary, GLsizei length);
void writeShaderKey(BinaryOutputStream *streamOut) const
{
ASSERT(streamOut && !mShaderHash.empty());
streamOut->writeBytes(mShaderHash.data(), egl::BlobCache::kKeyLength);
return;
}
private:
struct CompilingState;
~Shader() override;
static std::string joinShaderSources(GLsizei count,
const char *const *string,
const GLint *length);
static void GetSourceImpl(const std::string &source,
GLsizei bufSize,
GLsizei *length,
char *buffer);
angle::Result loadBinaryImpl(const Context *context,
const void *binary,
GLsizei length,
bool generatedWithOfflineCompiler);
// Compute a key to uniquely identify the shader object in memory caches.
void setShaderKey(const Context *context,
const ShCompileOptions &compileOptions,
const ShShaderOutput &outputType,
const ShBuiltInResources &resources);
ShaderState mState;
std::unique_ptr<rx::ShaderImpl> mImplementation;
const gl::Limitations mRendererLimitations;
const ShaderProgramID mHandle;
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;
egl::BlobCache::Key mShaderHash;
ShaderProgramManager *mResourceManager;
GLuint mCurrentMaxComputeWorkGroupInvocations;
unsigned int mMaxComputeSharedMemory;
};
const char *GetShaderTypeString(ShaderType type);
std::string GetShaderDumpFileDirectory();
std::string GetShaderDumpFileName(size_t shaderHash);
} // namespace gl
#endif // LIBANGLE_SHADER_H_