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
diff --git a/src/common/version.h b/src/common/version.h
index 13132d7..dc785b1 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
#define MAJOR_VERSION 1
#define MINOR_VERSION 0
#define BUILD_VERSION 0
-#define BUILD_REVISION 1141
+#define BUILD_REVISION 1143
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 862ddaa..4d5f8a7 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1991,26 +1991,27 @@
if (mState.currentProgram && mDxUniformsDirty)
{
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};
- 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.
- GLint coord = programObject->getDxCoordLocation();
+ GLint coord = programBinary->getDxCoordLocation();
float h = mSupportsShaderModel3 ? mRenderTargetDesc.Height : mState.viewportHeight / 2.0f;
GLfloat whxy[4] = {mState.viewportWidth / 2.0f, h,
(float)mState.viewportX + mState.viewportWidth / 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};
- 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};
- programObject->setUniform3fv(depthRange, 1, nearFarDiff);
+ programBinary->setUniform3fv(depthRange, 1, nearFarDiff);
mDxUniformsDirty = false;
}
@@ -2021,18 +2022,19 @@
void Context::applyState(GLenum drawMode)
{
Program *programObject = getCurrentProgram();
+ ProgramBinary *programBinary = programObject->getProgramBinary();
Framebuffer *framebufferObject = getDrawFramebuffer();
GLenum adjustedFrontFace = adjustWinding(mState.frontFace);
- GLint frontCCW = programObject->getDxFrontCCWLocation();
+ GLint frontCCW = programBinary->getDxFrontCCWLocation();
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);
- programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
+ programBinary->setUniform1iv(pointsOrLines, 1, &alwaysFront);
D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
bool zeroColorMaskAllowed = identifier->VendorId != 0x1002;
@@ -2311,18 +2313,20 @@
void Context::applyShaders()
{
Program *programObject = getCurrentProgram();
+ ProgramBinary *programBinary = programObject->getProgramBinary();
+
if (programObject->getSerial() != mAppliedProgramSerial)
{
- IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader();
- IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader();
+ IDirect3DVertexShader9 *vertexShader = programBinary->getVertexShader();
+ IDirect3DPixelShader9 *pixelShader = programBinary->getPixelShader();
mDevice->SetPixelShader(pixelShader);
mDevice->SetVertexShader(vertexShader);
- programObject->dirtyAllUniforms();
+ programBinary->dirtyAllUniforms();
mAppliedProgramSerial = programObject->getSerial();
}
- programObject->applyUniforms();
+ programBinary->applyUniforms();
}
// Applies the textures and sampler states to the Direct3D 9 device
@@ -2342,20 +2346,21 @@
void Context::applyTextures(SamplerType type)
{
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
unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS;
int d3dSamplerOffset = (type == SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
- int samplerRange = programObject->getUsedSamplerRange(type);
+ int samplerRange = programBinary->getUsedSamplerRange(type);
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;
if (textureUnit != -1)
{
- TextureType textureType = programObject->getSamplerTextureType(type, samplerIndex);
+ TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
Texture *texture = getSamplerTexture(textureUnit, textureType);
unsigned int texSerial = texture->getTextureSerial();
@@ -2986,7 +2991,7 @@
applyShaders();
applyTextures();
- if (!getCurrentProgram()->validateSamplers(false))
+ if (!getCurrentProgram()->getProgramBinary()->validateSamplers(false))
{
return error(GL_INVALID_OPERATION);
}
@@ -3076,7 +3081,7 @@
applyShaders();
applyTextures();
- if (!getCurrentProgram()->validateSamplers(false))
+ if (!getCurrentProgram()->getProgramBinary()->validateSamplers(false))
{
return error(GL_INVALID_OPERATION);
}
@@ -4165,6 +4170,8 @@
D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
D3DVERTEXELEMENT9 *element = &elements[0];
+ ProgramBinary *programBinary = program->getProgramBinary();
+
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].active)
@@ -4220,7 +4227,7 @@
element->Type = attributes[i].type;
element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD;
- element->UsageIndex = program->getSemanticIndex(i);
+ element->UsageIndex = programBinary->getSemanticIndex(i);
element++;
}
}
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index e0fe8d7..3a84497 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -33,16 +33,16 @@
return buffer;
}
-AttributeBindings::AttributeBindings()
-{
-}
-
-AttributeBindings::~AttributeBindings()
-{
+AttributeBindings::AttributeBindings()
+{
+}
+
+AttributeBindings::~AttributeBindings()
+{
}
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;
data = new unsigned char[bytes];
@@ -61,15 +61,13 @@
}
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();
- mFragmentShader = NULL;
- mVertexShader = NULL;
mPixelExecutable = NULL;
mVertexExecutable = NULL;
@@ -79,10 +77,38 @@
mInfoLog = NULL;
mValidated = false;
- unlink();
+ for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+ {
+ 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;
+
+ 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;
}
@@ -101,6 +127,37 @@
}
}
+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)
{
if (shader->getType() == GL_VERTEX_SHADER)
@@ -160,27 +217,27 @@
return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
}
-IDirect3DPixelShader9 *Program::getPixelShader()
+IDirect3DPixelShader9 *ProgramBinary::getPixelShader()
{
return mPixelExecutable;
}
-IDirect3DVertexShader9 *Program::getVertexShader()
+IDirect3DVertexShader9 *ProgramBinary::getVertexShader()
{
return mVertexExecutable;
}
-void AttributeBindings::bindAttributeLocation(GLuint index, const char *name)
-{
- if (index < MAX_VERTEX_ATTRIBS)
- {
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mAttributeBinding[i].erase(name);
- }
-
- mAttributeBinding[index].insert(name);
- }
+void AttributeBindings::bindAttributeLocation(GLuint index, const char *name)
+{
+ if (index < MAX_VERTEX_ATTRIBS)
+ {
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAttributeBinding[i].erase(name);
+ }
+
+ mAttributeBinding[index].insert(name);
+ }
}
void Program::bindAttributeLocation(GLuint index, const char *name)
@@ -188,7 +245,7 @@
mAttributeBindings.bindAttributeLocation(index, name);
}
-GLuint Program::getAttributeLocation(const char *name)
+GLuint ProgramBinary::getAttributeLocation(const char *name)
{
if (name)
{
@@ -204,7 +261,7 @@
return -1;
}
-int Program::getSemanticIndex(int attributeIndex)
+int ProgramBinary::getSemanticIndex(int attributeIndex)
{
ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
@@ -212,7 +269,7 @@
}
// Returns one more than the highest sampler index used.
-GLint Program::getUsedSamplerRange(SamplerType type)
+GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
{
switch (type)
{
@@ -228,7 +285,7 @@
// 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).
-GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
+GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
{
GLint logicalTextureUnit = -1;
@@ -263,7 +320,7 @@
// 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).
-TextureType Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{
switch (type)
{
@@ -281,7 +338,7 @@
return TEXTURE_2D;
}
-GLint Program::getUniformLocation(std::string name)
+GLint ProgramBinary::getUniformLocation(std::string name)
{
unsigned int subscript = 0;
@@ -307,7 +364,7 @@
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())
{
@@ -368,7 +425,7 @@
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())
{
@@ -430,7 +487,7 @@
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())
{
@@ -491,7 +548,7 @@
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())
{
@@ -574,7 +631,7 @@
}
}
-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())
{
@@ -607,7 +664,7 @@
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())
{
@@ -641,7 +698,7 @@
}
-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())
{
@@ -674,7 +731,7 @@
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())
{
@@ -728,7 +785,7 @@
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())
{
@@ -780,7 +837,7 @@
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())
{
@@ -832,7 +889,7 @@
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())
{
@@ -884,7 +941,7 @@
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())
{
@@ -953,7 +1010,7 @@
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())
{
@@ -1028,7 +1085,7 @@
return true;
}
-void Program::dirtyAllUniforms()
+void ProgramBinary::dirtyAllUniforms()
{
unsigned int numUniforms = mUniforms.size();
for (unsigned int index = 0; index < numUniforms; index++)
@@ -1038,7 +1095,7 @@
}
// 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) {
Uniform *targetUniform = *ub;
@@ -1079,7 +1136,7 @@
}
// 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)
{
@@ -1153,7 +1210,7 @@
// 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
-int Program::packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader)
+int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader)
{
Context *context = getContext();
const int maxVaryingVectors = context->getMaximumVaryingVectors();
@@ -1301,7 +1358,7 @@
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())
{
@@ -1645,23 +1702,27 @@
// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
// compiling them into binaries, determining the attribute mappings, and collecting
// a list of uniforms
-void Program::link()
-{
- link(mAttributeBindings, mFragmentShader, mVertexShader);
+void Program::link()
+{
+ 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())
{
- return;
+ return false;
}
if (!vertexShader || !vertexShader->isCompiled())
{
- return;
+ return false;
}
std::string pixelHLSL = fragmentShader->getHLSL();
@@ -1669,7 +1730,7 @@
if (!linkVaryings(pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
{
- return;
+ return false;
}
Context *context = getContext();
@@ -1686,7 +1747,7 @@
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));
@@ -1700,17 +1761,17 @@
{
if (!linkAttributes(attributeBindings, fragmentShader, vertexShader))
{
- return;
+ return false;
}
if (!linkUniforms(GL_FRAGMENT_SHADER, mConstantTablePS))
{
- return;
+ return false;
}
if (!linkUniforms(GL_VERTEX_SHADER, mConstantTableVS))
{
- return;
+ return false;
}
// these uniforms are searched as already-decorated because gl_ and dx_
@@ -1724,18 +1785,20 @@
context->markDxUniformsDirty();
- mLinked = true; // Success
+ return true;
}
}
+
+ return false;
}
// 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;
// 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);
@@ -1765,7 +1828,7 @@
}
// 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);
@@ -1787,7 +1850,7 @@
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);
for (int r = 0; r < rows; r++)
@@ -1812,7 +1875,7 @@
return -1;
}
-bool Program::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable)
+bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable)
{
D3DXCONSTANTTABLE_DESC constantTableDescription;
@@ -1838,7 +1901,7 @@
// Adds the description of a constant found in the binary shader to the list of uniforms
// 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)
{
@@ -1923,7 +1986,7 @@
}
}
-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);
@@ -1961,7 +2024,7 @@
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
{
@@ -2037,7 +2100,7 @@
}
// 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)
{
@@ -2047,7 +2110,7 @@
return name;
}
-std::string Program::undecorateUniform(const std::string &_name)
+std::string ProgramBinary::undecorateUniform(const std::string &_name)
{
std::string name = _name;
@@ -2071,7 +2134,7 @@
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];
BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS];
@@ -2128,7 +2191,7 @@
}
}
-bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
+bool ProgramBinary::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
{
if (targetUniform->ps.registerCount)
{
@@ -2143,7 +2206,7 @@
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);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
@@ -2204,7 +2267,7 @@
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);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
@@ -2221,7 +2284,7 @@
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);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
@@ -2238,7 +2301,7 @@
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);
D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS];
@@ -2255,7 +2318,7 @@
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)
{
@@ -2273,7 +2336,7 @@
// append a santized message to the program info log.
// 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.
-void Program::appendToInfoLogSanitized(const char *message)
+void ProgramBinary::appendToInfoLogSanitized(const char *message)
{
std::string msg(message);
@@ -2291,7 +2354,7 @@
appendToInfoLog("%s\n", msg.c_str());
}
-void Program::appendToInfoLog(const char *format, ...)
+void ProgramBinary::appendToInfoLog(const char *format, ...)
{
if (!format)
{
@@ -2324,7 +2387,7 @@
}
}
-void Program::resetInfoLog()
+void ProgramBinary::resetInfoLog()
{
if (mInfoLog)
{
@@ -2351,76 +2414,19 @@
}
}
- if (mPixelExecutable)
+ if (mProgramBinary)
{
- mPixelExecutable->Release();
- mPixelExecutable = NULL;
+ delete mProgramBinary;
+ mProgramBinary = NULL;
}
-
- if (mVertexExecutable)
- {
- mVertexExecutable->Release();
- mVertexExecutable = NULL;
- }
-
- if (mConstantTablePS)
- {
- mConstantTablePS->Release();
- mConstantTablePS = 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;
}
@@ -2455,7 +2461,7 @@
return mCurrentSerial++;
}
-int Program::getInfoLogLength() const
+int ProgramBinary::getInfoLogLength() const
{
if (!mInfoLog)
{
@@ -2467,7 +2473,19 @@
}
}
-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;
@@ -2488,6 +2506,26 @@
}
}
+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)
{
int total = 0;
@@ -2518,7 +2556,7 @@
}
}
-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
unsigned int activeAttribute = 0;
@@ -2556,7 +2594,30 @@
*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;
@@ -2571,7 +2632,19 @@
return count;
}
-GLint Program::getActiveAttributeMaxLength()
+GLint Program::getActiveAttributeCount()
+{
+ if (mProgramBinary)
+ {
+ return mProgramBinary->getActiveAttributeCount();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+GLint ProgramBinary::getActiveAttributeMaxLength()
{
int maxLength = 0;
@@ -2586,7 +2659,19 @@
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
unsigned int activeUniform = 0;
@@ -2631,7 +2716,30 @@
*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;
@@ -2647,7 +2755,19 @@
return count;
}
-GLint Program::getActiveUniformMaxLength()
+GLint Program::getActiveUniformCount()
+{
+ if (mProgramBinary)
+ {
+ return mProgramBinary->getActiveUniformCount();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+GLint ProgramBinary::getActiveUniformMaxLength()
{
int maxLength = 0;
@@ -2668,6 +2788,18 @@
return maxLength;
}
+GLint Program::getActiveUniformMaxLength()
+{
+ if (mProgramBinary)
+ {
+ return mProgramBinary->getActiveUniformMaxLength();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
void Program::flagForDeletion()
{
mDeleteStatus = true;
@@ -2678,30 +2810,34 @@
return mDeleteStatus;
}
-void Program::validate()
+bool Program::isValidated() const
+{
+ if (mProgramBinary)
+ {
+ return mProgramBinary->isValidated();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void ProgramBinary::validate()
{
resetInfoLog();
- if (!isLinked())
+ applyUniforms();
+ if (!validateSamplers(true))
{
- appendToInfoLog("Program has not been successfully linked.");
mValidated = false;
}
else
{
- applyUniforms();
- if (!validateSamplers(true))
- {
- mValidated = false;
- }
- else
- {
- 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
// texture image unit, and this is the current program, then ValidateProgram will fail, and
@@ -2788,32 +2924,32 @@
return true;
}
-GLint Program::getDxDepthRangeLocation() const
+GLint ProgramBinary::getDxDepthRangeLocation() const
{
return mDxDepthRangeLocation;
}
-GLint Program::getDxDepthLocation() const
+GLint ProgramBinary::getDxDepthLocation() const
{
return mDxDepthLocation;
}
-GLint Program::getDxCoordLocation() const
+GLint ProgramBinary::getDxCoordLocation() const
{
return mDxCoordLocation;
}
-GLint Program::getDxHalfPixelSizeLocation() const
+GLint ProgramBinary::getDxHalfPixelSizeLocation() const
{
return mDxHalfPixelSizeLocation;
}
-GLint Program::getDxFrontCCWLocation() const
+GLint ProgramBinary::getDxFrontCCWLocation() const
{
return mDxFrontCCWLocation;
}
-GLint Program::getDxPointsOrLinesLocation() const
+GLint ProgramBinary::getDxPointsOrLinesLocation() const
{
return mDxPointsOrLinesLocation;
}
diff --git a/src/libGLESv2/Program.h b/src/libGLESv2/Program.h
index f6d1173..b97fd97 100644
--- a/src/libGLESv2/Program.h
+++ b/src/libGLESv2/Program.h
@@ -100,21 +100,16 @@
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:
- Program(ResourceManager *manager, GLuint handle);
-
- ~Program();
-
- bool attachShader(Shader *shader);
- bool detachShader(Shader *shader);
- int getAttachedShadersCount() const;
+ ProgramBinary();
+ ~ProgramBinary();
IDirect3DPixelShader9 *getPixelShader();
IDirect3DVertexShader9 *getVertexShader();
- void bindAttributeLocation(GLuint index, const char *name);
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
@@ -148,9 +143,7 @@
void dirtyAllUniforms();
void applyUniforms();
- void link();
- void link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
- bool isLinked();
+ bool link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
int getInfoLogLength() const;
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
@@ -163,26 +156,17 @@
GLint getActiveUniformCount();
GLint getActiveUniformMaxLength();
- 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;
-
static std::string decorateAttribute(const std::string &name); // Prepend an underscore
static std::string undecorateUniform(const std::string &_name); // Remove leading underscore
private:
- DISALLOW_COPY_AND_ASSIGN(Program);
+ DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
ID3D10Blob *compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable);
- void unlink(bool destroy = false);
int packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader);
bool linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader);
@@ -208,15 +192,14 @@
static unsigned int issueSerial();
IDirect3DDevice9 *mDevice;
- FragmentShader *mFragmentShader;
- VertexShader *mVertexShader;
IDirect3DPixelShader9 *mPixelExecutable;
IDirect3DVertexShader9 *mVertexExecutable;
+
+ // These are only used during linking.
ID3DXConstantTable *mConstantTablePS;
ID3DXConstantTable *mConstantTableVS;
- AttributeBindings mAttributeBindings;
Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
@@ -244,10 +227,62 @@
GLint mDxFrontCCWLocation;
GLint mDxPointsOrLinesLocation;
- bool mLinked;
- bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
char *mInfoLog;
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;
diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h
index 9c7c0df..43083ec 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -42,7 +42,7 @@
class Shader
{
- friend Program;
+ friend class ProgramBinary;
public:
Shader(ResourceManager *manager, GLuint handle);
@@ -128,7 +128,7 @@
class VertexShader : public Shader
{
- friend Program;
+ friend class ProgramBinary;
public:
VertexShader(ResourceManager *manager, GLuint handle);
diff --git a/src/libGLESv2/VertexDataManager.cpp b/src/libGLESv2/VertexDataManager.cpp
index 910eabc..566d1e6 100644
--- a/src/libGLESv2/VertexDataManager.cpp
+++ b/src/libGLESv2/VertexDataManager.cpp
@@ -128,10 +128,11 @@
const VertexAttributeArray &attribs = mContext->getVertexAttributes();
Program *program = mContext->getCurrentProgram();
+ ProgramBinary *programBinary = program->getProgramBinary();
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
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 5970f33..fba16d4 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -2937,12 +2937,13 @@
}
}
- if (!programObject->isLinked())
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
{
return error(GL_INVALID_OPERATION, -1);
}
- return programObject->getAttributeLocation(name);
+ return programBinary->getAttributeLocation(name);
}
}
catch(std::bad_alloc&)
@@ -3396,7 +3397,7 @@
*params = programObject->isFlaggedForDeletion();
return;
case GL_LINK_STATUS:
- *params = programObject->isLinked();
+ *params = programObject->getProgramBinary() != NULL;
return;
case GL_VALIDATE_STATUS:
*params = programObject->isValidated();
@@ -3944,12 +3945,18 @@
gl::Program *programObject = context->getProgram(program);
- if (!programObject || !programObject->isLinked())
+ if (!programObject)
{
return error(GL_INVALID_OPERATION);
}
- if (!programObject->getUniformfv(location, &bufSize, params))
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!programBinary->getUniformfv(location, &bufSize, params))
{
return error(GL_INVALID_OPERATION);
}
@@ -3978,12 +3985,18 @@
gl::Program *programObject = context->getProgram(program);
- if (!programObject || !programObject->isLinked())
+ if (!programObject)
{
return error(GL_INVALID_OPERATION);
}
- if (!programObject->getUniformfv(location, NULL, params))
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!programBinary->getUniformfv(location, NULL, params))
{
return error(GL_INVALID_OPERATION);
}
@@ -4018,17 +4031,18 @@
gl::Program *programObject = context->getProgram(program);
- if (!programObject || !programObject->isLinked())
- {
- return error(GL_INVALID_OPERATION);
- }
-
if (!programObject)
{
return error(GL_INVALID_OPERATION);
}
- if (!programObject->getUniformiv(location, &bufSize, params))
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!programBinary->getUniformiv(location, &bufSize, params))
{
return error(GL_INVALID_OPERATION);
}
@@ -4057,17 +4071,18 @@
gl::Program *programObject = context->getProgram(program);
- if (!programObject || !programObject->isLinked())
- {
- return error(GL_INVALID_OPERATION);
- }
-
if (!programObject)
{
return error(GL_INVALID_OPERATION);
}
- if (!programObject->getUniformiv(location, NULL, params))
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!programBinary->getUniformiv(location, NULL, params))
{
return error(GL_INVALID_OPERATION);
}
@@ -4108,12 +4123,13 @@
}
}
- if (!programObject->isLinked())
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
{
return error(GL_INVALID_OPERATION, -1);
}
- return programObject->getUniformLocation(name);
+ return programBinary->getUniformLocation(name);
}
}
catch(std::bad_alloc&)
@@ -5844,7 +5860,13 @@
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);
}
@@ -5888,7 +5910,13 @@
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);
}
@@ -5934,7 +5962,13 @@
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);
}
@@ -5980,7 +6014,13 @@
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);
}
@@ -6026,7 +6066,13 @@
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);
}
@@ -6072,7 +6118,13 @@
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);
}
@@ -6118,7 +6170,13 @@
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);
}
@@ -6164,7 +6222,13 @@
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);
}
@@ -6204,7 +6268,13 @@
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);
}
@@ -6244,7 +6314,13 @@
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);
}
@@ -6284,7 +6360,13 @@
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);
}
@@ -6320,7 +6402,7 @@
}
}
- if (program != 0 && !programObject->isLinked())
+ if (program != 0 && !programObject->getProgramBinary())
{
return error(GL_INVALID_OPERATION);
}
@@ -6358,7 +6440,13 @@
}
}
- programObject->validate();
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
+ {
+ return;
+ }
+
+ programBinary->validate();
}
}
catch(std::bad_alloc&)