xref: /aosp_15_r20/external/angle/src/libANGLE/Shader.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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