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