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