• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getBinaryRetrievableHint()216 		bool getBinaryRetrievableHint() const { return retrievableBinary; }
setBinaryRetrievable(bool retrievable)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