Commit e2a59bba by apatrick@chromium.org

Refactor Program into Program and ProgramBinary.

Program manages the state and lifetime of the program object. ProgramBinary holds the linked program and the code to do the linking. There should be no functional change. WebGL conformance tests did not regress. Review URL: https://codereview.appspot.com/6267047 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1143 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 9a30b095
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 1141 #define BUILD_REVISION 1143
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -1991,26 +1991,27 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -1991,26 +1991,27 @@ bool Context::applyRenderTarget(bool ignoreViewport)
if (mState.currentProgram && mDxUniformsDirty) if (mState.currentProgram && mDxUniformsDirty)
{ {
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
ProgramBinary *programBinary = programObject->getProgramBinary();
GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation(); GLint halfPixelSize = programBinary->getDxHalfPixelSizeLocation();
GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height}; GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height};
programObject->setUniform2fv(halfPixelSize, 1, xy); programBinary->setUniform2fv(halfPixelSize, 1, xy);
// These values are used for computing gl_FragCoord in Program::linkVaryings(). The approach depends on Shader Model 3.0 support. // These values are used for computing gl_FragCoord in Program::linkVaryings(). The approach depends on Shader Model 3.0 support.
GLint coord = programObject->getDxCoordLocation(); GLint coord = programBinary->getDxCoordLocation();
float h = mSupportsShaderModel3 ? mRenderTargetDesc.Height : mState.viewportHeight / 2.0f; float h = mSupportsShaderModel3 ? mRenderTargetDesc.Height : mState.viewportHeight / 2.0f;
GLfloat whxy[4] = {mState.viewportWidth / 2.0f, h, GLfloat whxy[4] = {mState.viewportWidth / 2.0f, h,
(float)mState.viewportX + mState.viewportWidth / 2.0f, (float)mState.viewportX + mState.viewportWidth / 2.0f,
(float)mState.viewportY + mState.viewportHeight / 2.0f}; (float)mState.viewportY + mState.viewportHeight / 2.0f};
programObject->setUniform4fv(coord, 1, whxy); programBinary->setUniform4fv(coord, 1, whxy);
GLint depth = programObject->getDxDepthLocation(); GLint depth = programBinary->getDxDepthLocation();
GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f}; GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f};
programObject->setUniform2fv(depth, 1, dz); programBinary->setUniform2fv(depth, 1, dz);
GLint depthRange = programObject->getDxDepthRangeLocation(); GLint depthRange = programBinary->getDxDepthRangeLocation();
GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
programObject->setUniform3fv(depthRange, 1, nearFarDiff); programBinary->setUniform3fv(depthRange, 1, nearFarDiff);
mDxUniformsDirty = false; mDxUniformsDirty = false;
} }
...@@ -2021,18 +2022,19 @@ bool Context::applyRenderTarget(bool ignoreViewport) ...@@ -2021,18 +2022,19 @@ bool Context::applyRenderTarget(bool ignoreViewport)
void Context::applyState(GLenum drawMode) void Context::applyState(GLenum drawMode)
{ {
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
ProgramBinary *programBinary = programObject->getProgramBinary();
Framebuffer *framebufferObject = getDrawFramebuffer(); Framebuffer *framebufferObject = getDrawFramebuffer();
GLenum adjustedFrontFace = adjustWinding(mState.frontFace); GLenum adjustedFrontFace = adjustWinding(mState.frontFace);
GLint frontCCW = programObject->getDxFrontCCWLocation(); GLint frontCCW = programBinary->getDxFrontCCWLocation();
GLint ccw = (adjustedFrontFace == GL_CCW); GLint ccw = (adjustedFrontFace == GL_CCW);
programObject->setUniform1iv(frontCCW, 1, &ccw); programBinary->setUniform1iv(frontCCW, 1, &ccw);
GLint pointsOrLines = programObject->getDxPointsOrLinesLocation(); GLint pointsOrLines = programBinary->getDxPointsOrLinesLocation();
GLint alwaysFront = !isTriangleMode(drawMode); GLint alwaysFront = !isTriangleMode(drawMode);
programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront); programBinary->setUniform1iv(pointsOrLines, 1, &alwaysFront);
D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier(); D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
bool zeroColorMaskAllowed = identifier->VendorId != 0x1002; bool zeroColorMaskAllowed = identifier->VendorId != 0x1002;
...@@ -2311,18 +2313,20 @@ GLenum Context::applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mo ...@@ -2311,18 +2313,20 @@ GLenum Context::applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mo
void Context::applyShaders() void Context::applyShaders()
{ {
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
ProgramBinary *programBinary = programObject->getProgramBinary();
if (programObject->getSerial() != mAppliedProgramSerial) if (programObject->getSerial() != mAppliedProgramSerial)
{ {
IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader(); IDirect3DVertexShader9 *vertexShader = programBinary->getVertexShader();
IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader(); IDirect3DPixelShader9 *pixelShader = programBinary->getPixelShader();
mDevice->SetPixelShader(pixelShader); mDevice->SetPixelShader(pixelShader);
mDevice->SetVertexShader(vertexShader); mDevice->SetVertexShader(vertexShader);
programObject->dirtyAllUniforms(); programBinary->dirtyAllUniforms();
mAppliedProgramSerial = programObject->getSerial(); mAppliedProgramSerial = programObject->getSerial();
} }
programObject->applyUniforms(); programBinary->applyUniforms();
} }
// Applies the textures and sampler states to the Direct3D 9 device // Applies the textures and sampler states to the Direct3D 9 device
...@@ -2342,20 +2346,21 @@ void Context::applyTextures() ...@@ -2342,20 +2346,21 @@ void Context::applyTextures()
void Context::applyTextures(SamplerType type) void Context::applyTextures(SamplerType type)
{ {
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
ProgramBinary *programBinary = programObject->getProgramBinary();
int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; // Range of Direct3D 9 samplers of given sampler type int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; // Range of Direct3D 9 samplers of given sampler type
unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS; unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS;
int d3dSamplerOffset = (type == SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSamplerOffset = (type == SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
int samplerRange = programObject->getUsedSamplerRange(type); int samplerRange = programBinary->getUsedSamplerRange(type);
for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
{ {
int textureUnit = programObject->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index int textureUnit = programBinary->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index
int d3dSampler = samplerIndex + d3dSamplerOffset; int d3dSampler = samplerIndex + d3dSamplerOffset;
if (textureUnit != -1) if (textureUnit != -1)
{ {
TextureType textureType = programObject->getSamplerTextureType(type, samplerIndex); TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
Texture *texture = getSamplerTexture(textureUnit, textureType); Texture *texture = getSamplerTexture(textureUnit, textureType);
unsigned int texSerial = texture->getTextureSerial(); unsigned int texSerial = texture->getTextureSerial();
...@@ -2986,7 +2991,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan ...@@ -2986,7 +2991,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
applyShaders(); applyShaders();
applyTextures(); applyTextures();
if (!getCurrentProgram()->validateSamplers(false)) if (!getCurrentProgram()->getProgramBinary()->validateSamplers(false))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -3076,7 +3081,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid ...@@ -3076,7 +3081,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
applyShaders(); applyShaders();
applyTextures(); applyTextures();
if (!getCurrentProgram()->validateSamplers(false)) if (!getCurrentProgram()->getProgramBinary()->validateSamplers(false))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -4165,6 +4170,8 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl ...@@ -4165,6 +4170,8 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0]; D3DVERTEXELEMENT9 *element = &elements[0];
ProgramBinary *programBinary = program->getProgramBinary();
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{ {
if (attributes[i].active) if (attributes[i].active)
...@@ -4220,7 +4227,7 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl ...@@ -4220,7 +4227,7 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl
element->Type = attributes[i].type; element->Type = attributes[i].type;
element->Method = D3DDECLMETHOD_DEFAULT; element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD; element->Usage = D3DDECLUSAGE_TEXCOORD;
element->UsageIndex = program->getSemanticIndex(i); element->UsageIndex = programBinary->getSemanticIndex(i);
element++; element++;
} }
} }
......
...@@ -100,21 +100,16 @@ struct UniformLocation ...@@ -100,21 +100,16 @@ struct UniformLocation
unsigned int index; unsigned int index;
}; };
class Program // This is the result of linking a program. It is the state that would be passed to ProgramBinary.
class ProgramBinary
{ {
public: public:
Program(ResourceManager *manager, GLuint handle); ProgramBinary();
~ProgramBinary();
~Program();
bool attachShader(Shader *shader);
bool detachShader(Shader *shader);
int getAttachedShadersCount() const;
IDirect3DPixelShader9 *getPixelShader(); IDirect3DPixelShader9 *getPixelShader();
IDirect3DVertexShader9 *getVertexShader(); IDirect3DVertexShader9 *getVertexShader();
void bindAttributeLocation(GLuint index, const char *name);
GLuint getAttributeLocation(const char *name); GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex); int getSemanticIndex(int attributeIndex);
...@@ -148,9 +143,7 @@ class Program ...@@ -148,9 +143,7 @@ class Program
void dirtyAllUniforms(); void dirtyAllUniforms();
void applyUniforms(); void applyUniforms();
void link(); bool link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
void link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
bool isLinked();
int getInfoLogLength() const; int getInfoLogLength() const;
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
...@@ -163,26 +156,17 @@ class Program ...@@ -163,26 +156,17 @@ class Program
GLint getActiveUniformCount(); GLint getActiveUniformCount();
GLint getActiveUniformMaxLength(); GLint getActiveUniformMaxLength();
void addRef();
void release();
unsigned int getRefCount() const;
void flagForDeletion();
bool isFlaggedForDeletion() const;
void validate(); void validate();
bool validateSamplers(bool logErrors); bool validateSamplers(bool logErrors);
bool isValidated() const; bool isValidated() const;
unsigned int getSerial() const;
static std::string decorateAttribute(const std::string &name); // Prepend an underscore static std::string decorateAttribute(const std::string &name); // Prepend an underscore
static std::string undecorateUniform(const std::string &_name); // Remove leading underscore static std::string undecorateUniform(const std::string &_name); // Remove leading underscore
private: private:
DISALLOW_COPY_AND_ASSIGN(Program); DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
ID3D10Blob *compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable); ID3D10Blob *compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable);
void unlink(bool destroy = false);
int packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader); int packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader);
bool linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader); bool linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader);
...@@ -208,15 +192,14 @@ class Program ...@@ -208,15 +192,14 @@ class Program
static unsigned int issueSerial(); static unsigned int issueSerial();
IDirect3DDevice9 *mDevice; IDirect3DDevice9 *mDevice;
FragmentShader *mFragmentShader;
VertexShader *mVertexShader;
IDirect3DPixelShader9 *mPixelExecutable; IDirect3DPixelShader9 *mPixelExecutable;
IDirect3DVertexShader9 *mVertexExecutable; IDirect3DVertexShader9 *mVertexExecutable;
// These are only used during linking.
ID3DXConstantTable *mConstantTablePS; ID3DXConstantTable *mConstantTablePS;
ID3DXConstantTable *mConstantTableVS; ID3DXConstantTable *mConstantTableVS;
AttributeBindings mAttributeBindings;
Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS];
...@@ -244,10 +227,62 @@ class Program ...@@ -244,10 +227,62 @@ class Program
GLint mDxFrontCCWLocation; GLint mDxFrontCCWLocation;
GLint mDxPointsOrLinesLocation; GLint mDxPointsOrLinesLocation;
bool mLinked;
bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
char *mInfoLog; char *mInfoLog;
bool mValidated; bool mValidated;
};
class Program
{
public:
Program(ResourceManager *manager, GLuint handle);
~Program();
bool attachShader(Shader *shader);
bool detachShader(Shader *shader);
int getAttachedShadersCount() const;
void bindAttributeLocation(GLuint index, const char *name);
void link();
ProgramBinary *getProgramBinary();
int 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);
GLint getActiveAttributeCount();
GLint getActiveAttributeMaxLength();
void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLint getActiveUniformCount();
GLint getActiveUniformMaxLength();
void addRef();
void release();
unsigned int getRefCount() const;
void flagForDeletion();
bool isFlaggedForDeletion() const;
bool isValidated() const;
unsigned int getSerial() const;
private:
DISALLOW_COPY_AND_ASSIGN(Program);
void unlink(bool destroy = false);
static unsigned int issueSerial();
FragmentShader *mFragmentShader;
VertexShader *mVertexShader;
AttributeBindings mAttributeBindings;
ProgramBinary* mProgramBinary;
bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
unsigned int mRefCount; unsigned int mRefCount;
......
...@@ -42,7 +42,7 @@ typedef std::list<Varying> VaryingList; ...@@ -42,7 +42,7 @@ typedef std::list<Varying> VaryingList;
class Shader class Shader
{ {
friend Program; friend class ProgramBinary;
public: public:
Shader(ResourceManager *manager, GLuint handle); Shader(ResourceManager *manager, GLuint handle);
...@@ -128,7 +128,7 @@ typedef std::vector<Attribute> AttributeArray; ...@@ -128,7 +128,7 @@ typedef std::vector<Attribute> AttributeArray;
class VertexShader : public Shader class VertexShader : public Shader
{ {
friend Program; friend class ProgramBinary;
public: public:
VertexShader(ResourceManager *manager, GLuint handle); VertexShader(ResourceManager *manager, GLuint handle);
......
...@@ -128,10 +128,11 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat ...@@ -128,10 +128,11 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
const VertexAttributeArray &attribs = mContext->getVertexAttributes(); const VertexAttributeArray &attribs = mContext->getVertexAttributes();
Program *program = mContext->getCurrentProgram(); Program *program = mContext->getCurrentProgram();
ProgramBinary *programBinary = program->getProgramBinary();
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
translated[attributeIndex].active = (program->getSemanticIndex(attributeIndex) != -1); translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
} }
// Determine the required storage size per used buffer, and invalidate static buffers that don't contain matching attributes // Determine the required storage size per used buffer, and invalidate static buffers that don't contain matching attributes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment