// SwiftShader Software Renderer | |
// | |
// Copyright(c) 2005-2013 TransGaming Inc. | |
// | |
// All rights reserved. No part of this software may be copied, distributed, transmitted, | |
// transcribed, stored in a retrieval system, translated into any human or computer | |
// language by any means, or disclosed to third parties without the explicit written | |
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express | |
// or implied, including but not limited to any patent rights, are granted to you. | |
// | |
// Program.h: Defines the Program class. Implements GL program objects | |
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. | |
#ifndef LIBGLESV2_PROGRAM_H_ | |
#define LIBGLESV2_PROGRAM_H_ | |
#include "Shader.h" | |
#include "Context.h" | |
#include "Shader/PixelShader.hpp" | |
#include "Shader/VertexShader.hpp" | |
#include <string> | |
#include <vector> | |
#include <set> | |
namespace es2 | |
{ | |
class Device; | |
class ResourceManager; | |
class FragmentShader; | |
class VertexShader; | |
// Helper struct representing a single shader uniform | |
struct Uniform | |
{ | |
struct BlockInfo | |
{ | |
BlockInfo(const glsl::Uniform& uniform, int blockIndex); | |
int index; | |
int offset; | |
int arrayStride; | |
int matrixStride; | |
bool isRowMajorMatrix; | |
}; | |
Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, | |
const BlockInfo &blockInfo); | |
~Uniform(); | |
bool isArray() const; | |
int size() const; | |
int registerCount() const; | |
const GLenum type; | |
const GLenum precision; | |
const std::string name; | |
const unsigned int arraySize; | |
const BlockInfo blockInfo; | |
unsigned char *data; | |
bool dirty; | |
short psRegisterIndex; | |
short vsRegisterIndex; | |
}; | |
// Helper struct representing a single shader uniform block | |
struct UniformBlock | |
{ | |
// use GL_INVALID_INDEX for non-array elements | |
UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes); | |
void setRegisterIndex(GLenum shader, unsigned int registerIndex); | |
bool isArrayElement() const; | |
bool isReferencedByVertexShader() const; | |
bool isReferencedByFragmentShader() const; | |
const std::string name; | |
const unsigned int elementIndex; | |
const unsigned int dataSize; | |
std::vector<unsigned int> memberUniformIndexes; | |
unsigned int psRegisterIndex; | |
unsigned int vsRegisterIndex; | |
}; | |
// Struct used for correlating uniforms/elements of uniform arrays to handles | |
struct UniformLocation | |
{ | |
UniformLocation(const std::string &name, unsigned int element, unsigned int index); | |
std::string name; | |
unsigned int element; | |
unsigned int index; | |
}; | |
struct LinkedVarying | |
{ | |
LinkedVarying(); | |
LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col); | |
// Original GL name | |
std::string name; | |
GLenum type; | |
GLsizei size; | |
int reg; // First varying register, assigned during link | |
int col; // First register element, assigned during link | |
}; | |
class Program | |
{ | |
public: | |
Program(ResourceManager *manager, GLuint handle); | |
~Program(); | |
bool attachShader(Shader *shader); | |
bool detachShader(Shader *shader); | |
int getAttachedShadersCount() const; | |
sw::PixelShader *getPixelShader(); | |
sw::VertexShader *getVertexShader(); | |
void bindAttributeLocation(GLuint index, const char *name); | |
GLuint getAttributeLocation(const char *name); | |
int getAttributeStream(int attributeIndex); | |
GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex); | |
TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex); | |
GLuint getUniformIndex(const std::string &name) const; | |
GLuint getUniformBlockIndex(const std::string &name) const; | |
void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); | |
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; | |
void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; | |
GLint getUniformLocation(const std::string &name) const; | |
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); | |
bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); | |
bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); | |
bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v); | |
bool setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); | |
bool setUniform1iv(GLint location, GLsizei count, const GLint *v); | |
bool setUniform2iv(GLint location, GLsizei count, const GLint *v); | |
bool setUniform3iv(GLint location, GLsizei count, const GLint *v); | |
bool setUniform4iv(GLint location, GLsizei count, const GLint *v); | |
bool setUniform1uiv(GLint location, GLsizei count, const GLuint *v); | |
bool setUniform2uiv(GLint location, GLsizei count, const GLuint *v); | |
bool setUniform3uiv(GLint location, GLsizei count, const GLuint *v); | |
bool setUniform4uiv(GLint location, GLsizei count, const GLuint *v); | |
bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); | |
bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); | |
bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params); | |
void dirtyAllUniforms(); | |
void applyUniforms(); | |
void applyUniformBuffers(BufferBinding* uniformBuffers); | |
void applyTransformFeedback(TransformFeedback* transformFeedback); | |
void link(); | |
bool isLinked() const; | |
size_t getInfoLogLength() const; | |
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); | |
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); | |
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; | |
size_t getActiveAttributeCount() const; | |
GLint getActiveAttributeMaxLength() const; | |
void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; | |
size_t getActiveUniformCount() const; | |
GLint getActiveUniformMaxLength() const; | |
GLint getActiveUniformi(GLuint index, GLenum pname) const; | |
void getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; | |
size_t getActiveUniformBlockCount() const; | |
GLint getActiveUniformBlockMaxLength() const; | |
void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode); | |
void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const; | |
GLsizei getTransformFeedbackVaryingCount() const; | |
GLsizei getTransformFeedbackVaryingMaxLength() const; | |
GLenum getTransformFeedbackBufferMode() const; | |
void addRef(); | |
void release(); | |
unsigned int getRefCount() const; | |
void flagForDeletion(); | |
bool isFlaggedForDeletion() const; | |
void validate(); | |
bool validateSamplers(bool logErrors); | |
bool isValidated() const; | |
unsigned int getSerial() const; | |
bool getBinaryRetrievableHint() const { return retrievableBinary; } | |
void setBinaryRetrievable(bool retrievable) { retrievableBinary = retrievable; } | |
GLint getBinaryLength() const; | |
private: | |
void unlink(); | |
void resetUniformBlockBindings(); | |
bool linkVaryings(); | |
bool linkTransformFeedback(); | |
bool linkAttributes(); | |
int getAttributeBinding(const glsl::Attribute &attribute); | |
bool linkUniforms(const Shader *shader); | |
bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader); | |
bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2); | |
bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo); | |
bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block); | |
bool applyUniform(GLint location, float* data); | |
bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v); | |
bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v); | |
bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v); | |
bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v); | |
bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v); | |
bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v); | |
bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v); | |
bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v); | |
bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value); | |
bool applyUniform1iv(GLint location, GLsizei count, const GLint *v); | |
bool applyUniform2iv(GLint location, GLsizei count, const GLint *v); | |
bool applyUniform3iv(GLint location, GLsizei count, const GLint *v); | |
bool applyUniform4iv(GLint location, GLsizei count, const GLint *v); | |
bool applyUniform1uiv(GLint location, GLsizei count, const GLuint *v); | |
bool applyUniform2uiv(GLint location, GLsizei count, const GLuint *v); | |
bool applyUniform3uiv(GLint location, GLsizei count, const GLuint *v); | |
bool applyUniform4uiv(GLint location, GLsizei count, const GLuint *v); | |
bool setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements); | |
bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type); | |
bool setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements); | |
bool setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements); | |
void appendToInfoLog(const char *info, ...); | |
void resetInfoLog(); | |
static unsigned int issueSerial(); | |
private: | |
es2::Device *device; | |
FragmentShader *fragmentShader; | |
VertexShader *vertexShader; | |
sw::PixelShader *pixelBinary; | |
sw::VertexShader *vertexBinary; | |
std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS]; | |
glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS]; | |
int attributeStream[MAX_VERTEX_ATTRIBS]; | |
GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS]; | |
std::vector<std::string> transformFeedbackVaryings; | |
GLenum transformFeedbackBufferMode; | |
size_t totalLinkedVaryingsComponents; | |
struct Sampler | |
{ | |
bool active; | |
GLint logicalTextureUnit; | |
TextureType textureType; | |
}; | |
Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS]; | |
Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS]; | |
typedef std::vector<Uniform*> UniformArray; | |
UniformArray uniforms; | |
typedef std::vector<UniformLocation> UniformIndex; | |
UniformIndex uniformIndex; | |
typedef std::vector<UniformBlock*> UniformBlockArray; | |
UniformBlockArray uniformBlocks; | |
typedef std::vector<LinkedVarying> LinkedVaryingArray; | |
LinkedVaryingArray transformFeedbackLinkedVaryings; | |
bool linked; | |
bool orphaned; // Flag to indicate that the program can be deleted when no longer in use | |
char *infoLog; | |
bool validated; | |
bool retrievableBinary; | |
unsigned int referenceCount; | |
const unsigned int serial; | |
static unsigned int currentSerial; | |
ResourceManager *resourceManager; | |
const GLuint handle; | |
}; | |
} | |
#endif // LIBGLESV2_PROGRAM_H_ |