// 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. #ifndef LIBGL_PROGRAM_H_ #define LIBGL_PROGRAM_H_ #include "Shader.h" #include "Context.h" #include "Shader/PixelShader.hpp" #include "Shader/VertexShader.hpp" #include <string> #include <vector> #include <set> namespace gl { class Device; class ResourceManager; class FragmentShader; class VertexShader; // Helper struct representing a single shader uniform struct Uniform { Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize); ~Uniform(); bool isArray() const; int size() const; int registerCount() const; const GLenum type; const GLenum precision; const std::string name; const unsigned int arraySize; unsigned char *data; bool dirty; short psRegisterIndex; short 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; }; 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); GLuint getAttributeLocation(const char *name); int getAttributeStream(int attributeIndex); GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex); TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex); GLint getUniformLocation(std::string name); 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, const GLfloat *value); bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix4fv(GLint location, GLsizei count, 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 getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); void dirtyAllUniforms(); void applyUniforms(); void link(); bool isLinked(); int 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; void addRef(); void release(); unsigned int getRefCount() const; void flagForDeletion(); bool isFlaggedForDeletion() const; void validate(); bool validateSamplers(bool logErrors); bool isValidated() const; unsigned int getSerial() const; private: void unlink(); int packVaryings(const glsl::Varying *packing[][4]); bool linkVaryings(); bool linkAttributes(); int getAttributeBinding(const std::string &name); bool linkUniforms(Shader *shader); bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex); bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v); bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v); bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v); bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v); bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v); bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v); bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v); bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v); bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value); bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); bool applyUniform1iv(GLint location, GLsizei count, const GLint *v); bool applyUniform2iv(GLint location, GLsizei count, const GLint *v); bool applyUniform3iv(GLint location, GLsizei count, const GLint *v); bool applyUniform4iv(GLint location, GLsizei count, const GLint *v); void appendToInfoLog(const char *info, ...); void resetInfoLog(); static unsigned int issueSerial(); private: gl::Device *device; 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]; 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; bool linked; bool orphaned; // Flag to indicate that the program can be deleted when no longer in use char *infoLog; bool validated; unsigned int referenceCount; const unsigned int serial; static unsigned int currentSerial; ResourceManager *resourceManager; const GLuint handle; }; } #endif // LIBGL_PROGRAM_H_