1 // 2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Program.h: Defines the gl::Program class. Implements GL program objects 8 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. 9 10 #ifndef LIBGLESV2_PROGRAM_BINARY_H_ 11 #define LIBGLESV2_PROGRAM_BINARY_H_ 12 13 #include "common/RefCountObject.h" 14 #include "angletypes.h" 15 #include "common/mathutil.h" 16 #include "libGLESv2/Uniform.h" 17 #include "libGLESv2/Shader.h" 18 #include "libGLESv2/Constants.h" 19 #include "libGLESv2/renderer/d3d/VertexDataManager.h" 20 #include "libGLESv2/renderer/d3d/DynamicHLSL.h" 21 22 #include "angle_gl.h" 23 24 #include <string> 25 #include <vector> 26 27 // TODO(jmadill): place this in workarounds library 28 #define ANGLE_WORKAROUND_ENABLED 1 29 #define ANGLE_WORKAROUND_DISABLED 2 30 #define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED 31 32 namespace sh 33 { 34 class HLSLBlockEncoder; 35 } 36 37 #include <GLES3/gl3.h> 38 #include <GLES2/gl2.h> 39 #include <GLES2/gl2ext.h> 40 41 #include <string> 42 #include <vector> 43 44 namespace rx 45 { 46 class ShaderExecutable; 47 class Renderer; 48 struct TranslatedAttribute; 49 class UniformStorage; 50 class ProgramImpl; 51 } 52 53 namespace gl 54 { 55 struct Caps; 56 class Shader; 57 class InfoLog; 58 class AttributeBindings; 59 class Buffer; 60 class Framebuffer; 61 62 // Struct used for correlating uniforms/elements of uniform arrays to handles 63 struct VariableLocation 64 { 65 VariableLocation() 66 { 67 } 68 69 VariableLocation(const std::string &name, unsigned int element, unsigned int index); 70 71 std::string name; 72 unsigned int element; 73 unsigned int index; 74 }; 75 76 struct LinkedVarying 77 { 78 LinkedVarying(); 79 LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName, 80 unsigned int semanticIndex, unsigned int semanticIndexCount); 81 82 // Original GL name 83 std::string name; 84 85 GLenum type; 86 GLsizei size; 87 88 // DirectX semantic information 89 std::string semanticName; 90 unsigned int semanticIndex; 91 unsigned int semanticIndexCount; 92 }; 93 94 // This is the result of linking a program. It is the state that would be passed to ProgramBinary. 95 class ProgramBinary : public RefCountObject 96 { 97 public: 98 explicit ProgramBinary(rx::ProgramImpl *impl); 99 ~ProgramBinary(); 100 101 rx::ProgramImpl *getImplementation() { return mProgram; } 102 const rx::ProgramImpl *getImplementation() const { return mProgram; } 103 104 rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo); 105 rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout); 106 rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]); 107 rx::ShaderExecutable *getGeometryExecutable() const; 108 109 GLuint getAttributeLocation(const char *name); 110 int getSemanticIndex(int attributeIndex); 111 112 GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps); 113 GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex); 114 GLint getUsedSamplerRange(SamplerType type); 115 bool usesPointSize() const; 116 bool usesPointSpriteEmulation() const; 117 bool usesGeometryShader() const; 118 119 GLint getUniformLocation(std::string name); 120 GLuint getUniformIndex(std::string name); 121 GLuint getUniformBlockIndex(std::string name); 122 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); 123 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); 124 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); 125 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); 126 void setUniform1iv(GLint location, GLsizei count, const GLint *v); 127 void setUniform2iv(GLint location, GLsizei count, const GLint *v); 128 void setUniform3iv(GLint location, GLsizei count, const GLint *v); 129 void setUniform4iv(GLint location, GLsizei count, const GLint *v); 130 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v); 131 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v); 132 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v); 133 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v); 134 void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 135 void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 136 void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 137 void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 138 void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 139 void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 140 void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 141 void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 142 void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); 143 144 void getUniformfv(GLint location, GLfloat *params); 145 void getUniformiv(GLint location, GLint *params); 146 void getUniformuiv(GLint location, GLuint *params); 147 148 void dirtyAllUniforms(); 149 void applyUniforms(); 150 bool applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps); 151 152 bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length); 153 bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length); 154 GLint getLength(); 155 156 bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader, 157 const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps); 158 void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); 159 160 void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; 161 GLint getActiveAttributeCount() const; 162 GLint getActiveAttributeMaxLength() const; 163 164 void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; 165 GLint getActiveUniformCount() const; 166 GLint getActiveUniformMaxLength() const; 167 GLint getActiveUniformi(GLuint index, GLenum pname) const; 168 bool isValidUniformLocation(GLint location) const; 169 LinkedUniform *getUniformByLocation(GLint location) const; 170 LinkedUniform *getUniformByName(const std::string &name) const; 171 172 void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const; 173 void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; 174 GLuint getActiveUniformBlockCount() const; 175 GLuint getActiveUniformBlockMaxLength() const; 176 UniformBlock *getUniformBlockByIndex(GLuint blockIndex); 177 178 GLint getFragDataLocation(const char *name) const; 179 180 size_t getTransformFeedbackVaryingCount() const; 181 const LinkedVarying &getTransformFeedbackVarying(size_t idx) const; 182 GLenum getTransformFeedbackBufferMode() const; 183 184 void validate(InfoLog &infoLog, const Caps &caps); 185 bool validateSamplers(InfoLog *infoLog, const Caps &caps); 186 bool isValidated() const; 187 void updateSamplerMapping(); 188 189 unsigned int getSerial() const; 190 int getShaderVersion() const; 191 192 void initAttributesByLayout(); 193 void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const; 194 195 const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; } 196 197 static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader); 198 199 private: 200 DISALLOW_COPY_AND_ASSIGN(ProgramBinary); 201 202 struct Sampler 203 { 204 Sampler(); 205 206 bool active; 207 GLint logicalTextureUnit; 208 GLenum textureType; 209 }; 210 211 void reset(); 212 213 bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader); 214 215 static bool linkValidateVariablesBase(InfoLog &infoLog, 216 const std::string &variableName, 217 const sh::ShaderVariable &vertexVariable, 218 const sh::ShaderVariable &fragmentVariable, 219 bool validatePrecision); 220 221 static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); 222 static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying); 223 static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); 224 bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); 225 void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister); 226 void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder); 227 bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps); 228 bool indexUniforms(InfoLog &infoLog, const Caps &caps); 229 static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, 230 std::vector<Sampler> &outSamplers, GLuint *outUsedRange); 231 bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock); 232 bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); 233 bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings, 234 const std::vector<std::string> &transformFeedbackVaryingNames, 235 GLenum transformFeedbackBufferMode, 236 std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings, 237 const Caps &caps) const; 238 template <typename VarT> 239 void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex, 240 sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes, 241 bool inRowMajorLayout); 242 bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps); 243 bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps); 244 void defineOutputVariables(Shader *fragmentShader); 245 246 template <typename T> 247 void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); 248 249 template <int cols, int rows> 250 void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); 251 252 template <typename T> 253 void getUniformv(GLint location, T *params, GLenum uniformType); 254 255 class VertexExecutable 256 { 257 public: 258 VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS], 259 const GLenum signature[MAX_VERTEX_ATTRIBS], 260 rx::ShaderExecutable *shaderExecutable); 261 ~VertexExecutable(); 262 263 bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const; 264 265 const VertexFormat *inputs() const { return mInputs; } 266 const GLenum *signature() const { return mSignature; } 267 rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } 268 269 private: 270 VertexFormat mInputs[MAX_VERTEX_ATTRIBS]; 271 GLenum mSignature[MAX_VERTEX_ATTRIBS]; 272 rx::ShaderExecutable *mShaderExecutable; 273 }; 274 275 class PixelExecutable 276 { 277 public: 278 PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable); 279 ~PixelExecutable(); 280 281 bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; } 282 283 const std::vector<GLenum> &outputSignature() const { return mOutputSignature; } 284 rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } 285 286 private: 287 std::vector<GLenum> mOutputSignature; 288 rx::ShaderExecutable *mShaderExecutable; 289 }; 290 291 rx::ProgramImpl *mProgram; 292 293 std::vector<VertexExecutable *> mVertexExecutables; 294 std::vector<PixelExecutable *> mPixelExecutables; 295 296 rx::ShaderExecutable *mGeometryExecutable; 297 298 sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; 299 sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS]; 300 int mSemanticIndex[MAX_VERTEX_ATTRIBS]; 301 int mAttributesByLayout[MAX_VERTEX_ATTRIBS]; 302 303 GLenum mTransformFeedbackBufferMode; 304 std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings; 305 306 std::vector<Sampler> mSamplersPS; 307 std::vector<Sampler> mSamplersVS; 308 GLuint mUsedVertexSamplerRange; 309 GLuint mUsedPixelSamplerRange; 310 bool mUsesPointSize; 311 int mShaderVersion; 312 bool mDirtySamplerMapping; 313 314 std::vector<LinkedUniform*> mUniforms; 315 std::vector<UniformBlock*> mUniformBlocks; 316 std::vector<VariableLocation> mUniformIndex; 317 std::map<int, VariableLocation> mOutputVariables; 318 319 bool mValidated; 320 321 const unsigned int mSerial; 322 323 static unsigned int issueSerial(); 324 static unsigned int mCurrentSerial; 325 }; 326 327 } 328 329 #endif // LIBGLESV2_PROGRAM_BINARY_H_ 330