From 0a7aebadfbb3534284546aa3ca8612314c08f136 Mon Sep 17 00:00:00 2001 From: Miguel Costa Date: Tue, 26 Jun 2018 16:56:45 +0200 Subject: Update ANGLE to chromium/3280 Change-Id: I0802c0d7486f772d361f87a544d6c5af937f4ca1 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/src/libANGLE/Program.h | 641 ++++++++++++++++++++++-------- 1 file changed, 467 insertions(+), 174 deletions(-) (limited to 'src/3rdparty/angle/src/libANGLE/Program.h') diff --git a/src/3rdparty/angle/src/libANGLE/Program.h b/src/3rdparty/angle/src/libANGLE/Program.h index f885ad1694..c242d84671 100644 --- a/src/3rdparty/angle/src/libANGLE/Program.h +++ b/src/3rdparty/angle/src/libANGLE/Program.h @@ -11,8 +11,10 @@ #define LIBANGLE_PROGRAM_H_ #include -#include +#include +#include +#include #include #include #include @@ -22,15 +24,16 @@ #include "common/mathutil.h" #include "common/Optional.h" -#include "libANGLE/angletypes.h" #include "libANGLE/Constants.h" #include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/angletypes.h" namespace rx { -class ImplFactory; +class GLImplFactory; class ProgramImpl; struct TranslatedAttribute; } @@ -38,31 +41,17 @@ struct TranslatedAttribute; namespace gl { struct Caps; -struct Data; -class ResourceManager; +class Context; +class ContextState; class Shader; +class ShaderProgramManager; +class State; class InfoLog; -class AttributeBindings; class Buffer; class Framebuffer; -struct UniformBlock; -struct LinkedUniform; extern const char * const g_fakepath; -class AttributeBindings -{ - public: - AttributeBindings(); - ~AttributeBindings(); - - void bindAttributeLocation(GLuint index, const char *name); - int getAttributeBinding(const std::string &name) const; - - private: - std::set mAttributeBinding[MAX_VERTEX_ATTRIBS]; -}; - class InfoLog : angle::NonCopyable { public: @@ -122,134 +111,330 @@ class InfoLog : angle::NonCopyable template StreamHelper operator<<(const T &value) { - StreamHelper helper(&mStream); + ensureInitialized(); + StreamHelper helper(mLazyStream.get()); helper << value; return helper; } - std::string str() const { return mStream.str(); } + std::string str() const { return mLazyStream ? mLazyStream->str() : ""; } private: - std::stringstream mStream; + void ensureInitialized() + { + if (!mLazyStream) + { + mLazyStream.reset(new std::stringstream()); + } + } + + std::unique_ptr mLazyStream; }; // Struct used for correlating uniforms/elements of uniform arrays to handles struct VariableLocation { + static constexpr unsigned int kUnused = GL_INVALID_INDEX; + VariableLocation(); - VariableLocation(const std::string &name, unsigned int element, unsigned int index); + VariableLocation(unsigned int arrayIndex, unsigned int index); + + // If used is false, it means this location is only used to fill an empty space in an array, + // and there is no corresponding uniform variable for this location. It can also mean the + // uniform was optimized out by the implementation. + bool used() const { return (index != kUnused); } + void markUnused() { index = kUnused; } + void markIgnored() { ignored = true; } + + // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays. + unsigned int arrayIndex; + // "index" is an index of the variable. The variable contains the indices for other than the + // innermost GLSL arrays. + unsigned int index; + + // If this location was bound to an unreferenced uniform. Setting data on this uniform is a + // no-op. + bool ignored; +}; +// Information about a variable binding. +// Currently used by CHROMIUM_path_rendering +struct BindingInfo +{ + // The type of binding, for example GL_FLOAT_VEC3. + // This can be GL_NONE if the variable is optimized away. + GLenum type; + + // This is the name of the variable in + // the translated shader program. Note that + // this can be empty in the case where the + // variable has been optimized away. std::string name; - unsigned int element; - unsigned int index; + + // True if the binding is valid, otherwise false. + bool valid; }; -class Program final : angle::NonCopyable, public LabeledObject +// This small structure encapsulates binding sampler uniforms to active GL textures. +struct SamplerBinding { - public: - class Data final : angle::NonCopyable - { - public: - Data(); - ~Data(); + SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced); + SamplerBinding(const SamplerBinding &other); + ~SamplerBinding(); - const std::string &getLabel(); + // Necessary for retrieving active textures from the GL state. + GLenum textureType; - const Shader *getAttachedVertexShader() const { return mAttachedVertexShader; } - const Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; } - const std::vector &getTransformFeedbackVaryingNames() const - { - return mTransformFeedbackVaryingNames; - } - GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } - GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const - { - ASSERT(uniformBlockIndex < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); - return mUniformBlockBindings[uniformBlockIndex]; - } - const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const - { - return mActiveUniformBlockBindings; - } - const std::vector &getAttributes() const { return mAttributes; } - const AttributesMask &getActiveAttribLocationsMask() const - { - return mActiveAttribLocationsMask; - } - const std::map &getOutputVariables() const - { - return mOutputVariables; - } - const std::vector &getUniforms() const { return mUniforms; } - const std::vector &getUniformLocations() const + // List of all textures bound to this sampler, of type textureType. + std::vector boundTextureUnits; + + // A note if this sampler is an unreferenced uniform. + bool unreferenced; +}; + +// A varying with tranform feedback enabled. If it's an array, either the whole array or one of its +// elements specified by 'arrayIndex' can set to be enabled. +struct TransformFeedbackVarying : public sh::Varying +{ + TransformFeedbackVarying(const sh::Varying &varyingIn, GLuint index) + : sh::Varying(varyingIn), arrayIndex(index) + { + ASSERT(!isArrayOfArrays()); + } + std::string nameWithArrayIndex() const + { + std::stringstream fullNameStr; + fullNameStr << name; + if (arrayIndex != GL_INVALID_INDEX) { - return mUniformLocations; + fullNameStr << "[" << arrayIndex << "]"; } - const std::vector &getUniformBlocks() const { return mUniformBlocks; } + return fullNameStr.str(); + } + GLsizei size() const + { + return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1); + } - const LinkedUniform *getUniformByName(const std::string &name) const; - GLint getUniformLocation(const std::string &name) const; - GLuint getUniformIndex(const std::string &name) const; + GLuint arrayIndex; +}; - private: - friend class Program; +struct ImageBinding +{ + ImageBinding(size_t count); + ImageBinding(GLuint imageUnit, size_t count); + ImageBinding(const ImageBinding &other); + ~ImageBinding(); + + std::vector boundImageUnits; +}; + +using ShaderStagesMask = angle::BitSet; + +class ProgramState final : angle::NonCopyable +{ + public: + ProgramState(); + ~ProgramState(); + + const std::string &getLabel(); + + Shader *getAttachedVertexShader() const { return mAttachedVertexShader; } + Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; } + Shader *getAttachedComputeShader() const { return mAttachedComputeShader; } + Shader *getAttachedGeometryShader() const { return mAttachedGeometryShader; } + const std::vector &getTransformFeedbackVaryingNames() const + { + return mTransformFeedbackVaryingNames; + } + GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } + GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const + { + ASSERT(uniformBlockIndex < mUniformBlocks.size()); + return mUniformBlocks[uniformBlockIndex].binding; + } + GLuint getShaderStorageBlockBinding(GLuint blockIndex) const + { + ASSERT(blockIndex < mShaderStorageBlocks.size()); + return mShaderStorageBlocks[blockIndex].binding; + } + const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const + { + return mActiveUniformBlockBindings; + } + const std::vector &getAttributes() const { return mAttributes; } + const AttributesMask &getActiveAttribLocationsMask() const + { + return mActiveAttribLocationsMask; + } + unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; } + DrawBufferMask getActiveOutputVariables() const { return mActiveOutputVariables; } + const std::vector &getOutputVariables() const { return mOutputVariables; } + const std::vector &getOutputLocations() const { return mOutputLocations; } + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getUniformLocations() const { return mUniformLocations; } + const std::vector &getUniformBlocks() const { return mUniformBlocks; } + const std::vector &getShaderStorageBlocks() const + { + return mShaderStorageBlocks; + } + const std::vector &getBufferVariables() const { return mBufferVariables; } + const std::vector &getSamplerBindings() const { return mSamplerBindings; } + const std::vector &getImageBindings() const { return mImageBindings; } + const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } + const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; } + const RangeUI &getImageUniformRange() const { return mImageUniformRange; } + const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; } + + const std::vector &getLinkedTransformFeedbackVaryings() const + { + return mLinkedTransformFeedbackVaryings; + } + const std::vector &getAtomicCounterBuffers() const + { + return mAtomicCounterBuffers; + } - std::string mLabel; + GLuint getUniformIndexFromName(const std::string &name) const; + GLuint getUniformIndexFromLocation(GLint location) const; + Optional getSamplerIndex(GLint location) const; + bool isSamplerUniformIndex(GLuint index) const; + GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; + GLuint getAttributeLocation(const std::string &name) const; - Shader *mAttachedFragmentShader; - Shader *mAttachedVertexShader; + GLuint getBufferVariableIndexFromName(const std::string &name) const; - std::vector mTransformFeedbackVaryingNames; - std::vector mTransformFeedbackVaryingVars; - GLenum mTransformFeedbackBufferMode; + int getNumViews() const { return mNumViews; } + bool usesMultiview() const { return mNumViews != -1; } - GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; - UniformBlockBindingMask mActiveUniformBlockBindings; + const ShaderStagesMask &getLinkedShaderStages() const { return mLinkedShaderStages; } - std::vector mAttributes; - std::bitset mActiveAttribLocationsMask; + private: + friend class MemoryProgramCache; + friend class Program; + + std::string mLabel; + + sh::WorkGroupSize mComputeShaderLocalSize; + + Shader *mAttachedFragmentShader; + Shader *mAttachedVertexShader; + Shader *mAttachedComputeShader; + Shader *mAttachedGeometryShader; + + std::vector mTransformFeedbackVaryingNames; + std::vector mLinkedTransformFeedbackVaryings; + GLenum mTransformFeedbackBufferMode; + + // For faster iteration on the blocks currently being bound. + UniformBlockBindingMask mActiveUniformBlockBindings; + + std::vector mAttributes; + angle::BitSet mActiveAttribLocationsMask; + unsigned int mMaxActiveAttribLocation; + + // Uniforms are sorted in order: + // 1. Non-opaque uniforms + // 2. Sampler uniforms + // 3. Image uniforms + // 4. Atomic counter uniforms + // 5. Uniform block uniforms + // This makes opaque uniform validation easier, since we don't need a separate list. + // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section + // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each + // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include + // [0] in the end. This makes implementation of queries simpler. + std::vector mUniforms; + + std::vector mUniformLocations; + std::vector mUniformBlocks; + std::vector mBufferVariables; + std::vector mShaderStorageBlocks; + std::vector mAtomicCounterBuffers; + RangeUI mSamplerUniformRange; + RangeUI mImageUniformRange; + RangeUI mAtomicCounterUniformRange; - // Uniforms are sorted in order: - // 1. Non-sampler uniforms - // 2. Sampler uniforms - // 3. Uniform block uniforms - // This makes sampler validation easier, since we don't need a separate list. - std::vector mUniforms; - std::vector mUniformLocations; - std::vector mUniformBlocks; + // An array of the samplers that are used by the program + std::vector mSamplerBindings; - // TODO(jmadill): use unordered/hash map when available - std::map mOutputVariables; + // An array of the images that are used by the program + std::vector mImageBindings; - bool mBinaryRetrieveableHint; - }; + // Names and mapped names of output variables that are arrays include [0] in the end, similarly + // to uniforms. + std::vector mOutputVariables; + std::vector mOutputLocations; + DrawBufferMask mActiveOutputVariables; - Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle); - ~Program(); + // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location. + std::vector mOutputVariableTypes; + + bool mBinaryRetrieveableHint; + bool mSeparable; + ShaderStagesMask mLinkedShaderStages; + + // ANGLE_multiview. + int mNumViews; +}; + +class Program final : angle::NonCopyable, public LabeledObject +{ + public: + Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle); + void onDestroy(const Context *context); GLuint id() const { return mHandle; } void setLabel(const std::string &label) override; const std::string &getLabel() const override; - rx::ProgramImpl *getImplementation() { return mProgram; } - const rx::ProgramImpl *getImplementation() const { return mProgram; } + rx::ProgramImpl *getImplementation() const { return mProgram; } - bool attachShader(Shader *shader); - bool detachShader(Shader *shader); + void attachShader(Shader *shader); + void detachShader(const Context *context, Shader *shader); int getAttachedShadersCount() const; - void bindAttributeLocation(GLuint index, const char *name); + const Shader *getAttachedVertexShader() const { return mState.mAttachedVertexShader; } + const Shader *getAttachedFragmentShader() const { return mState.mAttachedFragmentShader; } + const Shader *getAttachedComputeShader() const { return mState.mAttachedComputeShader; } + const Shader *getAttachedGeometryShader() const { return mState.mAttachedGeometryShader; } - Error link(const gl::Data &data); + void bindAttributeLocation(GLuint index, const char *name); + void bindUniformLocation(GLuint index, const char *name); + + // CHROMIUM_path_rendering + BindingInfo getFragmentInputBindingInfo(const Context *context, GLint index) const; + void bindFragmentInputLocation(GLint index, const char *name); + void pathFragmentInputGen(const Context *context, + GLint index, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + + Error link(const gl::Context *context); bool isLinked() const; - Error loadBinary(GLenum binaryFormat, const void *binary, GLsizei length); - Error saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const; - GLint getBinaryLength() const; + bool hasLinkedVertexShader() const { return mState.mLinkedShaderStages[SHADER_VERTEX]; } + bool hasLinkedFragmentShader() const { return mState.mLinkedShaderStages[SHADER_FRAGMENT]; } + bool hasLinkedComputeShader() const { return mState.mLinkedShaderStages[SHADER_COMPUTE]; } + + Error loadBinary(const Context *context, + GLenum binaryFormat, + const void *binary, + GLsizei length); + Error saveBinary(const Context *context, + GLenum *binaryFormat, + void *binary, + GLsizei bufSize, + GLsizei *length) const; + GLint getBinaryLength(const Context *context) const; void setBinaryRetrievableHint(bool retrievable); bool getBinaryRetrievableHint() const; + void setSeparable(bool separable); + bool isSeparable() const; + int getInfoLogLength() const; void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) const; @@ -257,12 +442,23 @@ class Program final : angle::NonCopyable, public LabeledObject GLuint getAttributeLocation(const std::string &name) const; bool isAttribLocationActive(size_t attribLocation) const; - void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + void getActiveAttribute(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const; GLint getActiveAttributeCount() const; GLint getActiveAttributeMaxLength() const; - const std::vector &getAttributes() const { return mData.mAttributes; } + const std::vector &getAttributes() const { return mState.mAttributes; } GLint getFragDataLocation(const std::string &name) const; + size_t getOutputResourceCount() const; + const std::vector &getOutputVariableTypes() const + { + return mState.mOutputVariableTypes; + } + DrawBufferMask getActiveOutputVariables() const { return mState.mActiveOutputVariables; } void getActiveUniform(GLuint index, GLsizei bufsize, @@ -271,10 +467,21 @@ class Program final : angle::NonCopyable, public LabeledObject GLenum *type, GLchar *name) const; GLint getActiveUniformCount() const; + size_t getActiveBufferVariableCount() const; GLint getActiveUniformMaxLength() const; - GLint getActiveUniformi(GLuint index, GLenum pname) const; bool isValidUniformLocation(GLint location) const; const LinkedUniform &getUniformByLocation(GLint location) const; + const VariableLocation &getUniformLocation(GLint location) const; + const std::vector &getUniformLocations() const; + const LinkedUniform &getUniformByIndex(GLuint index) const; + + const BufferVariable &getBufferVariableByIndex(GLuint index) const; + + enum SetUniformResult + { + SamplerChanged, + NoSamplerChange, + }; GLint getUniformLocation(const std::string &name) const; GLuint getUniformIndex(const std::string &name) const; @@ -282,7 +489,7 @@ class Program final : angle::NonCopyable, public LabeledObject void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); - void setUniform1iv(GLint location, GLsizei count, const GLint *v); + SetUniformResult setUniform1iv(GLint location, GLsizei count, const GLint *v); void setUniform2iv(GLint location, GLsizei count, const GLint *v); void setUniform3iv(GLint location, GLsizei count, const GLint *v); void setUniform4iv(GLint location, GLsizei count, const GLint *v); @@ -300,21 +507,32 @@ class Program final : angle::NonCopyable, public LabeledObject void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void getUniformfv(GLint location, GLfloat *params) const; - void getUniformiv(GLint location, GLint *params) const; - void getUniformuiv(GLint location, GLuint *params) const; - - void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const; - void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; + void getUniformfv(const Context *context, GLint location, GLfloat *params) const; + void getUniformiv(const Context *context, GLint location, GLint *params) const; + void getUniformuiv(const Context *context, GLint location, GLuint *params) const; + + void getActiveUniformBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const; + void getActiveShaderStorageBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const; GLuint getActiveUniformBlockCount() const; + GLuint getActiveAtomicCounterBufferCount() const; + GLuint getActiveShaderStorageBlockCount() const; GLint getActiveUniformBlockMaxLength() const; GLuint getUniformBlockIndex(const std::string &name) const; + GLuint getShaderStorageBlockIndex(const std::string &name) const; void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; + GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const; - const UniformBlock &getUniformBlockByIndex(GLuint index) const; + const InterfaceBlock &getUniformBlockByIndex(GLuint index) const; + const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const; void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode); void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const; @@ -322,11 +540,14 @@ class Program final : angle::NonCopyable, public LabeledObject GLsizei getTransformFeedbackVaryingMaxLength() const; GLenum getTransformFeedbackBufferMode() const; - static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); - static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); + static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, + const std::string &uniformName, + const sh::InterfaceBlockField &vertexUniform, + const sh::InterfaceBlockField &fragmentUniform, + bool webglCompatibility); void addRef(); - void release(); + void release(const Context *context); unsigned int getRefCount() const; void flagForDeletion(); bool isFlaggedForDeletion() const; @@ -334,28 +555,25 @@ class Program final : angle::NonCopyable, public LabeledObject void validate(const Caps &caps); bool validateSamplers(InfoLog *infoLog, const Caps &caps); bool isValidated() const; + bool samplesFromTexture(const gl::State &state, GLuint textureID) const; const AttributesMask &getActiveAttribLocationsMask() const { - return mData.mActiveAttribLocationsMask; + return mState.mActiveAttribLocationsMask; } - private: - void unlink(bool destroy = false); - void resetUniformBlockBindings(); - - bool linkAttributes(const gl::Data &data, - InfoLog &infoLog, - const AttributeBindings &attributeBindings, - const Shader *vertexShader); - bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps); - static bool linkVaryings(InfoLog &infoLog, - const Shader *vertexShader, - const Shader *fragmentShader); - bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); - void indexUniforms(); - bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, - const sh::InterfaceBlock &fragmentInterfaceBlock); + const std::vector &getSamplerBindings() const + { + return mState.mSamplerBindings; + } + + const std::vector &getImageBindings() const { return mState.mImageBindings; } + const sh::WorkGroupSize &getComputeShaderLocalSize() const + { + return mState.mComputeShaderLocalSize; + } + + const ProgramState &getState() const { return mState; } static bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, @@ -363,71 +581,147 @@ class Program final : angle::NonCopyable, public LabeledObject const sh::ShaderVariable &fragmentVariable, bool validatePrecision); - static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying); - bool linkValidateTransformFeedback(InfoLog &infoLog, - const std::vector &linkedVaryings, - const Caps &caps) const; + GLuint getInputResourceIndex(const GLchar *name) const; + GLuint getOutputResourceIndex(const GLchar *name) const; + void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getBufferVariableResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const; + const sh::Attribute &getInputResource(GLuint index) const; + const sh::OutputVariable &getOutputResource(GLuint index) const; + + class Bindings final : angle::NonCopyable + { + public: + Bindings(); + ~Bindings(); + void bindLocation(GLuint index, const std::string &name); + int getBinding(const std::string &name) const; - void gatherTransformFeedbackVaryings(const std::vector &varyings); - bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps); - void defineOutputVariables(Shader *fragmentShader); + typedef std::unordered_map::const_iterator const_iterator; + const_iterator begin() const; + const_iterator end() const; - std::vector getMergedVaryings() const; - void linkOutputVariables(); + private: + std::unordered_map mBindings; + }; - bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog); + const Bindings &getAttributeBindings() const { return mAttributeBindings; } + const Bindings &getUniformLocationBindings() const { return mUniformLocationBindings; } + const Bindings &getFragmentInputBindings() const { return mFragmentInputBindings; } - struct VectorAndSamplerCount - { - VectorAndSamplerCount() : vectorCount(0), samplerCount(0) {} - VectorAndSamplerCount(const VectorAndSamplerCount &other) = default; - VectorAndSamplerCount &operator=(const VectorAndSamplerCount &other) = default; + int getNumViews() const { return mState.getNumViews(); } + bool usesMultiview() const { return mState.usesMultiview(); } - VectorAndSamplerCount &operator+=(const VectorAndSamplerCount &other) - { - vectorCount += other.vectorCount; - samplerCount += other.samplerCount; - return *this; - } + struct VaryingRef + { + const sh::Varying *get() const { return vertex ? vertex : fragment; } - unsigned int vectorCount; - unsigned int samplerCount; + const sh::Varying *vertex = nullptr; + const sh::Varying *fragment = nullptr; }; + using MergedVaryings = std::map; + + private: + ~Program() override; + + void unlink(); + + bool linkAttributes(const Context *context, InfoLog &infoLog); + bool validateVertexAndFragmentInterfaceBlocks( + const std::vector &vertexInterfaceBlocks, + const std::vector &fragmentInterfaceBlocks, + InfoLog &infoLog, + bool webglCompatibility) const; + bool linkInterfaceBlocks(const Context *context, InfoLog &infoLog); + bool linkVaryings(const Context *context, InfoLog &infoLog) const; + + bool linkUniforms(const Context *context, + InfoLog &infoLog, + const Bindings &uniformLocationBindings); + void linkSamplerAndImageBindings(); + bool linkAtomicCounterBuffers(); + + void updateLinkedShaderStages(); + + bool areMatchingInterfaceBlocks(InfoLog &infoLog, + const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock, + bool webglCompatibility) const; + + static bool linkValidateVaryings(InfoLog &infoLog, + const std::string &varyingName, + const sh::Varying &vertexVarying, + const sh::Varying &fragmentVarying, + int shaderVersion); + bool linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const; + bool linkValidateTransformFeedback(const gl::Context *context, + InfoLog &infoLog, + const MergedVaryings &linkedVaryings, + const Caps &caps) const; + bool linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const; - VectorAndSamplerCount flattenUniform(const sh::ShaderVariable &uniform, - const std::string &fullName, - std::vector *samplerUniforms); + void gatherTransformFeedbackVaryings(const MergedVaryings &varyings); - void gatherInterfaceBlockInfo(); - template - void defineUniformBlockMembers(const std::vector &fields, - const std::string &prefix, - int blockIndex); + MergedVaryings getMergedVaryings(const Context *context) const; + void linkOutputVariables(const Context *context); - void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType); + void setUniformValuesFromBindingQualifiers(); - template - void setUniformInternal(GLint location, GLsizei count, const T *v); + void gatherAtomicCounterBuffers(); + void initInterfaceBlockBindings(); + // Both these function update the cached uniform values and return a modified "count" + // so that the uniform update doesn't overflow the uniform. + template + GLsizei clampUniformCount(const VariableLocation &locationInfo, + GLsizei count, + int vectorSize, + const T *v); template - void setMatrixUniformInternal(GLint location, GLsizei count, GLboolean transpose, const T *v); + GLsizei clampMatrixUniformCount(GLint location, GLsizei count, GLboolean transpose, const T *v); + + void updateSamplerUniform(const VariableLocation &locationInfo, + GLsizei clampedCount, + const GLint *v); template - void getUniformInternal(GLint location, DestT *dataOut) const; + void getUniformInternal(const Context *context, + DestT *dataOut, + GLint location, + GLenum nativeType, + int components) const; + + template + void getResourceName(GLuint index, + const std::vector &resources, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const; - Data mData; + ProgramState mState; rx::ProgramImpl *mProgram; bool mValidated; - AttributeBindings mAttributeBindings; + Bindings mAttributeBindings; + + // Note that this has nothing to do with binding layout qualifiers that can be set for some + // uniforms in GLES3.1+. It is used to pre-set the location of uniforms. + Bindings mUniformLocationBindings; + + // CHROMIUM_path_rendering + Bindings mFragmentInputBindings; bool mLinked; bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use unsigned int mRefCount; - ResourceManager *mResourceManager; + ShaderProgramManager *mResourceManager; const GLuint mHandle; InfoLog mInfoLog; @@ -435,8 +729,7 @@ class Program final : angle::NonCopyable, public LabeledObject // Cache for sampler validation Optional mCachedValidateSamplersResult; std::vector mTextureUnitTypesCache; - RangeUI mSamplerUniformRange; }; -} +} // namespace gl #endif // LIBANGLE_PROGRAM_H_ -- cgit v1.2.3