1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker // Shader.h: Defines the abstract gl::Shader class and its concrete derived 8*8975f5c5SAndroid Build Coastguard Worker // classes VertexShader and FragmentShader. Implements GL shader objects and 9*8975f5c5SAndroid Build Coastguard Worker // related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 10*8975f5c5SAndroid Build Coastguard Worker // 3.8 page 84. 11*8975f5c5SAndroid Build Coastguard Worker 12*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_SHADER_H_ 13*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_SHADER_H_ 14*8975f5c5SAndroid Build Coastguard Worker 15*8975f5c5SAndroid Build Coastguard Worker #include <list> 16*8975f5c5SAndroid Build Coastguard Worker #include <memory> 17*8975f5c5SAndroid Build Coastguard Worker #include <string> 18*8975f5c5SAndroid Build Coastguard Worker #include <vector> 19*8975f5c5SAndroid Build Coastguard Worker 20*8975f5c5SAndroid Build Coastguard Worker #include <GLSLANG/ShaderLang.h> 21*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h" 22*8975f5c5SAndroid Build Coastguard Worker 23*8975f5c5SAndroid Build Coastguard Worker #include "common/BinaryStream.h" 24*8975f5c5SAndroid Build Coastguard Worker #include "common/CompiledShaderState.h" 25*8975f5c5SAndroid Build Coastguard Worker #include "common/MemoryBuffer.h" 26*8975f5c5SAndroid Build Coastguard Worker #include "common/Optional.h" 27*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h" 28*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/BlobCache.h" 29*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Caps.h" 30*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Compiler.h" 31*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Debug.h" 32*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h" 33*8975f5c5SAndroid Build Coastguard Worker 34*8975f5c5SAndroid Build Coastguard Worker namespace rx 35*8975f5c5SAndroid Build Coastguard Worker { 36*8975f5c5SAndroid Build Coastguard Worker class GLImplFactory; 37*8975f5c5SAndroid Build Coastguard Worker class ShaderImpl; 38*8975f5c5SAndroid Build Coastguard Worker class ShaderSh; 39*8975f5c5SAndroid Build Coastguard Worker class WaitableCompileEvent; 40*8975f5c5SAndroid Build Coastguard Worker } // namespace rx 41*8975f5c5SAndroid Build Coastguard Worker 42*8975f5c5SAndroid Build Coastguard Worker namespace angle 43*8975f5c5SAndroid Build Coastguard Worker { 44*8975f5c5SAndroid Build Coastguard Worker class WaitableEvent; 45*8975f5c5SAndroid Build Coastguard Worker class WorkerThreadPool; 46*8975f5c5SAndroid Build Coastguard Worker } // namespace angle 47*8975f5c5SAndroid Build Coastguard Worker 48*8975f5c5SAndroid Build Coastguard Worker namespace gl 49*8975f5c5SAndroid Build Coastguard Worker { 50*8975f5c5SAndroid Build Coastguard Worker class Context; 51*8975f5c5SAndroid Build Coastguard Worker class ShaderProgramManager; 52*8975f5c5SAndroid Build Coastguard Worker class State; 53*8975f5c5SAndroid Build Coastguard Worker class BinaryInputStream; 54*8975f5c5SAndroid Build Coastguard Worker class BinaryOutputStream; 55*8975f5c5SAndroid Build Coastguard Worker 56*8975f5c5SAndroid Build Coastguard Worker // We defer the compile until link time, or until properties are queried. 57*8975f5c5SAndroid Build Coastguard Worker enum class CompileStatus 58*8975f5c5SAndroid Build Coastguard Worker { 59*8975f5c5SAndroid Build Coastguard Worker // Compilation never done, or has failed. 60*8975f5c5SAndroid Build Coastguard Worker NOT_COMPILED, 61*8975f5c5SAndroid Build Coastguard Worker // Compile is in progress. 62*8975f5c5SAndroid Build Coastguard Worker COMPILE_REQUESTED, 63*8975f5c5SAndroid Build Coastguard Worker // Compilation job is done, but is being resolved. This enum value is there to allow access to 64*8975f5c5SAndroid Build Coastguard Worker // compiled state during resolve without triggering threading-related assertions (which ensure 65*8975f5c5SAndroid Build Coastguard Worker // no compile job is in progress). 66*8975f5c5SAndroid Build Coastguard Worker IS_RESOLVING, 67*8975f5c5SAndroid Build Coastguard Worker // Compilation was successful. 68*8975f5c5SAndroid Build Coastguard Worker COMPILED, 69*8975f5c5SAndroid Build Coastguard Worker }; 70*8975f5c5SAndroid Build Coastguard Worker 71*8975f5c5SAndroid Build Coastguard Worker // A representation of the compile job. The program's link job can wait on this while the shader is 72*8975f5c5SAndroid Build Coastguard Worker // free to recompile (and generate other compile jobs). 73*8975f5c5SAndroid Build Coastguard Worker struct CompileJob; 74*8975f5c5SAndroid Build Coastguard Worker using SharedCompileJob = std::shared_ptr<CompileJob>; 75*8975f5c5SAndroid Build Coastguard Worker 76*8975f5c5SAndroid Build Coastguard Worker class ShaderState final : angle::NonCopyable 77*8975f5c5SAndroid Build Coastguard Worker { 78*8975f5c5SAndroid Build Coastguard Worker public: 79*8975f5c5SAndroid Build Coastguard Worker ShaderState(ShaderType shaderType); 80*8975f5c5SAndroid Build Coastguard Worker ~ShaderState(); 81*8975f5c5SAndroid Build Coastguard Worker getLabel()82*8975f5c5SAndroid Build Coastguard Worker const std::string &getLabel() const { return mLabel; } 83*8975f5c5SAndroid Build Coastguard Worker getSource()84*8975f5c5SAndroid Build Coastguard Worker const std::string &getSource() const { return mSource; } compilePending()85*8975f5c5SAndroid Build Coastguard Worker bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; } getCompileStatus()86*8975f5c5SAndroid Build Coastguard Worker CompileStatus getCompileStatus() const { return mCompileStatus; } 87*8975f5c5SAndroid Build Coastguard Worker getShaderType()88*8975f5c5SAndroid Build Coastguard Worker ShaderType getShaderType() const { return mCompiledState->shaderType; } 89*8975f5c5SAndroid Build Coastguard Worker getCompiledState()90*8975f5c5SAndroid Build Coastguard Worker const SharedCompiledShaderState &getCompiledState() const 91*8975f5c5SAndroid Build Coastguard Worker { 92*8975f5c5SAndroid Build Coastguard Worker ASSERT(!compilePending()); 93*8975f5c5SAndroid Build Coastguard Worker return mCompiledState; 94*8975f5c5SAndroid Build Coastguard Worker } 95*8975f5c5SAndroid Build Coastguard Worker 96*8975f5c5SAndroid Build Coastguard Worker private: 97*8975f5c5SAndroid Build Coastguard Worker friend class Shader; 98*8975f5c5SAndroid Build Coastguard Worker 99*8975f5c5SAndroid Build Coastguard Worker std::string mLabel; 100*8975f5c5SAndroid Build Coastguard Worker std::string mSource; 101*8975f5c5SAndroid Build Coastguard Worker size_t mSourceHash = 0; 102*8975f5c5SAndroid Build Coastguard Worker 103*8975f5c5SAndroid Build Coastguard Worker SharedCompiledShaderState mCompiledState; 104*8975f5c5SAndroid Build Coastguard Worker 105*8975f5c5SAndroid Build Coastguard Worker // Indicates if this shader has been successfully compiled 106*8975f5c5SAndroid Build Coastguard Worker CompileStatus mCompileStatus = CompileStatus::NOT_COMPILED; 107*8975f5c5SAndroid Build Coastguard Worker }; 108*8975f5c5SAndroid Build Coastguard Worker 109*8975f5c5SAndroid Build Coastguard Worker class Shader final : angle::NonCopyable, public LabeledObject 110*8975f5c5SAndroid Build Coastguard Worker { 111*8975f5c5SAndroid Build Coastguard Worker public: 112*8975f5c5SAndroid Build Coastguard Worker Shader(ShaderProgramManager *manager, 113*8975f5c5SAndroid Build Coastguard Worker rx::GLImplFactory *implFactory, 114*8975f5c5SAndroid Build Coastguard Worker const gl::Limitations &rendererLimitations, 115*8975f5c5SAndroid Build Coastguard Worker ShaderType type, 116*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID handle); 117*8975f5c5SAndroid Build Coastguard Worker 118*8975f5c5SAndroid Build Coastguard Worker void onDestroy(const Context *context); 119*8975f5c5SAndroid Build Coastguard Worker 120*8975f5c5SAndroid Build Coastguard Worker angle::Result setLabel(const Context *context, const std::string &label) override; 121*8975f5c5SAndroid Build Coastguard Worker const std::string &getLabel() const override; 122*8975f5c5SAndroid Build Coastguard Worker getType()123*8975f5c5SAndroid Build Coastguard Worker ShaderType getType() const { return mState.getShaderType(); } 124*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID getHandle() const; 125*8975f5c5SAndroid Build Coastguard Worker getImplementation()126*8975f5c5SAndroid Build Coastguard Worker rx::ShaderImpl *getImplementation() const { return mImplementation.get(); } 127*8975f5c5SAndroid Build Coastguard Worker 128*8975f5c5SAndroid Build Coastguard Worker void setSource(const Context *context, 129*8975f5c5SAndroid Build Coastguard Worker GLsizei count, 130*8975f5c5SAndroid Build Coastguard Worker const char *const *string, 131*8975f5c5SAndroid Build Coastguard Worker const GLint *length); 132*8975f5c5SAndroid Build Coastguard Worker int getInfoLogLength(const Context *context); 133*8975f5c5SAndroid Build Coastguard Worker void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog); getInfoLogString()134*8975f5c5SAndroid Build Coastguard Worker std::string getInfoLogString() const { return mInfoLog; } 135*8975f5c5SAndroid Build Coastguard Worker int getSourceLength() const; getSourceString()136*8975f5c5SAndroid Build Coastguard Worker const std::string &getSourceString() const { return mState.getSource(); } 137*8975f5c5SAndroid Build Coastguard Worker void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; 138*8975f5c5SAndroid Build Coastguard Worker int getTranslatedSourceLength(const Context *context); 139*8975f5c5SAndroid Build Coastguard Worker int getTranslatedSourceWithDebugInfoLength(const Context *context); 140*8975f5c5SAndroid Build Coastguard Worker const std::string &getTranslatedSource(const Context *context); 141*8975f5c5SAndroid Build Coastguard Worker void getTranslatedSource(const Context *context, 142*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize, 143*8975f5c5SAndroid Build Coastguard Worker GLsizei *length, 144*8975f5c5SAndroid Build Coastguard Worker char *buffer); 145*8975f5c5SAndroid Build Coastguard Worker void getTranslatedSourceWithDebugInfo(const Context *context, 146*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize, 147*8975f5c5SAndroid Build Coastguard Worker GLsizei *length, 148*8975f5c5SAndroid Build Coastguard Worker char *buffer); 149*8975f5c5SAndroid Build Coastguard Worker 150*8975f5c5SAndroid Build Coastguard Worker size_t getSourceHash() const; 151*8975f5c5SAndroid Build Coastguard Worker 152*8975f5c5SAndroid Build Coastguard Worker void compile(const Context *context, angle::JobResultExpectancy resultExpectancy); 153*8975f5c5SAndroid Build Coastguard Worker bool isCompiled(const Context *context); 154*8975f5c5SAndroid Build Coastguard Worker bool isCompleted(); 155*8975f5c5SAndroid Build Coastguard Worker 156*8975f5c5SAndroid Build Coastguard Worker // Return the compilation job, which will be used by the program link job to wait for the 157*8975f5c5SAndroid Build Coastguard Worker // completion of compilation. If compilation has already finished, a placeholder job is 158*8975f5c5SAndroid Build Coastguard Worker // returned which can be used to retrieve the status of compilation. 159*8975f5c5SAndroid Build Coastguard Worker SharedCompileJob getCompileJob(SharedCompiledShaderState *compiledStateOut); 160*8975f5c5SAndroid Build Coastguard Worker 161*8975f5c5SAndroid Build Coastguard Worker // Return the compiled shader state for the program. The program holds a reference to this 162*8975f5c5SAndroid Build Coastguard Worker // state, so the shader is free to recompile, get deleted, etc. getCompiledState()163*8975f5c5SAndroid Build Coastguard Worker const SharedCompiledShaderState &getCompiledState() const { return mState.getCompiledState(); } 164*8975f5c5SAndroid Build Coastguard Worker 165*8975f5c5SAndroid Build Coastguard Worker void addRef(); 166*8975f5c5SAndroid Build Coastguard Worker void release(const Context *context); 167*8975f5c5SAndroid Build Coastguard Worker unsigned int getRefCount() const; 168*8975f5c5SAndroid Build Coastguard Worker bool isFlaggedForDeletion() const; 169*8975f5c5SAndroid Build Coastguard Worker void flagForDeletion(); 170*8975f5c5SAndroid Build Coastguard Worker getState()171*8975f5c5SAndroid Build Coastguard Worker const ShaderState &getState() const { return mState; } 172*8975f5c5SAndroid Build Coastguard Worker hasBeenDeleted()173*8975f5c5SAndroid Build Coastguard Worker bool hasBeenDeleted() const { return mDeleteStatus; } 174*8975f5c5SAndroid Build Coastguard Worker 175*8975f5c5SAndroid Build Coastguard Worker // Block until compilation is finished and resolve it. 176*8975f5c5SAndroid Build Coastguard Worker void resolveCompile(const Context *context); 177*8975f5c5SAndroid Build Coastguard Worker 178*8975f5c5SAndroid Build Coastguard Worker // Writes a shader's binary to the output memory buffer. 179*8975f5c5SAndroid Build Coastguard Worker angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const; 180*8975f5c5SAndroid Build Coastguard Worker bool deserialize(BinaryInputStream &stream); 181*8975f5c5SAndroid Build Coastguard Worker 182*8975f5c5SAndroid Build Coastguard Worker // Load a binary from shader cache. 183*8975f5c5SAndroid Build Coastguard Worker bool loadBinary(const Context *context, 184*8975f5c5SAndroid Build Coastguard Worker const void *binary, 185*8975f5c5SAndroid Build Coastguard Worker GLsizei length, 186*8975f5c5SAndroid Build Coastguard Worker angle::JobResultExpectancy resultExpectancy); 187*8975f5c5SAndroid Build Coastguard Worker // Load a binary from a glShaderBinary call. 188*8975f5c5SAndroid Build Coastguard Worker bool loadShaderBinary(const Context *context, 189*8975f5c5SAndroid Build Coastguard Worker const void *binary, 190*8975f5c5SAndroid Build Coastguard Worker GLsizei length, 191*8975f5c5SAndroid Build Coastguard Worker angle::JobResultExpectancy resultExpectancy); 192*8975f5c5SAndroid Build Coastguard Worker writeShaderKey(BinaryOutputStream * streamOut)193*8975f5c5SAndroid Build Coastguard Worker void writeShaderKey(BinaryOutputStream *streamOut) const 194*8975f5c5SAndroid Build Coastguard Worker { 195*8975f5c5SAndroid Build Coastguard Worker ASSERT(streamOut && !mShaderHash.empty()); 196*8975f5c5SAndroid Build Coastguard Worker streamOut->writeBytes(mShaderHash.data(), egl::BlobCache::kKeyLength); 197*8975f5c5SAndroid Build Coastguard Worker return; 198*8975f5c5SAndroid Build Coastguard Worker } 199*8975f5c5SAndroid Build Coastguard Worker 200*8975f5c5SAndroid Build Coastguard Worker private: 201*8975f5c5SAndroid Build Coastguard Worker ~Shader() override; 202*8975f5c5SAndroid Build Coastguard Worker static std::string joinShaderSources(GLsizei count, 203*8975f5c5SAndroid Build Coastguard Worker const char *const *string, 204*8975f5c5SAndroid Build Coastguard Worker const GLint *length); 205*8975f5c5SAndroid Build Coastguard Worker static void GetSourceImpl(const std::string &source, 206*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize, 207*8975f5c5SAndroid Build Coastguard Worker GLsizei *length, 208*8975f5c5SAndroid Build Coastguard Worker char *buffer); 209*8975f5c5SAndroid Build Coastguard Worker bool loadBinaryImpl(const Context *context, 210*8975f5c5SAndroid Build Coastguard Worker const void *binary, 211*8975f5c5SAndroid Build Coastguard Worker GLsizei length, 212*8975f5c5SAndroid Build Coastguard Worker angle::JobResultExpectancy resultExpectancy, 213*8975f5c5SAndroid Build Coastguard Worker bool generatedWithOfflineCompiler); 214*8975f5c5SAndroid Build Coastguard Worker 215*8975f5c5SAndroid Build Coastguard Worker // Compute a key to uniquely identify the shader object in memory caches. 216*8975f5c5SAndroid Build Coastguard Worker void setShaderKey(const Context *context, 217*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &compileOptions, 218*8975f5c5SAndroid Build Coastguard Worker const ShShaderOutput &outputType, 219*8975f5c5SAndroid Build Coastguard Worker const ShBuiltInResources &resources); 220*8975f5c5SAndroid Build Coastguard Worker 221*8975f5c5SAndroid Build Coastguard Worker ShaderState mState; 222*8975f5c5SAndroid Build Coastguard Worker std::unique_ptr<rx::ShaderImpl> mImplementation; 223*8975f5c5SAndroid Build Coastguard Worker const gl::Limitations mRendererLimitations; 224*8975f5c5SAndroid Build Coastguard Worker const ShaderProgramID mHandle; 225*8975f5c5SAndroid Build Coastguard Worker unsigned int mRefCount; // Number of program objects this shader is attached to 226*8975f5c5SAndroid Build Coastguard Worker bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use 227*8975f5c5SAndroid Build Coastguard Worker std::string mInfoLog; 228*8975f5c5SAndroid Build Coastguard Worker 229*8975f5c5SAndroid Build Coastguard Worker // We keep a reference to the translator in order to defer compiles while preserving settings. 230*8975f5c5SAndroid Build Coastguard Worker BindingPointer<Compiler> mBoundCompiler; 231*8975f5c5SAndroid Build Coastguard Worker SharedCompileJob mCompileJob; 232*8975f5c5SAndroid Build Coastguard Worker egl::BlobCache::Key mShaderHash; 233*8975f5c5SAndroid Build Coastguard Worker 234*8975f5c5SAndroid Build Coastguard Worker ShaderProgramManager *mResourceManager; 235*8975f5c5SAndroid Build Coastguard Worker }; 236*8975f5c5SAndroid Build Coastguard Worker 237*8975f5c5SAndroid Build Coastguard Worker const char *GetShaderTypeString(ShaderType type); 238*8975f5c5SAndroid Build Coastguard Worker std::string GetShaderDumpFileDirectory(); 239*8975f5c5SAndroid Build Coastguard Worker std::string GetShaderDumpFileName(size_t shaderHash); 240*8975f5c5SAndroid Build Coastguard Worker 241*8975f5c5SAndroid Build Coastguard Worker // Block until the compilation job is finished. This can be used by the program link job to wait 242*8975f5c5SAndroid Build Coastguard Worker // for shader compilation. As such, it may be called by multiple threads without holding a lock and 243*8975f5c5SAndroid Build Coastguard Worker // must therefore be thread-safe. It returns true if shader compilation has succeeded. 244*8975f5c5SAndroid Build Coastguard Worker bool WaitCompileJobUnlocked(const SharedCompileJob &compileJob); 245*8975f5c5SAndroid Build Coastguard Worker } // namespace gl 246*8975f5c5SAndroid Build Coastguard Worker 247*8975f5c5SAndroid Build Coastguard Worker #endif // LIBANGLE_SHADER_H_ 248