Home | History | Annotate | Download | only in libGLESv2
      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