• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 CompileTask;
51 class Context;
52 class ShaderProgramManager;
53 class State;
54 class BinaryInputStream;
55 class BinaryOutputStream;
56 
57 // We defer the compile until link time, or until properties are queried.
58 enum class CompileStatus
59 {
60     NOT_COMPILED,
61     COMPILE_REQUESTED,
62     COMPILED,
63 };
64 
65 class ShaderState final : angle::NonCopyable
66 {
67   public:
68     ShaderState(ShaderType shaderType);
69     ~ShaderState();
70 
getLabel()71     const std::string &getLabel() const { return mLabel; }
72 
getSource()73     const std::string &getSource() const { return mSource; }
isCompiledToBinary()74     bool isCompiledToBinary() const { return !mCompiledShaderState.compiledBinary.empty(); }
getTranslatedSource()75     const std::string &getTranslatedSource() const { return mCompiledShaderState.translatedSource; }
getCompiledBinary()76     const sh::BinaryBlob &getCompiledBinary() const { return mCompiledShaderState.compiledBinary; }
77 
getShaderType()78     ShaderType getShaderType() const { return mCompiledShaderState.shaderType; }
getShaderVersion()79     int getShaderVersion() const { return mCompiledShaderState.shaderVersion; }
80 
getInputVaryings()81     const std::vector<sh::ShaderVariable> &getInputVaryings() const
82     {
83         return mCompiledShaderState.inputVaryings;
84     }
getOutputVaryings()85     const std::vector<sh::ShaderVariable> &getOutputVaryings() const
86     {
87         return mCompiledShaderState.outputVaryings;
88     }
getUniforms()89     const std::vector<sh::ShaderVariable> &getUniforms() const
90     {
91         return mCompiledShaderState.uniforms;
92     }
getUniformBlocks()93     const std::vector<sh::InterfaceBlock> &getUniformBlocks() const
94     {
95         return mCompiledShaderState.uniformBlocks;
96     }
getShaderStorageBlocks()97     const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
98     {
99         return mCompiledShaderState.shaderStorageBlocks;
100     }
getActiveAttributes()101     const std::vector<sh::ShaderVariable> &getActiveAttributes() const
102     {
103         return mCompiledShaderState.activeAttributes;
104     }
getAllAttributes()105     const std::vector<sh::ShaderVariable> &getAllAttributes() const
106     {
107         return mCompiledShaderState.allAttributes;
108     }
getActiveOutputVariables()109     const std::vector<sh::ShaderVariable> &getActiveOutputVariables() const
110     {
111         return mCompiledShaderState.activeOutputVariables;
112     }
113 
compilePending()114     bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; }
115 
getLocalSize()116     const sh::WorkGroupSize &getLocalSize() const { return mCompiledShaderState.localSize; }
117 
hasClipDistance()118     bool hasClipDistance() const { return mCompiledShaderState.hasClipDistance; }
hasDiscard()119     bool hasDiscard() const { return mCompiledShaderState.hasDiscard; }
enablesPerSampleShading()120     bool enablesPerSampleShading() const { return mCompiledShaderState.enablesPerSampleShading; }
getSpecConstUsageBits()121     rx::SpecConstUsageBits getSpecConstUsageBits() const
122     {
123         return mCompiledShaderState.specConstUsageBits;
124     }
125 
getNumViews()126     int getNumViews() const { return mCompiledShaderState.numViews; }
127 
getGeometryShaderInputPrimitiveType()128     Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType() const
129     {
130         return mCompiledShaderState.geometryShaderInputPrimitiveType;
131     }
132 
getGeometryShaderOutputPrimitiveType()133     Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType() const
134     {
135         return mCompiledShaderState.geometryShaderOutputPrimitiveType;
136     }
137 
getGeometryShaderMaxVertices()138     Optional<GLint> getGeometryShaderMaxVertices() const
139     {
140         return mCompiledShaderState.geometryShaderMaxVertices;
141     }
142 
getGeometryShaderInvocations()143     Optional<GLint> getGeometryShaderInvocations() const
144     {
145         return mCompiledShaderState.geometryShaderInvocations;
146     }
147 
getCompileStatus()148     CompileStatus getCompileStatus() const { return mCompileStatus; }
149 
150   private:
151     friend class Shader;
152 
153     std::string mLabel;
154     std::string mSource;
155     size_t mSourceHash = 0;
156 
157     gl::CompiledShaderState mCompiledShaderState;
158 
159     // Indicates if this shader has been successfully compiled
160     CompileStatus mCompileStatus = CompileStatus::NOT_COMPILED;
161 };
162 
163 class Shader final : angle::NonCopyable, public LabeledObject
164 {
165   public:
166     Shader(ShaderProgramManager *manager,
167            rx::GLImplFactory *implFactory,
168            const gl::Limitations &rendererLimitations,
169            ShaderType type,
170            ShaderProgramID handle);
171 
172     void onDestroy(const Context *context);
173 
174     angle::Result setLabel(const Context *context, const std::string &label) override;
175     const std::string &getLabel() const override;
176 
getType()177     ShaderType getType() const { return mType; }
178     ShaderProgramID getHandle() const;
179 
getImplementation()180     rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
181 
182     void setSource(const Context *context,
183                    GLsizei count,
184                    const char *const *string,
185                    const GLint *length);
186     int getInfoLogLength(const Context *context);
187     void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog);
getInfoLogString()188     std::string getInfoLogString() const { return mInfoLog; }
189     int getSourceLength() const;
getSourceString()190     const std::string &getSourceString() const { return mState.getSource(); }
191     void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
192     int getTranslatedSourceLength(const Context *context);
193     int getTranslatedSourceWithDebugInfoLength(const Context *context);
194     const std::string &getTranslatedSource(const Context *context);
195     void getTranslatedSource(const Context *context,
196                              GLsizei bufSize,
197                              GLsizei *length,
198                              char *buffer);
199     void getTranslatedSourceWithDebugInfo(const Context *context,
200                                           GLsizei bufSize,
201                                           GLsizei *length,
202                                           char *buffer);
203     const sh::BinaryBlob &getCompiledBinary(const Context *context);
204 
205     size_t getSourceHash() const;
206 
207     void compile(const Context *context);
208     bool isCompiled(const Context *context);
209     bool isCompleted();
210 
211     void addRef();
212     void release(const Context *context);
213     unsigned int getRefCount() const;
214     bool isFlaggedForDeletion() const;
215     void flagForDeletion();
hasClipDistance()216     bool hasClipDistance() const { return mState.mCompiledShaderState.hasClipDistance; }
hasDiscard()217     bool hasDiscard() const { return mState.mCompiledShaderState.hasDiscard; }
enablesPerSampleShading()218     bool enablesPerSampleShading() const
219     {
220         return mState.mCompiledShaderState.enablesPerSampleShading;
221     }
getAdvancedBlendEquations()222     BlendEquationBitSet getAdvancedBlendEquations() const
223     {
224         return mState.mCompiledShaderState.advancedBlendEquations;
225     }
getSpecConstUsageBits()226     rx::SpecConstUsageBits getSpecConstUsageBits() const
227     {
228         return mState.mCompiledShaderState.specConstUsageBits;
229     }
230 
231     int getShaderVersion(const Context *context);
232 
233     const std::vector<sh::ShaderVariable> &getInputVaryings(const Context *context);
234     const std::vector<sh::ShaderVariable> &getOutputVaryings(const Context *context);
235     const std::vector<sh::ShaderVariable> &getUniforms(const Context *context);
236     const std::vector<sh::InterfaceBlock> &getUniformBlocks(const Context *context);
237     const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks(const Context *context);
238     const std::vector<sh::ShaderVariable> &getActiveAttributes(const Context *context);
239     const std::vector<sh::ShaderVariable> &getAllAttributes(const Context *context);
240     const std::vector<sh::ShaderVariable> &getActiveOutputVariables(const Context *context);
241 
242     // Returns mapped name of a transform feedback varying. The original name may contain array
243     // brackets with an index inside, which will get copied to the mapped name. The varying must be
244     // known to be declared in the shader.
245     std::string getTransformFeedbackVaryingMappedName(const Context *context,
246                                                       const std::string &tfVaryingName);
247 
248     const sh::WorkGroupSize &getWorkGroupSize(const Context *context);
249 
250     int getNumViews(const Context *context);
251 
252     Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType(const Context *context);
253     Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType(const Context *context);
254     int getGeometryShaderInvocations(const Context *context);
255     Optional<GLint> getGeometryShaderMaxVertices(const Context *context);
256     int getTessControlShaderVertices(const Context *context);
257     GLenum getTessGenMode(const Context *context);
258     GLenum getTessGenSpacing(const Context *context);
259     GLenum getTessGenVertexOrder(const Context *context);
260     GLenum getTessGenPointMode(const Context *context);
261 
getState()262     const ShaderState &getState() const { return mState; }
263 
getCurrentMaxComputeWorkGroupInvocations()264     GLuint getCurrentMaxComputeWorkGroupInvocations() const
265     {
266         return mCurrentMaxComputeWorkGroupInvocations;
267     }
268 
getMaxComputeSharedMemory()269     unsigned int getMaxComputeSharedMemory() const { return mMaxComputeSharedMemory; }
hasBeenDeleted()270     bool hasBeenDeleted() const { return mDeleteStatus; }
271 
272     // Block until compiling is finished and resolve it.
273     void resolveCompile(const Context *context);
274 
275     // Writes a shader's binary to the output memory buffer.
276     angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
277     angle::Result deserialize(BinaryInputStream &stream);
278 
279     // Load a binary from shader cache.
280     angle::Result loadBinary(const Context *context, const void *binary, GLsizei length);
281     // Load a binary from a glShaderBinary call.
282     angle::Result loadShaderBinary(const Context *context, const void *binary, GLsizei length);
283 
writeShaderKey(BinaryOutputStream * streamOut)284     void writeShaderKey(BinaryOutputStream *streamOut) const
285     {
286         ASSERT(streamOut && !mShaderHash.empty());
287         streamOut->writeBytes(mShaderHash.data(), egl::BlobCache::kKeyLength);
288         return;
289     }
290 
291   private:
292     struct CompilingState;
293 
294     ~Shader() override;
295     static std::string joinShaderSources(GLsizei count,
296                                          const char *const *string,
297                                          const GLint *length);
298     static void GetSourceImpl(const std::string &source,
299                               GLsizei bufSize,
300                               GLsizei *length,
301                               char *buffer);
302     angle::Result loadBinaryImpl(const Context *context,
303                                  const void *binary,
304                                  GLsizei length,
305                                  bool generatedWithOfflineCompiler);
306 
307     // Compute a key to uniquely identify the shader object in memory caches.
308     void setShaderKey(const Context *context,
309                       const ShCompileOptions &compileOptions,
310                       const ShShaderOutput &outputType,
311                       const ShBuiltInResources &resources);
312 
313     ShaderState mState;
314     std::unique_ptr<rx::ShaderImpl> mImplementation;
315     const gl::Limitations mRendererLimitations;
316     const ShaderProgramID mHandle;
317     const ShaderType mType;
318     unsigned int mRefCount;  // Number of program objects this shader is attached to
319     bool mDeleteStatus;  // Flag to indicate that the shader can be deleted when no longer in use
320     std::string mInfoLog;
321 
322     // We keep a reference to the translator in order to defer compiles while preserving settings.
323     BindingPointer<Compiler> mBoundCompiler;
324     std::unique_ptr<CompilingState> mCompilingState;
325     egl::BlobCache::Key mShaderHash;
326 
327     ShaderProgramManager *mResourceManager;
328 
329     GLuint mCurrentMaxComputeWorkGroupInvocations;
330     unsigned int mMaxComputeSharedMemory;
331 };
332 
333 const char *GetShaderTypeString(ShaderType type);
334 std::string GetShaderDumpFileDirectory();
335 std::string GetShaderDumpFileName(size_t shaderHash);
336 
337 }  // namespace gl
338 
339 #endif  // LIBANGLE_SHADER_H_
340