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 #include <map> 30 31 namespace es2 32 { 33 class Device; 34 class ResourceManager; 35 class FragmentShader; 36 class VertexShader; 37 38 // Helper struct representing a single shader uniform 39 struct Uniform 40 { 41 struct BlockInfo 42 { 43 BlockInfo(const glsl::Uniform& uniform, int blockIndex); 44 45 int index = -1; 46 int offset = -1; 47 int arrayStride = -1; 48 int matrixStride = -1; 49 bool isRowMajorMatrix = false; 50 }; 51 52 Uniform(const glsl::Uniform &uniform, 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 std::vector<glsl::ShaderVariable> fields; 66 67 unsigned char *data = nullptr; 68 bool dirty = true; 69 70 short psRegisterIndex = -1; 71 short vsRegisterIndex = -1; 72 }; 73 74 // Helper struct representing a single shader uniform block 75 struct UniformBlock 76 { 77 // use GL_INVALID_INDEX for non-array elements 78 UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes); 79 80 void setRegisterIndex(GLenum shader, unsigned int registerIndex); 81 82 bool isArrayElement() const; 83 bool isReferencedByVertexShader() const; 84 bool isReferencedByFragmentShader() const; 85 86 const std::string name; 87 const unsigned int elementIndex; 88 const unsigned int dataSize; 89 90 std::vector<unsigned int> memberUniformIndexes; 91 92 unsigned int psRegisterIndex; 93 unsigned int vsRegisterIndex; 94 }; 95 96 // Struct used for correlating uniforms/elements of uniform arrays to handles 97 struct UniformLocation 98 { 99 UniformLocation(const std::string &name, unsigned int element, unsigned int index); 100 101 std::string name; 102 unsigned int element; 103 unsigned int index; 104 }; 105 106 struct LinkedVarying 107 { 108 LinkedVarying(); 109 LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col); 110 111 // Original GL name 112 std::string name; 113 114 GLenum type; 115 GLsizei size; 116 117 int reg; // First varying register, assigned during link 118 int col; // First register element, assigned during link 119 }; 120 121 class Program 122 { 123 public: 124 Program(ResourceManager *manager, GLuint handle); 125 126 ~Program(); 127 128 bool attachShader(Shader *shader); 129 bool detachShader(Shader *shader); 130 int getAttachedShadersCount() const; 131 132 sw::PixelShader *getPixelShader(); 133 sw::VertexShader *getVertexShader(); 134 135 void bindAttributeLocation(GLuint index, const char *name); 136 GLint getAttributeLocation(const char *name); 137 int getAttributeStream(int attributeIndex); 138 139 GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex); 140 TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex); 141 142 GLuint getUniformIndex(const std::string &name) const; 143 GLuint getUniformBlockIndex(const std::string &name) const; 144 void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); 145 GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; 146 void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; 147 148 GLint getUniformLocation(const std::string &name) const; 149 bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); 150 bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); 151 bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); 152 bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v); 153 bool setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 154 bool setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 155 bool setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 156 bool setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 157 bool setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 158 bool setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 159 bool setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 160 bool setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 161 bool setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 162 bool setUniform1iv(GLint location, GLsizei count, const GLint *v); 163 bool setUniform2iv(GLint location, GLsizei count, const GLint *v); 164 bool setUniform3iv(GLint location, GLsizei count, const GLint *v); 165 bool setUniform4iv(GLint location, GLsizei count, const GLint *v); 166 bool setUniform1uiv(GLint location, GLsizei count, const GLuint *v); 167 bool setUniform2uiv(GLint location, GLsizei count, const GLuint *v); 168 bool setUniform3uiv(GLint location, GLsizei count, const GLuint *v); 169 bool setUniform4uiv(GLint location, GLsizei count, const GLuint *v); 170 171 bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); 172 bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); 173 bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params); 174 175 void dirtyAllUniforms(); 176 void applyUniforms(Device *device); 177 void applyUniformBuffers(Device *device, BufferBinding* uniformBuffers); 178 void applyTransformFeedback(Device *device, TransformFeedback* transformFeedback); 179 180 void link(); 181 bool isLinked() const; 182 size_t getInfoLogLength() const; 183 void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); 184 void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); 185 186 GLint getFragDataLocation(const GLchar *name); 187 188 void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; 189 size_t getActiveAttributeCount() const; 190 GLint getActiveAttributeMaxLength() const; 191 192 void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; 193 size_t getActiveUniformCount() const; 194 GLint getActiveUniformMaxLength() const; 195 GLint getActiveUniformi(GLuint index, GLenum pname) const; 196 197 void getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 198 size_t getActiveUniformBlockCount() const; 199 GLint getActiveUniformBlockMaxLength() const; 200 201 void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode); 202 void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const; 203 GLsizei getTransformFeedbackVaryingCount() const; 204 GLsizei getTransformFeedbackVaryingMaxLength() const; 205 GLenum getTransformFeedbackBufferMode() const; 206 207 void addRef(); 208 void release(); 209 unsigned int getRefCount() const; 210 void flagForDeletion(); 211 bool isFlaggedForDeletion() const; 212 213 void validate(Device* device); 214 bool validateSamplers(bool logErrors); 215 bool isValidated() const; 216 217 unsigned int getSerial() const; 218 getBinaryRetrievableHint()219 bool getBinaryRetrievableHint() const { return retrievableBinary; } setBinaryRetrievable(bool retrievable)220 void setBinaryRetrievable(bool retrievable) { retrievableBinary = retrievable; } 221 GLint getBinaryLength() const; 222 223 private: 224 void unlink(); 225 void resetUniformBlockBindings(); 226 227 bool linkVaryings(); 228 bool linkTransformFeedback(); 229 230 bool linkAttributes(); 231 bool linkAttribute(const glsl::Attribute &attribute, int location, unsigned int &usedLocations); 232 int getAttributeLocation(const std::string &name); 233 234 Uniform *getUniform(const std::string &name) const; 235 bool linkUniforms(const Shader *shader); 236 bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader); 237 bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2); 238 bool areMatchingFields(const std::vector<glsl::ShaderVariable>& fields1, const std::vector<glsl::ShaderVariable>& fields2, const std::string& name); 239 bool validateUniformStruct(GLenum shader, const glsl::Uniform &newUniformStruct); 240 bool defineUniform(GLenum shader, const glsl::Uniform &uniform, const Uniform::BlockInfo& blockInfo); 241 bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block); 242 bool applyUniform(Device *device, GLint location, float* data); 243 bool applyUniform1bv(Device *device, GLint location, GLsizei count, const GLboolean *v); 244 bool applyUniform2bv(Device *device, GLint location, GLsizei count, const GLboolean *v); 245 bool applyUniform3bv(Device *device, GLint location, GLsizei count, const GLboolean *v); 246 bool applyUniform4bv(Device *device, GLint location, GLsizei count, const GLboolean *v); 247 bool applyUniform1fv(Device *device, GLint location, GLsizei count, const GLfloat *v); 248 bool applyUniform2fv(Device *device, GLint location, GLsizei count, const GLfloat *v); 249 bool applyUniform3fv(Device *device, GLint location, GLsizei count, const GLfloat *v); 250 bool applyUniform4fv(Device *device, GLint location, GLsizei count, const GLfloat *v); 251 bool applyUniformMatrix2fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 252 bool applyUniformMatrix2x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 253 bool applyUniformMatrix2x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 254 bool applyUniformMatrix3fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 255 bool applyUniformMatrix3x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 256 bool applyUniformMatrix3x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 257 bool applyUniformMatrix4fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 258 bool applyUniformMatrix4x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 259 bool applyUniformMatrix4x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value); 260 bool applyUniform1iv(Device *device, GLint location, GLsizei count, const GLint *v); 261 bool applyUniform2iv(Device *device, GLint location, GLsizei count, const GLint *v); 262 bool applyUniform3iv(Device *device, GLint location, GLsizei count, const GLint *v); 263 bool applyUniform4iv(Device *device, GLint location, GLsizei count, const GLint *v); 264 bool applyUniform1uiv(Device *device, GLint location, GLsizei count, const GLuint *v); 265 bool applyUniform2uiv(Device *device, GLint location, GLsizei count, const GLuint *v); 266 bool applyUniform3uiv(Device *device, GLint location, GLsizei count, const GLuint *v); 267 bool applyUniform4uiv(Device *device, GLint location, GLsizei count, const GLuint *v); 268 269 bool setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements); 270 bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type); 271 bool setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements); 272 bool setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements); 273 274 void appendToInfoLog(const char *info, ...); 275 void resetInfoLog(); 276 277 static unsigned int issueSerial(); 278 279 FragmentShader *fragmentShader; 280 VertexShader *vertexShader; 281 282 sw::PixelShader *pixelBinary; 283 sw::VertexShader *vertexBinary; 284 285 std::map<std::string, GLuint> attributeBinding; 286 std::map<std::string, GLuint> linkedAttributeLocation; 287 std::vector<glsl::Attribute> linkedAttribute; 288 int attributeStream[MAX_VERTEX_ATTRIBS]; 289 290 GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS]; 291 292 std::vector<std::string> transformFeedbackVaryings; 293 GLenum transformFeedbackBufferMode; 294 size_t totalLinkedVaryingsComponents; 295 296 struct Sampler 297 { 298 bool active; 299 GLint logicalTextureUnit; 300 TextureType textureType; 301 }; 302 303 Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS]; 304 Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS]; 305 306 typedef std::vector<Uniform*> UniformArray; 307 UniformArray uniforms; 308 typedef std::vector<Uniform> UniformStructArray; 309 UniformStructArray uniformStructs; 310 typedef std::vector<UniformLocation> UniformIndex; 311 UniformIndex uniformIndex; 312 typedef std::vector<UniformBlock*> UniformBlockArray; 313 UniformBlockArray uniformBlocks; 314 typedef std::vector<LinkedVarying> LinkedVaryingArray; 315 LinkedVaryingArray transformFeedbackLinkedVaryings; 316 317 bool linked; 318 bool orphaned; // Flag to indicate that the program can be deleted when no longer in use 319 char *infoLog; 320 bool validated; 321 bool retrievableBinary; 322 323 unsigned int referenceCount; 324 const unsigned int serial; 325 326 static unsigned int currentSerial; 327 328 ResourceManager *resourceManager; 329 const GLuint handle; 330 }; 331 } 332 333 #endif // LIBGLESV2_PROGRAM_H_ 334