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.
17
18#ifndef LIBGL_PROGRAM_H_
19#define LIBGL_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
30namespace gl
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		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize);
41
42		~Uniform();
43
44		bool isArray() const;
45		int size() const;
46		int registerCount() const;
47
48		const GLenum type;
49		const GLenum precision;
50		const std::string name;
51		const unsigned int arraySize;
52
53		unsigned char *data;
54		bool dirty;
55
56		short psRegisterIndex;
57		short vsRegisterIndex;
58	};
59
60	// Struct used for correlating uniforms/elements of uniform arrays to handles
61	struct UniformLocation
62	{
63		UniformLocation(const std::string &name, unsigned int element, unsigned int index);
64
65		std::string name;
66		unsigned int element;
67		unsigned int index;
68	};
69
70	class Program
71	{
72	public:
73		Program(ResourceManager *manager, GLuint handle);
74
75		~Program();
76
77		bool attachShader(Shader *shader);
78		bool detachShader(Shader *shader);
79		int getAttachedShadersCount() const;
80
81		sw::PixelShader *getPixelShader();
82		sw::VertexShader *getVertexShader();
83
84		void bindAttributeLocation(GLuint index, const char *name);
85		GLuint getAttributeLocation(const char *name);
86		int getAttributeStream(int attributeIndex);
87
88		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);
89		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);
90
91		GLint getUniformLocation(std::string name);
92		bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
93		bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
94		bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
95		bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
96		bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);
97		bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
98		bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
99		bool setUniform1iv(GLint location, GLsizei count, const GLint *v);
100		bool setUniform2iv(GLint location, GLsizei count, const GLint *v);
101		bool setUniform3iv(GLint location, GLsizei count, const GLint *v);
102		bool setUniform4iv(GLint location, GLsizei count, const GLint *v);
103
104		bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
105		bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
106
107		void dirtyAllUniforms();
108		void applyUniforms();
109
110		void link();
111		bool isLinked();
112		int getInfoLogLength() const;
113		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
114		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
115
116		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
117		size_t getActiveAttributeCount() const;
118		GLint getActiveAttributeMaxLength() const;
119
120		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
121		size_t getActiveUniformCount() const;
122		GLint getActiveUniformMaxLength() const;
123
124		void addRef();
125		void release();
126		unsigned int getRefCount() const;
127		void flagForDeletion();
128		bool isFlaggedForDeletion() const;
129
130		void validate();
131		bool validateSamplers(bool logErrors);
132		bool isValidated() const;
133
134		unsigned int getSerial() const;
135
136	private:
137		void unlink();
138
139		int packVaryings(const glsl::Varying *packing[][4]);
140		bool linkVaryings();
141
142		bool linkAttributes();
143		int getAttributeBinding(const std::string &name);
144
145		bool linkUniforms(Shader *shader);
146		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex);
147		bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);
148		bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);
149		bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
150		bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v);
151		bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v);
152		bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v);
153		bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v);
154		bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v);
155		bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);
156		bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
157		bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
158		bool applyUniform1iv(GLint location, GLsizei count, const GLint *v);
159		bool applyUniform2iv(GLint location, GLsizei count, const GLint *v);
160		bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
161		bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);
162
163		void appendToInfoLog(const char *info, ...);
164		void resetInfoLog();
165
166		static unsigned int issueSerial();
167
168	private:
169		gl::Device *device;
170		FragmentShader *fragmentShader;
171		VertexShader *vertexShader;
172
173		sw::PixelShader *pixelBinary;
174		sw::VertexShader *vertexBinary;
175
176		std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];
177		glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];
178		int attributeStream[MAX_VERTEX_ATTRIBS];
179
180		struct Sampler
181		{
182			bool active;
183			GLint logicalTextureUnit;
184			TextureType textureType;
185		};
186
187		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];
188		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];
189
190		typedef std::vector<Uniform*> UniformArray;
191		UniformArray uniforms;
192		typedef std::vector<UniformLocation> UniformIndex;
193		UniformIndex uniformIndex;
194
195		bool linked;
196		bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use
197		char *infoLog;
198		bool validated;
199
200		unsigned int referenceCount;
201		const unsigned int serial;
202
203		static unsigned int currentSerial;
204
205		ResourceManager *resourceManager;
206		const GLuint handle;
207	};
208}
209
210#endif   // LIBGL_PROGRAM_H_
211