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