|  | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | // Program.h: Defines the Program class. Implements GL program objects | 
|  | // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. | 
|  |  | 
|  | #ifndef LIBGLESV2_PROGRAM_H_ | 
|  | #define LIBGLESV2_PROGRAM_H_ | 
|  |  | 
|  | #include "Shader.h" | 
|  | #include "Context.h" | 
|  | #include "Shader/PixelShader.hpp" | 
|  | #include "Shader/VertexShader.hpp" | 
|  |  | 
|  | #include <string> | 
|  | #include <vector> | 
|  | #include <set> | 
|  |  | 
|  | namespace es2 | 
|  | { | 
|  | class Device; | 
|  | class ResourceManager; | 
|  | class FragmentShader; | 
|  | class VertexShader; | 
|  |  | 
|  | // Helper struct representing a single shader uniform | 
|  | struct Uniform | 
|  | { | 
|  | struct BlockInfo | 
|  | { | 
|  | BlockInfo(const glsl::Uniform& uniform, int blockIndex); | 
|  |  | 
|  | int index; | 
|  | int offset; | 
|  | int arrayStride; | 
|  | int matrixStride; | 
|  | bool isRowMajorMatrix; | 
|  | }; | 
|  |  | 
|  | Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, | 
|  | const BlockInfo &blockInfo); | 
|  |  | 
|  | ~Uniform(); | 
|  |  | 
|  | bool isArray() const; | 
|  | int size() const; | 
|  | int registerCount() const; | 
|  |  | 
|  | const GLenum type; | 
|  | const GLenum precision; | 
|  | const std::string name; | 
|  | const unsigned int arraySize; | 
|  | const BlockInfo blockInfo; | 
|  |  | 
|  | unsigned char *data; | 
|  | bool dirty; | 
|  |  | 
|  | short psRegisterIndex; | 
|  | short vsRegisterIndex; | 
|  | }; | 
|  |  | 
|  | // Helper struct representing a single shader uniform block | 
|  | struct UniformBlock | 
|  | { | 
|  | // use GL_INVALID_INDEX for non-array elements | 
|  | UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes); | 
|  |  | 
|  | void setRegisterIndex(GLenum shader, unsigned int registerIndex); | 
|  |  | 
|  | bool isArrayElement() const; | 
|  | bool isReferencedByVertexShader() const; | 
|  | bool isReferencedByFragmentShader() const; | 
|  |  | 
|  | const std::string name; | 
|  | const unsigned int elementIndex; | 
|  | const unsigned int dataSize; | 
|  |  | 
|  | std::vector<unsigned int> memberUniformIndexes; | 
|  |  | 
|  | unsigned int psRegisterIndex; | 
|  | unsigned int vsRegisterIndex; | 
|  | }; | 
|  |  | 
|  | // Struct used for correlating uniforms/elements of uniform arrays to handles | 
|  | struct UniformLocation | 
|  | { | 
|  | UniformLocation(const std::string &name, unsigned int element, unsigned int index); | 
|  |  | 
|  | std::string name; | 
|  | unsigned int element; | 
|  | unsigned int index; | 
|  | }; | 
|  |  | 
|  | struct LinkedVarying | 
|  | { | 
|  | LinkedVarying(); | 
|  | LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col); | 
|  |  | 
|  | // Original GL name | 
|  | std::string name; | 
|  |  | 
|  | GLenum type; | 
|  | GLsizei size; | 
|  |  | 
|  | int reg;    // First varying register, assigned during link | 
|  | int col;    // First register element, assigned during link | 
|  | }; | 
|  |  | 
|  | class Program | 
|  | { | 
|  | public: | 
|  | Program(ResourceManager *manager, GLuint handle); | 
|  |  | 
|  | ~Program(); | 
|  |  | 
|  | bool attachShader(Shader *shader); | 
|  | bool detachShader(Shader *shader); | 
|  | int getAttachedShadersCount() const; | 
|  |  | 
|  | sw::PixelShader *getPixelShader(); | 
|  | sw::VertexShader *getVertexShader(); | 
|  |  | 
|  | void bindAttributeLocation(GLuint index, const char *name); | 
|  | GLint getAttributeLocation(const char *name); | 
|  | int getAttributeStream(int attributeIndex); | 
|  |  | 
|  | GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex); | 
|  | TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex); | 
|  |  | 
|  | GLuint getUniformIndex(const std::string &name) const; | 
|  | GLuint getUniformBlockIndex(const std::string &name) const; | 
|  | void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); | 
|  | GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; | 
|  | void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; | 
|  |  | 
|  | GLint getUniformLocation(const std::string &name) const; | 
|  | bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); | 
|  | bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); | 
|  | bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); | 
|  | bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v); | 
|  | bool setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | 
|  | bool setUniform1iv(GLint location, GLsizei count, const GLint *v); | 
|  | bool setUniform2iv(GLint location, GLsizei count, const GLint *v); | 
|  | bool setUniform3iv(GLint location, GLsizei count, const GLint *v); | 
|  | bool setUniform4iv(GLint location, GLsizei count, const GLint *v); | 
|  | bool setUniform1uiv(GLint location, GLsizei count, const GLuint *v); | 
|  | bool setUniform2uiv(GLint location, GLsizei count, const GLuint *v); | 
|  | bool setUniform3uiv(GLint location, GLsizei count, const GLuint *v); | 
|  | bool setUniform4uiv(GLint location, GLsizei count, const GLuint *v); | 
|  |  | 
|  | bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); | 
|  | bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); | 
|  | bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params); | 
|  |  | 
|  | void dirtyAllUniforms(); | 
|  | void applyUniforms(Device *device); | 
|  | void applyUniformBuffers(Device *device, BufferBinding* uniformBuffers); | 
|  | void applyTransformFeedback(Device *device, TransformFeedback* transformFeedback); | 
|  |  | 
|  | void link(); | 
|  | bool isLinked() const; | 
|  | size_t getInfoLogLength() const; | 
|  | void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); | 
|  | void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); | 
|  |  | 
|  | void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; | 
|  | size_t getActiveAttributeCount() const; | 
|  | GLint getActiveAttributeMaxLength() const; | 
|  |  | 
|  | void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; | 
|  | size_t getActiveUniformCount() const; | 
|  | GLint getActiveUniformMaxLength() const; | 
|  | GLint getActiveUniformi(GLuint index, GLenum pname) const; | 
|  |  | 
|  | void getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; | 
|  | size_t getActiveUniformBlockCount() const; | 
|  | GLint getActiveUniformBlockMaxLength() 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; | 
|  | GLsizei getTransformFeedbackVaryingCount() const; | 
|  | GLsizei getTransformFeedbackVaryingMaxLength() const; | 
|  | GLenum getTransformFeedbackBufferMode() const; | 
|  |  | 
|  | void addRef(); | 
|  | void release(); | 
|  | unsigned int getRefCount() const; | 
|  | void flagForDeletion(); | 
|  | bool isFlaggedForDeletion() const; | 
|  |  | 
|  | void validate(Device* device); | 
|  | bool validateSamplers(bool logErrors); | 
|  | bool isValidated() const; | 
|  |  | 
|  | unsigned int getSerial() const; | 
|  |  | 
|  | bool getBinaryRetrievableHint() const { return retrievableBinary; } | 
|  | void setBinaryRetrievable(bool retrievable) { retrievableBinary = retrievable; } | 
|  | GLint getBinaryLength() const; | 
|  |  | 
|  | private: | 
|  | void unlink(); | 
|  | void resetUniformBlockBindings(); | 
|  |  | 
|  | bool linkVaryings(); | 
|  | bool linkTransformFeedback(); | 
|  |  | 
|  | bool linkAttributes(); | 
|  | int getAttributeBinding(const glsl::Attribute &attribute); | 
|  |  | 
|  | bool linkUniforms(const Shader *shader); | 
|  | bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader); | 
|  | bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2); | 
|  | bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo); | 
|  | bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block); | 
|  | bool applyUniform(Device *device, GLint location, float* data); | 
|  | bool applyUniform1bv(Device *device, GLint location, GLsizei count, const GLboolean *v); | 
|  | bool applyUniform2bv(Device *device, GLint location, GLsizei count, const GLboolean *v); | 
|  | bool applyUniform3bv(Device *device, GLint location, GLsizei count, const GLboolean *v); | 
|  | bool applyUniform4bv(Device *device, GLint location, GLsizei count, const GLboolean *v); | 
|  | bool applyUniform1fv(Device *device, GLint location, GLsizei count, const GLfloat *v); | 
|  | bool applyUniform2fv(Device *device, GLint location, GLsizei count, const GLfloat *v); | 
|  | bool applyUniform3fv(Device *device, GLint location, GLsizei count, const GLfloat *v); | 
|  | bool applyUniform4fv(Device *device, GLint location, GLsizei count, const GLfloat *v); | 
|  | bool applyUniformMatrix2fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix2x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix2x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix3fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix3x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix3x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix4fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix4x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniformMatrix4x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value); | 
|  | bool applyUniform1iv(Device *device, GLint location, GLsizei count, const GLint *v); | 
|  | bool applyUniform2iv(Device *device, GLint location, GLsizei count, const GLint *v); | 
|  | bool applyUniform3iv(Device *device, GLint location, GLsizei count, const GLint *v); | 
|  | bool applyUniform4iv(Device *device, GLint location, GLsizei count, const GLint *v); | 
|  | bool applyUniform1uiv(Device *device, GLint location, GLsizei count, const GLuint *v); | 
|  | bool applyUniform2uiv(Device *device, GLint location, GLsizei count, const GLuint *v); | 
|  | bool applyUniform3uiv(Device *device, GLint location, GLsizei count, const GLuint *v); | 
|  | bool applyUniform4uiv(Device *device, GLint location, GLsizei count, const GLuint *v); | 
|  |  | 
|  | bool setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements); | 
|  | bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type); | 
|  | bool setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements); | 
|  | bool setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements); | 
|  |  | 
|  | void appendToInfoLog(const char *info, ...); | 
|  | void resetInfoLog(); | 
|  |  | 
|  | static unsigned int issueSerial(); | 
|  |  | 
|  | private: | 
|  | FragmentShader *fragmentShader; | 
|  | VertexShader *vertexShader; | 
|  |  | 
|  | sw::PixelShader *pixelBinary; | 
|  | sw::VertexShader *vertexBinary; | 
|  |  | 
|  | std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS]; | 
|  | glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS]; | 
|  | int attributeStream[MAX_VERTEX_ATTRIBS]; | 
|  |  | 
|  | GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS]; | 
|  |  | 
|  | std::vector<std::string> transformFeedbackVaryings; | 
|  | GLenum transformFeedbackBufferMode; | 
|  | size_t totalLinkedVaryingsComponents; | 
|  |  | 
|  | struct Sampler | 
|  | { | 
|  | bool active; | 
|  | GLint logicalTextureUnit; | 
|  | TextureType textureType; | 
|  | }; | 
|  |  | 
|  | Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS]; | 
|  | Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS]; | 
|  |  | 
|  | typedef std::vector<Uniform*> UniformArray; | 
|  | UniformArray uniforms; | 
|  | typedef std::vector<UniformLocation> UniformIndex; | 
|  | UniformIndex uniformIndex; | 
|  | typedef std::vector<UniformBlock*> UniformBlockArray; | 
|  | UniformBlockArray uniformBlocks; | 
|  | typedef std::vector<LinkedVarying> LinkedVaryingArray; | 
|  | LinkedVaryingArray transformFeedbackLinkedVaryings; | 
|  |  | 
|  | bool linked; | 
|  | bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use | 
|  | char *infoLog; | 
|  | bool validated; | 
|  | bool retrievableBinary; | 
|  |  | 
|  | unsigned int referenceCount; | 
|  | const unsigned int serial; | 
|  |  | 
|  | static unsigned int currentSerial; | 
|  |  | 
|  | ResourceManager *resourceManager; | 
|  | const GLuint handle; | 
|  | }; | 
|  | } | 
|  |  | 
|  | #endif   // LIBGLESV2_PROGRAM_H_ |