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++;
} }
} }
......
...@@ -42,7 +42,7 @@ AttributeBindings::~AttributeBindings() ...@@ -42,7 +42,7 @@ AttributeBindings::~AttributeBindings()
} }
Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize) Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize)
: type(type), _name(_name), name(Program::undecorateUniform(_name)), arraySize(arraySize) : type(type), _name(_name), name(ProgramBinary::undecorateUniform(_name)), arraySize(arraySize)
{ {
int bytes = UniformInternalSize(type) * arraySize; int bytes = UniformInternalSize(type) * arraySize;
data = new unsigned char[bytes]; data = new unsigned char[bytes];
...@@ -61,15 +61,13 @@ bool Uniform::isArray() ...@@ -61,15 +61,13 @@ bool Uniform::isArray()
} }
UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index) UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index)
: name(Program::undecorateUniform(_name)), element(element), index(index) : name(ProgramBinary::undecorateUniform(_name)), element(element), index(index)
{ {
} }
Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial()) ProgramBinary::ProgramBinary()
{ {
mDevice = getDevice(); mDevice = getDevice();
mFragmentShader = NULL;
mVertexShader = NULL;
mPixelExecutable = NULL; mPixelExecutable = NULL;
mVertexExecutable = NULL; mVertexExecutable = NULL;
...@@ -79,10 +77,38 @@ Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(man ...@@ -79,10 +77,38 @@ Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(man
mInfoLog = NULL; mInfoLog = NULL;
mValidated = false; mValidated = false;
unlink(); for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mSemanticIndex[index] = -1;
}
mDeleteStatus = false; for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
{
mSamplersPS[index].active = false;
}
for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++)
{
mSamplersVS[index].active = false;
}
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
mDxDepthRangeLocation = -1;
mDxDepthLocation = -1;
mDxCoordLocation = -1;
mDxHalfPixelSizeLocation = -1;
mDxFrontCCWLocation = -1;
mDxPointsOrLinesLocation = -1;
}
Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial())
{
mFragmentShader = NULL;
mVertexShader = NULL;
mProgramBinary = NULL;
mDeleteStatus = false;
mRefCount = 0; mRefCount = 0;
} }
...@@ -101,6 +127,37 @@ Program::~Program() ...@@ -101,6 +127,37 @@ Program::~Program()
} }
} }
ProgramBinary::~ProgramBinary()
{
if (mPixelExecutable)
{
mPixelExecutable->Release();
}
if (mVertexExecutable)
{
mVertexExecutable->Release();
}
if (mConstantTablePS)
{
mConstantTablePS->Release();
}
if (mConstantTableVS)
{
mConstantTableVS->Release();
}
while (!mUniforms.empty())
{
delete mUniforms.back();
mUniforms.pop_back();
}
delete[] mInfoLog;
}
bool Program::attachShader(Shader *shader) bool Program::attachShader(Shader *shader)
{ {
if (shader->getType() == GL_VERTEX_SHADER) if (shader->getType() == GL_VERTEX_SHADER)
...@@ -160,12 +217,12 @@ int Program::getAttachedShadersCount() const ...@@ -160,12 +217,12 @@ int Program::getAttachedShadersCount() const
return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0); return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
} }
IDirect3DPixelShader9 *Program::getPixelShader() IDirect3DPixelShader9 *ProgramBinary::getPixelShader()
{ {
return mPixelExecutable; return mPixelExecutable;
} }
IDirect3DVertexShader9 *Program::getVertexShader() IDirect3DVertexShader9 *ProgramBinary::getVertexShader()
{ {
return mVertexExecutable; return mVertexExecutable;
} }
...@@ -188,7 +245,7 @@ void Program::bindAttributeLocation(GLuint index, const char *name) ...@@ -188,7 +245,7 @@ void Program::bindAttributeLocation(GLuint index, const char *name)
mAttributeBindings.bindAttributeLocation(index, name); mAttributeBindings.bindAttributeLocation(index, name);
} }
GLuint Program::getAttributeLocation(const char *name) GLuint ProgramBinary::getAttributeLocation(const char *name)
{ {
if (name) if (name)
{ {
...@@ -204,7 +261,7 @@ GLuint Program::getAttributeLocation(const char *name) ...@@ -204,7 +261,7 @@ GLuint Program::getAttributeLocation(const char *name)
return -1; return -1;
} }
int Program::getSemanticIndex(int attributeIndex) int ProgramBinary::getSemanticIndex(int attributeIndex)
{ {
ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
...@@ -212,7 +269,7 @@ int Program::getSemanticIndex(int attributeIndex) ...@@ -212,7 +269,7 @@ int Program::getSemanticIndex(int attributeIndex)
} }
// Returns one more than the highest sampler index used. // Returns one more than the highest sampler index used.
GLint Program::getUsedSamplerRange(SamplerType type) GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
{ {
switch (type) switch (type)
{ {
...@@ -228,7 +285,7 @@ GLint Program::getUsedSamplerRange(SamplerType type) ...@@ -228,7 +285,7 @@ GLint Program::getUsedSamplerRange(SamplerType type)
// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler // Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
// index (0-15 for the pixel shader and 0-3 for the vertex shader). // index (0-15 for the pixel shader and 0-3 for the vertex shader).
GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex) GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
{ {
GLint logicalTextureUnit = -1; GLint logicalTextureUnit = -1;
...@@ -263,7 +320,7 @@ GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex) ...@@ -263,7 +320,7 @@ GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
// Returns the texture type for a given Direct3D 9 sampler type and // Returns the texture type for a given Direct3D 9 sampler type and
// index (0-15 for the pixel shader and 0-3 for the vertex shader). // index (0-15 for the pixel shader and 0-3 for the vertex shader).
TextureType Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{ {
switch (type) switch (type)
{ {
...@@ -281,7 +338,7 @@ TextureType Program::getSamplerTextureType(SamplerType type, unsigned int sample ...@@ -281,7 +338,7 @@ TextureType Program::getSamplerTextureType(SamplerType type, unsigned int sample
return TEXTURE_2D; return TEXTURE_2D;
} }
GLint Program::getUniformLocation(std::string name) GLint ProgramBinary::getUniformLocation(std::string name)
{ {
unsigned int subscript = 0; unsigned int subscript = 0;
...@@ -307,7 +364,7 @@ GLint Program::getUniformLocation(std::string name) ...@@ -307,7 +364,7 @@ GLint Program::getUniformLocation(std::string name)
return -1; return -1;
} }
bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -368,7 +425,7 @@ bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) ...@@ -368,7 +425,7 @@ bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
return true; return true;
} }
bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -430,7 +487,7 @@ bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) ...@@ -430,7 +487,7 @@ bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
return true; return true;
} }
bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -491,7 +548,7 @@ bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) ...@@ -491,7 +548,7 @@ bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
return true; return true;
} }
bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -574,7 +631,7 @@ void transposeMatrix(T *target, const GLfloat *value) ...@@ -574,7 +631,7 @@ void transposeMatrix(T *target, const GLfloat *value)
} }
} }
bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -607,7 +664,7 @@ bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat * ...@@ -607,7 +664,7 @@ bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *
return true; return true;
} }
bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -641,7 +698,7 @@ bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat * ...@@ -641,7 +698,7 @@ bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *
} }
bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -674,7 +731,7 @@ bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat * ...@@ -674,7 +731,7 @@ bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *
return true; return true;
} }
bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -728,7 +785,7 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) ...@@ -728,7 +785,7 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
return true; return true;
} }
bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -780,7 +837,7 @@ bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) ...@@ -780,7 +837,7 @@ bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
return true; return true;
} }
bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -832,7 +889,7 @@ bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) ...@@ -832,7 +889,7 @@ bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
return true; return true;
} }
bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -884,7 +941,7 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) ...@@ -884,7 +941,7 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
return true; return true;
} }
bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -953,7 +1010,7 @@ bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) ...@@ -953,7 +1010,7 @@ bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
return true; return true;
} }
bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -1028,7 +1085,7 @@ bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) ...@@ -1028,7 +1085,7 @@ bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
return true; return true;
} }
void Program::dirtyAllUniforms() void ProgramBinary::dirtyAllUniforms()
{ {
unsigned int numUniforms = mUniforms.size(); unsigned int numUniforms = mUniforms.size();
for (unsigned int index = 0; index < numUniforms; index++) for (unsigned int index = 0; index < numUniforms; index++)
...@@ -1038,7 +1095,7 @@ void Program::dirtyAllUniforms() ...@@ -1038,7 +1095,7 @@ void Program::dirtyAllUniforms()
} }
// Applies all the uniforms set for this program object to the Direct3D 9 device // Applies all the uniforms set for this program object to the Direct3D 9 device
void Program::applyUniforms() void ProgramBinary::applyUniforms()
{ {
for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) { for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) {
Uniform *targetUniform = *ub; Uniform *targetUniform = *ub;
...@@ -1079,7 +1136,7 @@ void Program::applyUniforms() ...@@ -1079,7 +1136,7 @@ void Program::applyUniforms()
} }
// Compiles the HLSL code of the attached shaders into executable binaries // Compiles the HLSL code of the attached shaders into executable binaries
ID3D10Blob *Program::compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable) ID3D10Blob *ProgramBinary::compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable)
{ {
if (!hlsl) if (!hlsl)
{ {
...@@ -1153,7 +1210,7 @@ ID3D10Blob *Program::compileToBinary(const char *hlsl, const char *profile, ID3D ...@@ -1153,7 +1210,7 @@ ID3D10Blob *Program::compileToBinary(const char *hlsl, const char *profile, ID3D
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful // Returns the number of used varying registers, or -1 if unsuccesful
int Program::packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader) int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader)
{ {
Context *context = getContext(); Context *context = getContext();
const int maxVaryingVectors = context->getMaximumVaryingVectors(); const int maxVaryingVectors = context->getMaximumVaryingVectors();
...@@ -1301,7 +1358,7 @@ int Program::packVaryings(const Varying *packing[][4], FragmentShader *fragmentS ...@@ -1301,7 +1358,7 @@ int Program::packVaryings(const Varying *packing[][4], FragmentShader *fragmentS
return registers; return registers;
} }
bool Program::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader) bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader)
{ {
if (pixelHLSL.empty() || vertexHLSL.empty()) if (pixelHLSL.empty() || vertexHLSL.empty())
{ {
...@@ -1647,21 +1704,25 @@ bool Program::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, Frag ...@@ -1647,21 +1704,25 @@ bool Program::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, Frag
// a list of uniforms // a list of uniforms
void Program::link() void Program::link()
{ {
link(mAttributeBindings, mFragmentShader, mVertexShader); unlink(false);
mProgramBinary = new ProgramBinary;
if (!mProgramBinary->link(mAttributeBindings, mFragmentShader, mVertexShader))
{
unlink(false);
}
} }
void Program::link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{ {
unlink();
if (!fragmentShader || !fragmentShader->isCompiled()) if (!fragmentShader || !fragmentShader->isCompiled())
{ {
return; return false;
} }
if (!vertexShader || !vertexShader->isCompiled()) if (!vertexShader || !vertexShader->isCompiled())
{ {
return; return false;
} }
std::string pixelHLSL = fragmentShader->getHLSL(); std::string pixelHLSL = fragmentShader->getHLSL();
...@@ -1669,7 +1730,7 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f ...@@ -1669,7 +1730,7 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f
if (!linkVaryings(pixelHLSL, vertexHLSL, fragmentShader, vertexShader)) if (!linkVaryings(pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
{ {
return; return false;
} }
Context *context = getContext(); Context *context = getContext();
...@@ -1686,7 +1747,7 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f ...@@ -1686,7 +1747,7 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f
if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY) if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY)
{ {
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY, false);
} }
ASSERT(SUCCEEDED(vertexResult) && SUCCEEDED(pixelResult)); ASSERT(SUCCEEDED(vertexResult) && SUCCEEDED(pixelResult));
...@@ -1700,17 +1761,17 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f ...@@ -1700,17 +1761,17 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f
{ {
if (!linkAttributes(attributeBindings, fragmentShader, vertexShader)) if (!linkAttributes(attributeBindings, fragmentShader, vertexShader))
{ {
return; return false;
} }
if (!linkUniforms(GL_FRAGMENT_SHADER, mConstantTablePS)) if (!linkUniforms(GL_FRAGMENT_SHADER, mConstantTablePS))
{ {
return; return false;
} }
if (!linkUniforms(GL_VERTEX_SHADER, mConstantTableVS)) if (!linkUniforms(GL_VERTEX_SHADER, mConstantTableVS))
{ {
return; return false;
} }
// these uniforms are searched as already-decorated because gl_ and dx_ // these uniforms are searched as already-decorated because gl_ and dx_
...@@ -1724,18 +1785,20 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f ...@@ -1724,18 +1785,20 @@ void Program::link(const AttributeBindings &attributeBindings, FragmentShader *f
context->markDxUniformsDirty(); context->markDxUniformsDirty();
mLinked = true; // Success return true;
} }
} }
return false;
} }
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
bool Program::linkAttributes(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{ {
unsigned int usedLocations = 0; unsigned int usedLocations = 0;
// Link attributes that have a binding location // Link attributes that have a binding location
for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++) for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
{ {
int location = attributeBindings.getAttributeBinding(attribute->name); int location = attributeBindings.getAttributeBinding(attribute->name);
...@@ -1765,7 +1828,7 @@ bool Program::linkAttributes(const AttributeBindings &attributeBindings, Fragmen ...@@ -1765,7 +1828,7 @@ bool Program::linkAttributes(const AttributeBindings &attributeBindings, Fragmen
} }
// Link attributes that don't have a binding location // Link attributes that don't have a binding location
for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++) for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
{ {
int location = attributeBindings.getAttributeBinding(attribute->name); int location = attributeBindings.getAttributeBinding(attribute->name);
...@@ -1787,7 +1850,7 @@ bool Program::linkAttributes(const AttributeBindings &attributeBindings, Fragmen ...@@ -1787,7 +1850,7 @@ bool Program::linkAttributes(const AttributeBindings &attributeBindings, Fragmen
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
{ {
int index = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name); int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1); int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1);
for (int r = 0; r < rows; r++) for (int r = 0; r < rows; r++)
...@@ -1812,7 +1875,7 @@ int AttributeBindings::getAttributeBinding(const std::string &name) const ...@@ -1812,7 +1875,7 @@ int AttributeBindings::getAttributeBinding(const std::string &name) const
return -1; return -1;
} }
bool Program::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable) bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable)
{ {
D3DXCONSTANTTABLE_DESC constantTableDescription; D3DXCONSTANTTABLE_DESC constantTableDescription;
...@@ -1838,7 +1901,7 @@ bool Program::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable) ...@@ -1838,7 +1901,7 @@ bool Program::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable)
// Adds the description of a constant found in the binary shader to the list of uniforms // Adds the description of a constant found in the binary shader to the list of uniforms
// Returns true if succesful (uniform not already defined) // Returns true if succesful (uniform not already defined)
bool Program::defineUniform(GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name) bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name)
{ {
if (constantDescription.RegisterSet == D3DXRS_SAMPLER) if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{ {
...@@ -1923,7 +1986,7 @@ bool Program::defineUniform(GLenum shader, const D3DXHANDLE &constantHandle, con ...@@ -1923,7 +1986,7 @@ bool Program::defineUniform(GLenum shader, const D3DXHANDLE &constantHandle, con
} }
} }
bool Program::defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) bool ProgramBinary::defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &_name)
{ {
Uniform *uniform = createUniform(constantDescription, _name); Uniform *uniform = createUniform(constantDescription, _name);
...@@ -1961,7 +2024,7 @@ bool Program::defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDesc ...@@ -1961,7 +2024,7 @@ bool Program::defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDesc
return true; return true;
} }
Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) Uniform *ProgramBinary::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name)
{ {
if (constantDescription.Rows == 1) // Vectors and scalars if (constantDescription.Rows == 1) // Vectors and scalars
{ {
...@@ -2037,7 +2100,7 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, co ...@@ -2037,7 +2100,7 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, co
} }
// This method needs to match OutputHLSL::decorate // This method needs to match OutputHLSL::decorate
std::string Program::decorateAttribute(const std::string &name) std::string ProgramBinary::decorateAttribute(const std::string &name)
{ {
if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0) if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
{ {
...@@ -2047,7 +2110,7 @@ std::string Program::decorateAttribute(const std::string &name) ...@@ -2047,7 +2110,7 @@ std::string Program::decorateAttribute(const std::string &name)
return name; return name;
} }
std::string Program::undecorateUniform(const std::string &_name) std::string ProgramBinary::undecorateUniform(const std::string &_name)
{ {
std::string name = _name; std::string name = _name;
...@@ -2071,7 +2134,7 @@ std::string Program::undecorateUniform(const std::string &_name) ...@@ -2071,7 +2134,7 @@ std::string Program::undecorateUniform(const std::string &_name)
return name; return name;
} }
void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v) void ProgramBinary::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v)
{ {
float vector[D3D9_MAX_FLOAT_CONSTANTS * 4]; float vector[D3D9_MAX_FLOAT_CONSTANTS * 4];
BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS]; BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS];
...@@ -2128,7 +2191,7 @@ void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, ...@@ -2128,7 +2191,7 @@ void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width,
} }
} }
bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v) bool ProgramBinary::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
{ {
if (targetUniform->ps.registerCount) if (targetUniform->ps.registerCount)
{ {
...@@ -2143,7 +2206,7 @@ bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v) ...@@ -2143,7 +2206,7 @@ bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
return true; return true;
} }
bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v) bool ProgramBinary::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v)
{ {
ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
...@@ -2204,7 +2267,7 @@ bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint ...@@ -2204,7 +2267,7 @@ bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint
return true; return true;
} }
bool Program::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v) bool ProgramBinary::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v)
{ {
ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
...@@ -2221,7 +2284,7 @@ bool Program::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint ...@@ -2221,7 +2284,7 @@ bool Program::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint
return true; return true;
} }
bool Program::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v) bool ProgramBinary::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v)
{ {
ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
...@@ -2238,7 +2301,7 @@ bool Program::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint ...@@ -2238,7 +2301,7 @@ bool Program::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint
return true; return true;
} }
bool Program::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v) bool ProgramBinary::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v)
{ {
ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
...@@ -2255,7 +2318,7 @@ bool Program::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint ...@@ -2255,7 +2318,7 @@ bool Program::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint
return true; return true;
} }
void Program::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector) void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector)
{ {
if (targetUniform->ps.registerCount) if (targetUniform->ps.registerCount)
{ {
...@@ -2273,7 +2336,7 @@ void Program::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXV ...@@ -2273,7 +2336,7 @@ void Program::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXV
// append a santized message to the program info log. // append a santized message to the program info log.
// The D3D compiler includes a fake file path in some of the warning or error // The D3D compiler includes a fake file path in some of the warning or error
// messages, so lets remove all occurrences of this fake file path from the log. // messages, so lets remove all occurrences of this fake file path from the log.
void Program::appendToInfoLogSanitized(const char *message) void ProgramBinary::appendToInfoLogSanitized(const char *message)
{ {
std::string msg(message); std::string msg(message);
...@@ -2291,7 +2354,7 @@ void Program::appendToInfoLogSanitized(const char *message) ...@@ -2291,7 +2354,7 @@ void Program::appendToInfoLogSanitized(const char *message)
appendToInfoLog("%s\n", msg.c_str()); appendToInfoLog("%s\n", msg.c_str());
} }
void Program::appendToInfoLog(const char *format, ...) void ProgramBinary::appendToInfoLog(const char *format, ...)
{ {
if (!format) if (!format)
{ {
...@@ -2324,7 +2387,7 @@ void Program::appendToInfoLog(const char *format, ...) ...@@ -2324,7 +2387,7 @@ void Program::appendToInfoLog(const char *format, ...)
} }
} }
void Program::resetInfoLog() void ProgramBinary::resetInfoLog()
{ {
if (mInfoLog) if (mInfoLog)
{ {
...@@ -2351,76 +2414,19 @@ void Program::unlink(bool destroy) ...@@ -2351,76 +2414,19 @@ void Program::unlink(bool destroy)
} }
} }
if (mPixelExecutable) if (mProgramBinary)
{
mPixelExecutable->Release();
mPixelExecutable = NULL;
}
if (mVertexExecutable)
{
mVertexExecutable->Release();
mVertexExecutable = NULL;
}
if (mConstantTablePS)
{ {
mConstantTablePS->Release(); delete mProgramBinary;
mConstantTablePS = NULL; mProgramBinary = NULL;
} }
if (mConstantTableVS)
{
mConstantTableVS->Release();
mConstantTableVS = NULL;
}
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mLinkedAttribute[index].name.clear();
mSemanticIndex[index] = -1;
}
for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
{
mSamplersPS[index].active = false;
}
for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++)
{
mSamplersVS[index].active = false;
}
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
while (!mUniforms.empty())
{
delete mUniforms.back();
mUniforms.pop_back();
}
mDxDepthRangeLocation = -1;
mDxDepthLocation = -1;
mDxCoordLocation = -1;
mDxHalfPixelSizeLocation = -1;
mDxFrontCCWLocation = -1;
mDxPointsOrLinesLocation = -1;
mUniformIndex.clear();
delete[] mInfoLog;
mInfoLog = NULL;
mLinked = false;
} }
bool Program::isLinked() ProgramBinary* Program::getProgramBinary()
{ {
return mLinked; return mProgramBinary;
} }
bool Program::isValidated() const bool ProgramBinary::isValidated() const
{ {
return mValidated; return mValidated;
} }
...@@ -2455,7 +2461,7 @@ unsigned int Program::issueSerial() ...@@ -2455,7 +2461,7 @@ unsigned int Program::issueSerial()
return mCurrentSerial++; return mCurrentSerial++;
} }
int Program::getInfoLogLength() const int ProgramBinary::getInfoLogLength() const
{ {
if (!mInfoLog) if (!mInfoLog)
{ {
...@@ -2467,7 +2473,19 @@ int Program::getInfoLogLength() const ...@@ -2467,7 +2473,19 @@ int Program::getInfoLogLength() const
} }
} }
void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) int Program::getInfoLogLength() const
{
if (mProgramBinary)
{
return mProgramBinary->getInfoLogLength();
}
else
{
return 0;
}
}
void ProgramBinary::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{ {
int index = 0; int index = 0;
...@@ -2488,6 +2506,26 @@ void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) ...@@ -2488,6 +2506,26 @@ void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
} }
} }
void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
if (mProgramBinary)
{
return mProgramBinary->getInfoLog(bufSize, length, infoLog);
}
else
{
if (bufSize > 0)
{
infoLog[0] = '\0';
}
if (length)
{
*length = 0;
}
}
}
void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
{ {
int total = 0; int total = 0;
...@@ -2518,7 +2556,7 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade ...@@ -2518,7 +2556,7 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade
} }
} }
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{ {
// Skip over inactive attributes // Skip over inactive attributes
unsigned int activeAttribute = 0; unsigned int activeAttribute = 0;
...@@ -2556,7 +2594,30 @@ void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, ...@@ -2556,7 +2594,30 @@ void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length,
*type = mLinkedAttribute[attribute].type; *type = mLinkedAttribute[attribute].type;
} }
GLint Program::getActiveAttributeCount() void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
if (mProgramBinary)
{
mProgramBinary->getActiveAttribute(index, bufsize, length, size, type, name);
}
else
{
if (bufsize > 0)
{
name[0] = '\0';
}
if (length)
{
*length = 0;
}
*type = GL_NONE;
*size = 1;
}
}
GLint ProgramBinary::getActiveAttributeCount()
{ {
int count = 0; int count = 0;
...@@ -2571,7 +2632,19 @@ GLint Program::getActiveAttributeCount() ...@@ -2571,7 +2632,19 @@ GLint Program::getActiveAttributeCount()
return count; return count;
} }
GLint Program::getActiveAttributeMaxLength() GLint Program::getActiveAttributeCount()
{
if (mProgramBinary)
{
return mProgramBinary->getActiveAttributeCount();
}
else
{
return 0;
}
}
GLint ProgramBinary::getActiveAttributeMaxLength()
{ {
int maxLength = 0; int maxLength = 0;
...@@ -2586,7 +2659,19 @@ GLint Program::getActiveAttributeMaxLength() ...@@ -2586,7 +2659,19 @@ GLint Program::getActiveAttributeMaxLength()
return maxLength; return maxLength;
} }
void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) GLint Program::getActiveAttributeMaxLength()
{
if (mProgramBinary)
{
return mProgramBinary->getActiveAttributeMaxLength();
}
else
{
return 0;
}
}
void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{ {
// Skip over internal uniforms // Skip over internal uniforms
unsigned int activeUniform = 0; unsigned int activeUniform = 0;
...@@ -2631,7 +2716,30 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G ...@@ -2631,7 +2716,30 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G
*type = mUniforms[uniform]->type; *type = mUniforms[uniform]->type;
} }
GLint Program::getActiveUniformCount() void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
if (mProgramBinary)
{
return mProgramBinary->getActiveUniform(index, bufsize, length, size, type, name);
}
else
{
if (bufsize > 0)
{
name[0] = '\0';
}
if (length)
{
*length = 0;
}
*size = 0;
*type = GL_NONE;
}
}
GLint ProgramBinary::getActiveUniformCount()
{ {
int count = 0; int count = 0;
...@@ -2647,7 +2755,19 @@ GLint Program::getActiveUniformCount() ...@@ -2647,7 +2755,19 @@ GLint Program::getActiveUniformCount()
return count; return count;
} }
GLint Program::getActiveUniformMaxLength() GLint Program::getActiveUniformCount()
{
if (mProgramBinary)
{
return mProgramBinary->getActiveUniformCount();
}
else
{
return 0;
}
}
GLint ProgramBinary::getActiveUniformMaxLength()
{ {
int maxLength = 0; int maxLength = 0;
...@@ -2668,6 +2788,18 @@ GLint Program::getActiveUniformMaxLength() ...@@ -2668,6 +2788,18 @@ GLint Program::getActiveUniformMaxLength()
return maxLength; return maxLength;
} }
GLint Program::getActiveUniformMaxLength()
{
if (mProgramBinary)
{
return mProgramBinary->getActiveUniformMaxLength();
}
else
{
return 0;
}
}
void Program::flagForDeletion() void Program::flagForDeletion()
{ {
mDeleteStatus = true; mDeleteStatus = true;
...@@ -2678,17 +2810,22 @@ bool Program::isFlaggedForDeletion() const ...@@ -2678,17 +2810,22 @@ bool Program::isFlaggedForDeletion() const
return mDeleteStatus; return mDeleteStatus;
} }
void Program::validate() bool Program::isValidated() const
{ {
resetInfoLog(); if (mProgramBinary)
if (!isLinked())
{ {
appendToInfoLog("Program has not been successfully linked."); return mProgramBinary->isValidated();
mValidated = false;
} }
else else
{ {
return false;
}
}
void ProgramBinary::validate()
{
resetInfoLog();
applyUniforms(); applyUniforms();
if (!validateSamplers(true)) if (!validateSamplers(true))
{ {
...@@ -2698,10 +2835,9 @@ void Program::validate() ...@@ -2698,10 +2835,9 @@ void Program::validate()
{ {
mValidated = true; mValidated = true;
} }
}
} }
bool Program::validateSamplers(bool logErrors) bool ProgramBinary::validateSamplers(bool logErrors)
{ {
// if any two active samplers in a program are of different types, but refer to the same // if any two active samplers in a program are of different types, but refer to the same
// texture image unit, and this is the current program, then ValidateProgram will fail, and // texture image unit, and this is the current program, then ValidateProgram will fail, and
...@@ -2788,32 +2924,32 @@ bool Program::validateSamplers(bool logErrors) ...@@ -2788,32 +2924,32 @@ bool Program::validateSamplers(bool logErrors)
return true; return true;
} }
GLint Program::getDxDepthRangeLocation() const GLint ProgramBinary::getDxDepthRangeLocation() const
{ {
return mDxDepthRangeLocation; return mDxDepthRangeLocation;
} }
GLint Program::getDxDepthLocation() const GLint ProgramBinary::getDxDepthLocation() const
{ {
return mDxDepthLocation; return mDxDepthLocation;
} }
GLint Program::getDxCoordLocation() const GLint ProgramBinary::getDxCoordLocation() const
{ {
return mDxCoordLocation; return mDxCoordLocation;
} }
GLint Program::getDxHalfPixelSizeLocation() const GLint ProgramBinary::getDxHalfPixelSizeLocation() const
{ {
return mDxHalfPixelSizeLocation; return mDxHalfPixelSizeLocation;
} }
GLint Program::getDxFrontCCWLocation() const GLint ProgramBinary::getDxFrontCCWLocation() const
{ {
return mDxFrontCCWLocation; return mDxFrontCCWLocation;
} }
GLint Program::getDxPointsOrLinesLocation() const GLint ProgramBinary::getDxPointsOrLinesLocation() const
{ {
return mDxPointsOrLinesLocation; return mDxPointsOrLinesLocation;
} }
......
...@@ -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
......
...@@ -2937,12 +2937,13 @@ int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) ...@@ -2937,12 +2937,13 @@ int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
} }
} }
if (!programObject->isLinked()) gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{ {
return error(GL_INVALID_OPERATION, -1); return error(GL_INVALID_OPERATION, -1);
} }
return programObject->getAttributeLocation(name); return programBinary->getAttributeLocation(name);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -3396,7 +3397,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) ...@@ -3396,7 +3397,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
*params = programObject->isFlaggedForDeletion(); *params = programObject->isFlaggedForDeletion();
return; return;
case GL_LINK_STATUS: case GL_LINK_STATUS:
*params = programObject->isLinked(); *params = programObject->getProgramBinary() != NULL;
return; return;
case GL_VALIDATE_STATUS: case GL_VALIDATE_STATUS:
*params = programObject->isValidated(); *params = programObject->isValidated();
...@@ -3944,12 +3945,18 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz ...@@ -3944,12 +3945,18 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz
gl::Program *programObject = context->getProgram(program); gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked()) if (!programObject)
{
return error(GL_INVALID_OPERATION);
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!programObject->getUniformfv(location, &bufSize, params)) if (!programBinary->getUniformfv(location, &bufSize, params))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -3978,12 +3985,18 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) ...@@ -3978,12 +3985,18 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
gl::Program *programObject = context->getProgram(program); gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked()) if (!programObject)
{
return error(GL_INVALID_OPERATION);
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!programObject->getUniformfv(location, NULL, params)) if (!programBinary->getUniformfv(location, NULL, params))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -4018,17 +4031,18 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz ...@@ -4018,17 +4031,18 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz
gl::Program *programObject = context->getProgram(program); gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked()) if (!programObject)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!programObject) gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!programObject->getUniformiv(location, &bufSize, params)) if (!programBinary->getUniformiv(location, &bufSize, params))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -4057,17 +4071,18 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) ...@@ -4057,17 +4071,18 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
gl::Program *programObject = context->getProgram(program); gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked()) if (!programObject)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!programObject) gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!programObject->getUniformiv(location, NULL, params)) if (!programBinary->getUniformiv(location, NULL, params))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -4108,12 +4123,13 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) ...@@ -4108,12 +4123,13 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
} }
} }
if (!programObject->isLinked()) gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{ {
return error(GL_INVALID_OPERATION, -1); return error(GL_INVALID_OPERATION, -1);
} }
return programObject->getUniformLocation(name); return programBinary->getUniformLocation(name);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -5844,7 +5860,13 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) ...@@ -5844,7 +5860,13 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform1fv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform1fv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -5888,7 +5910,13 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) ...@@ -5888,7 +5910,13 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform1iv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform1iv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -5934,7 +5962,13 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) ...@@ -5934,7 +5962,13 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform2fv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform2fv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -5980,7 +6014,13 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) ...@@ -5980,7 +6014,13 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform2iv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform2iv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6026,7 +6066,13 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) ...@@ -6026,7 +6066,13 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform3fv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform3fv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6072,7 +6118,13 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) ...@@ -6072,7 +6118,13 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform3iv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform3iv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6118,7 +6170,13 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) ...@@ -6118,7 +6170,13 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform4fv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform4fv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6164,7 +6222,13 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) ...@@ -6164,7 +6222,13 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniform4iv(location, count, v)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform4iv(location, count, v))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6204,7 +6268,13 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans ...@@ -6204,7 +6268,13 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniformMatrix2fv(location, count, value)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniformMatrix2fv(location, count, value))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6244,7 +6314,13 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans ...@@ -6244,7 +6314,13 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniformMatrix3fv(location, count, value)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniformMatrix3fv(location, count, value))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6284,7 +6360,13 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans ...@@ -6284,7 +6360,13 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if (!program->setUniformMatrix4fv(location, count, value)) gl::ProgramBinary *programBinary = program->getProgramBinary();
if (!programBinary)
{
return error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniformMatrix4fv(location, count, value))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6320,7 +6402,7 @@ void __stdcall glUseProgram(GLuint program) ...@@ -6320,7 +6402,7 @@ void __stdcall glUseProgram(GLuint program)
} }
} }
if (program != 0 && !programObject->isLinked()) if (program != 0 && !programObject->getProgramBinary())
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -6358,7 +6440,13 @@ void __stdcall glValidateProgram(GLuint program) ...@@ -6358,7 +6440,13 @@ void __stdcall glValidateProgram(GLuint program)
} }
} }
programObject->validate(); gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
return;
}
programBinary->validate();
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
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