Home | History | Annotate | Download | only in libGLESv2
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Program.h: Defines the Program class. Implements GL program objects
     16 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
     17 
     18 #ifndef LIBGLESV2_PROGRAM_H_
     19 #define LIBGLESV2_PROGRAM_H_
     20 
     21 #include "Shader.h"
     22 #include "Context.h"
     23 #include "Shader/PixelShader.hpp"
     24 #include "Shader/VertexShader.hpp"
     25 
     26 #include <string>
     27 #include <vector>
     28 #include <set>
     29 
     30 namespace es2
     31 {
     32 	class Device;
     33 	class ResourceManager;
     34 	class FragmentShader;
     35 	class VertexShader;
     36 
     37 	// Helper struct representing a single shader uniform
     38 	struct Uniform
     39 	{
     40 		struct BlockInfo
     41 		{
     42 			BlockInfo(const glsl::Uniform& uniform, int blockIndex);
     43 
     44 			int index;
     45 			int offset;
     46 			int arrayStride;
     47 			int matrixStride;
     48 			bool isRowMajorMatrix;
     49 		};
     50 
     51 		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
     52 		        const BlockInfo &blockInfo);
     53 
     54 		~Uniform();
     55 
     56 		bool isArray() const;
     57 		int size() const;
     58 		int registerCount() const;
     59 
     60 		const GLenum type;
     61 		const GLenum precision;
     62 		const std::string name;
     63 		const unsigned int arraySize;
     64 		const BlockInfo blockInfo;
     65 
     66 		unsigned char *data;
     67 		bool dirty;
     68 
     69 		short psRegisterIndex;
     70 		short vsRegisterIndex;
     71 	};
     72 
     73 	// Helper struct representing a single shader uniform block
     74 	struct UniformBlock
     75 	{
     76 		// use GL_INVALID_INDEX for non-array elements
     77 		UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes);
     78 
     79 		void setRegisterIndex(GLenum shader, unsigned int registerIndex);
     80 
     81 		bool isArrayElement() const;
     82 		bool isReferencedByVertexShader() const;
     83 		bool isReferencedByFragmentShader() const;
     84 
     85 		const std::string name;
     86 		const unsigned int elementIndex;
     87 		const unsigned int dataSize;
     88 
     89 		std::vector<unsigned int> memberUniformIndexes;
     90 
     91 		unsigned int psRegisterIndex;
     92 		unsigned int vsRegisterIndex;
     93 	};
     94 
     95 	// Struct used for correlating uniforms/elements of uniform arrays to handles
     96 	struct UniformLocation
     97 	{
     98 		UniformLocation(const std::string &name, unsigned int element, unsigned int index);
     99 
    100 		std::string name;
    101 		unsigned int element;
    102 		unsigned int index;
    103 	};
    104 
    105 	struct LinkedVarying
    106 	{
    107 		LinkedVarying();
    108 		LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col);
    109 
    110 		// Original GL name
    111 		std::string name;
    112 
    113 		GLenum type;
    114 		GLsizei size;
    115 
    116 		int reg;    // First varying register, assigned during link
    117 		int col;    // First register element, assigned during link
    118 	};
    119 
    120 	class Program
    121 	{
    122 	public:
    123 		Program(ResourceManager *manager, GLuint handle);
    124 
    125 		~Program();
    126 
    127 		bool attachShader(Shader *shader);
    128 		bool detachShader(Shader *shader);
    129 		int getAttachedShadersCount() const;
    130 
    131 		sw::PixelShader *getPixelShader();
    132 		sw::VertexShader *getVertexShader();
    133 
    134 		void bindAttributeLocation(GLuint index, const char *name);
    135 		GLint getAttributeLocation(const char *name);
    136 		int getAttributeStream(int attributeIndex);
    137 
    138 		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);
    139 		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);
    140 
    141 		GLuint getUniformIndex(const std::string &name) const;
    142 		GLuint getUniformBlockIndex(const std::string &name) const;
    143 		void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
    144 		GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
    145 		void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
    146 
    147 		GLint getUniformLocation(const std::string &name) const;
    148 		bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
    149 		bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
    150 		bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
    151 		bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
    152 		bool setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    153 		bool setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    154 		bool setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    155 		bool setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    156 		bool setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    157 		bool setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    158 		bool setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    159 		bool setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    160 		bool setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    161 		bool setUniform1iv(GLint location, GLsizei count, const GLint *v);
    162 		bool setUniform2iv(GLint location, GLsizei count, const GLint *v);
    163 		bool setUniform3iv(GLint location, GLsizei count, const GLint *v);
    164 		bool setUniform4iv(GLint location, GLsizei count, const GLint *v);
    165 		bool setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
    166 		bool setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
    167 		bool setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
    168 		bool setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
    169 
    170 		bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
    171 		bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
    172 		bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params);
    173 
    174 		void dirtyAllUniforms();
    175 		void applyUniforms(Device *device);
    176 		void applyUniformBuffers(Device *device, BufferBinding* uniformBuffers);
    177 		void applyTransformFeedback(Device *device, TransformFeedback* transformFeedback);
    178 
    179 		void link();
    180 		bool isLinked() const;
    181 		size_t getInfoLogLength() const;
    182 		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
    183 		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
    184 
    185 		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
    186 		size_t getActiveAttributeCount() const;
    187 		GLint getActiveAttributeMaxLength() const;
    188 
    189 		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
    190 		size_t getActiveUniformCount() const;
    191 		GLint getActiveUniformMaxLength() const;
    192 		GLint getActiveUniformi(GLuint index, GLenum pname) const;
    193 
    194 		void getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
    195 		size_t getActiveUniformBlockCount() const;
    196 		GLint getActiveUniformBlockMaxLength() const;
    197 
    198 		void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);
    199 		void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
    200 		GLsizei getTransformFeedbackVaryingCount() const;
    201 		GLsizei getTransformFeedbackVaryingMaxLength() const;
    202 		GLenum getTransformFeedbackBufferMode() const;
    203 
    204 		void addRef();
    205 		void release();
    206 		unsigned int getRefCount() const;
    207 		void flagForDeletion();
    208 		bool isFlaggedForDeletion() const;
    209 
    210 		void validate(Device* device);
    211 		bool validateSamplers(bool logErrors);
    212 		bool isValidated() const;
    213 
    214 		unsigned int getSerial() const;
    215 
    216 		bool getBinaryRetrievableHint() const { return retrievableBinary; }
    217 		void setBinaryRetrievable(bool retrievable) { retrievableBinary = retrievable; }
    218 		GLint getBinaryLength() const;
    219 
    220 	private:
    221 		void unlink();
    222 		void resetUniformBlockBindings();
    223 
    224 		bool linkVaryings();
    225 		bool linkTransformFeedback();
    226 
    227 		bool linkAttributes();
    228 		int getAttributeBinding(const glsl::Attribute &attribute);
    229 
    230 		bool linkUniforms(const Shader *shader);
    231 		bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader);
    232 		bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2);
    233 		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo);
    234 		bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block);
    235 		bool applyUniform(Device *device, GLint location, float* data);
    236 		bool applyUniform1bv(Device *device, GLint location, GLsizei count, const GLboolean *v);
    237 		bool applyUniform2bv(Device *device, GLint location, GLsizei count, const GLboolean *v);
    238 		bool applyUniform3bv(Device *device, GLint location, GLsizei count, const GLboolean *v);
    239 		bool applyUniform4bv(Device *device, GLint location, GLsizei count, const GLboolean *v);
    240 		bool applyUniform1fv(Device *device, GLint location, GLsizei count, const GLfloat *v);
    241 		bool applyUniform2fv(Device *device, GLint location, GLsizei count, const GLfloat *v);
    242 		bool applyUniform3fv(Device *device, GLint location, GLsizei count, const GLfloat *v);
    243 		bool applyUniform4fv(Device *device, GLint location, GLsizei count, const GLfloat *v);
    244 		bool applyUniformMatrix2fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    245 		bool applyUniformMatrix2x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    246 		bool applyUniformMatrix2x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    247 		bool applyUniformMatrix3fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    248 		bool applyUniformMatrix3x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    249 		bool applyUniformMatrix3x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    250 		bool applyUniformMatrix4fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    251 		bool applyUniformMatrix4x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    252 		bool applyUniformMatrix4x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value);
    253 		bool applyUniform1iv(Device *device, GLint location, GLsizei count, const GLint *v);
    254 		bool applyUniform2iv(Device *device, GLint location, GLsizei count, const GLint *v);
    255 		bool applyUniform3iv(Device *device, GLint location, GLsizei count, const GLint *v);
    256 		bool applyUniform4iv(Device *device, GLint location, GLsizei count, const GLint *v);
    257 		bool applyUniform1uiv(Device *device, GLint location, GLsizei count, const GLuint *v);
    258 		bool applyUniform2uiv(Device *device, GLint location, GLsizei count, const GLuint *v);
    259 		bool applyUniform3uiv(Device *device, GLint location, GLsizei count, const GLuint *v);
    260 		bool applyUniform4uiv(Device *device, GLint location, GLsizei count, const GLuint *v);
    261 
    262 		bool setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements);
    263 		bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type);
    264 		bool setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements);
    265 		bool setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements);
    266 
    267 		void appendToInfoLog(const char *info, ...);
    268 		void resetInfoLog();
    269 
    270 		static unsigned int issueSerial();
    271 
    272 	private:
    273 		FragmentShader *fragmentShader;
    274 		VertexShader *vertexShader;
    275 
    276 		sw::PixelShader *pixelBinary;
    277 		sw::VertexShader *vertexBinary;
    278 
    279 		std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];
    280 		glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];
    281 		int attributeStream[MAX_VERTEX_ATTRIBS];
    282 
    283 		GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS];
    284 
    285 		std::vector<std::string> transformFeedbackVaryings;
    286 		GLenum transformFeedbackBufferMode;
    287 		size_t totalLinkedVaryingsComponents;
    288 
    289 		struct Sampler
    290 		{
    291 			bool active;
    292 			GLint logicalTextureUnit;
    293 			TextureType textureType;
    294 		};
    295 
    296 		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];
    297 		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];
    298 
    299 		typedef std::vector<Uniform*> UniformArray;
    300 		UniformArray uniforms;
    301 		typedef std::vector<UniformLocation> UniformIndex;
    302 		UniformIndex uniformIndex;
    303 		typedef std::vector<UniformBlock*> UniformBlockArray;
    304 		UniformBlockArray uniformBlocks;
    305 		typedef std::vector<LinkedVarying> LinkedVaryingArray;
    306 		LinkedVaryingArray transformFeedbackLinkedVaryings;
    307 
    308 		bool linked;
    309 		bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use
    310 		char *infoLog;
    311 		bool validated;
    312 		bool retrievableBinary;
    313 
    314 		unsigned int referenceCount;
    315 		const unsigned int serial;
    316 
    317 		static unsigned int currentSerial;
    318 
    319 		ResourceManager *resourceManager;
    320 		const GLuint handle;
    321 	};
    322 }
    323 
    324 #endif   // LIBGLESV2_PROGRAM_H_
    325