Merge the ProgramBinary class into Program.
BUG=angle:731
Change-Id: I2ee97155841dc62f04bb71c1f2035d210fd3883c
Reviewed-on: https://chromium-review.googlesource.com/232694
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index c02bbe6..fe85831 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -18,7 +18,6 @@
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/Program.h"
-#include "libANGLE/ProgramBinary.h"
#include "libANGLE/Query.h"
#include "libANGLE/ResourceManager.h"
#include "libANGLE/Sampler.h"
@@ -123,17 +122,7 @@
Context::~Context()
{
- GLuint currentProgram = mState.getCurrentProgramId();
- if (currentProgram != 0)
- {
- Program *programObject = mResourceManager->getProgram(currentProgram);
- if (programObject)
- {
- programObject->release();
- }
- currentProgram = 0;
- }
- mState.setCurrentProgram(0, NULL);
+ mState.reset();
while (!mFramebufferMap.empty())
{
@@ -623,58 +612,7 @@
void Context::useProgram(GLuint program)
{
- GLuint priorProgramId = mState.getCurrentProgramId();
- Program *priorProgram = mResourceManager->getProgram(priorProgramId);
-
- if (priorProgramId != program)
- {
- mState.setCurrentProgram(program, mResourceManager->getProgram(program));
-
- if (priorProgram)
- {
- priorProgram->release();
- }
- }
-}
-
-Error Context::linkProgram(GLuint program)
-{
- Program *programObject = mResourceManager->getProgram(program);
-
- Error error = programObject->link(getData());
- if (error.isError())
- {
- return error;
- }
-
- // if the current program was relinked successfully we
- // need to install the new executables
- if (programObject->isLinked() && program == mState.getCurrentProgramId())
- {
- mState.setCurrentProgramBinary(programObject->getProgramBinary());
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
-{
- Program *programObject = mResourceManager->getProgram(program);
-
- Error error = programObject->setProgramBinary(binaryFormat, binary, length);
- if (error.isError())
- {
- return error;
- }
-
- // if the current program was reloaded successfully we
- // need to install the new executables
- if (programObject->isLinked() && program == mState.getCurrentProgramId())
- {
- mState.setCurrentProgramBinary(programObject->getProgramBinary());
- }
-
- return Error(GL_NO_ERROR);
+ mState.setProgram(getProgram(program));
}
void Context::bindTransformFeedback(GLuint transformFeedback)
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index 4836e40..8ceaa2b 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -43,7 +43,6 @@
{
class Shader;
class Program;
-class ProgramBinary;
class Texture;
class Texture2D;
class TextureCubeMap;
@@ -126,8 +125,6 @@
void bindPixelPackBuffer(GLuint buffer);
void bindPixelUnpackBuffer(GLuint buffer);
void useProgram(GLuint program);
- Error linkProgram(GLuint program);
- Error setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
Error beginQuery(GLenum target, GLuint query);
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 6453454..0c086b4 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -8,14 +8,47 @@
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
#include "libANGLE/Program.h"
-#include "libANGLE/ProgramBinary.h"
#include "libANGLE/ResourceManager.h"
+#include "libANGLE/Data.h"
+#include "libANGLE/features.h"
#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/ProgramImpl.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+
+#include "common/debug.h"
+#include "common/version.h"
+#include "common/utilities.h"
+#include "common/platform.h"
+#include "common/blocklayout.h"
+
+#include <algorithm>
namespace gl
{
const char * const g_fakepath = "C:\\fakepath";
+namespace
+{
+
+unsigned int ParseAndStripArrayIndex(std::string* name)
+{
+ unsigned int subscript = GL_INVALID_INDEX;
+
+ // Strip any trailing array operator and retrieve the subscript
+ size_t open = name->find_last_of('[');
+ size_t close = name->find_last_of(']');
+ if (open != std::string::npos && close == name->length() - 1)
+ {
+ subscript = atoi(name->substr(open + 1).c_str());
+ name->erase(open);
+ }
+
+ return subscript;
+}
+
+}
+
AttributeBindings::AttributeBindings()
{
}
@@ -136,17 +169,41 @@
}
}
-Program::Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
+VariableLocation::VariableLocation()
+ : name(), element(0), index(0)
{
- mFragmentShader = NULL;
- mVertexShader = NULL;
- mProgramBinary.set(NULL);
- mDeleteStatus = false;
- mLinked = false;
- mRefCount = 0;
- mRenderer = renderer;
+}
+
+VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
+ : name(name), element(element), index(index)
+{
+}
+
+LinkedVarying::LinkedVarying()
+{
+}
+
+LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
+ unsigned int semanticIndex, unsigned int semanticIndexCount)
+ : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount)
+{
+}
+
+Program::Program(rx::ProgramImpl *impl, ResourceManager *manager, GLuint handle)
+ : mProgram(impl),
+ mValidated(false),
+ mFragmentShader(NULL),
+ mVertexShader(NULL),
+ mLinked(false),
+ mDeleteStatus(false),
+ mRefCount(0),
+ mResourceManager(manager),
+ mHandle(handle)
+{
+ ASSERT(mProgram);
resetUniformBlockBindings();
+ unlink();
}
Program::~Program()
@@ -162,6 +219,8 @@
{
mFragmentShader->release();
}
+
+ SafeDelete(mProgram);
}
bool Program::attachShader(Shader *shader)
@@ -251,15 +310,59 @@
mInfoLog.reset();
resetUniformBlockBindings();
- mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
- mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
- if (result.error.isError())
+ if (!mFragmentShader || !mFragmentShader->isCompiled())
+ {
+ return Error(GL_NO_ERROR);
+ }
+ ASSERT(mFragmentShader->getType() == GL_FRAGMENT_SHADER);
+
+ if (!mVertexShader || !mVertexShader->isCompiled())
+ {
+ return Error(GL_NO_ERROR);
+ }
+ ASSERT(mVertexShader->getType() == GL_VERTEX_SHADER);
+
+ int registers;
+ std::vector<LinkedVarying> linkedVaryings;
+ rx::LinkResult result = mProgram->link(data, mInfoLog, mFragmentShader, mVertexShader, mTransformFeedbackVaryings, mTransformFeedbackBufferMode,
+ ®isters, &linkedVaryings, &mOutputVariables);
+ if (result.error.isError() || !result.linkSuccess)
{
return result.error;
}
- mLinked = result.linkSuccess;
+ if (!linkAttributes(mInfoLog, mAttributeBindings, mVertexShader))
+ {
+ return Error(GL_NO_ERROR);
+ }
+
+ if (!mProgram->linkUniforms(mInfoLog, *mVertexShader, *mFragmentShader, *data.caps))
+ {
+ return Error(GL_NO_ERROR);
+ }
+
+ if (!linkUniformBlocks(mInfoLog, *mVertexShader, *mFragmentShader, *data.caps))
+ {
+ return Error(GL_NO_ERROR);
+ }
+
+ if (!gatherTransformFeedbackLinkedVaryings(mInfoLog, linkedVaryings, mTransformFeedbackVaryings,
+ mTransformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
+ {
+ return Error(GL_NO_ERROR);
+ }
+
+ // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
+ // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
+ result = mProgram->compileProgramExecutables(mInfoLog, mFragmentShader, mVertexShader, registers);
+ if (result.error.isError() || !result.linkSuccess)
+ {
+ mInfoLog.append("Failed to create D3D shaders.");
+ unlink(false);
+ return result.error;
+ }
+
+ mLinked = true;
return gl::Error(GL_NO_ERROR);
}
@@ -294,7 +397,15 @@
}
}
- mProgramBinary.set(NULL);
+ std::fill(mLinkedAttribute, mLinkedAttribute + ArraySize(mLinkedAttribute), sh::Attribute());
+ std::fill(mSemanticIndex, mSemanticIndex + ArraySize(mSemanticIndex), -1);
+ std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1);
+ mOutputVariables.clear();
+
+ mProgram->reset();
+
+ mValidated = false;
+
mLinked = false;
}
@@ -303,27 +414,146 @@
return mLinked;
}
-ProgramBinary* Program::getProgramBinary() const
-{
- return mProgramBinary.get();
-}
-
-Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
+Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei length)
{
unlink(false);
- mInfoLog.reset();
+#if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED
+ return Error(GL_NO_ERROR);
+#else
+ ASSERT(binaryFormat == mProgram->getBinaryFormat());
- mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
- if (result.error.isError())
+ BinaryInputStream stream(binary, length);
+
+ GLenum format = stream.readInt<GLenum>();
+ if (format != mProgram->getBinaryFormat())
{
- mProgramBinary.set(NULL);
+ mInfoLog.append("Invalid program binary format.");
+ return Error(GL_NO_ERROR);
+ }
+
+ int majorVersion = stream.readInt<int>();
+ int minorVersion = stream.readInt<int>();
+ if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
+ {
+ mInfoLog.append("Invalid program binary version.");
+ return Error(GL_NO_ERROR);
+ }
+
+ unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
+ stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE);
+ if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
+ {
+ mInfoLog.append("Invalid program binary version.");
+ return Error(GL_NO_ERROR);
+ }
+
+ // TODO: move to ProgramImpl
+ int compileFlags = stream.readInt<int>();
+ if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ {
+ mInfoLog.append("Mismatched compilation flags.");
+ return Error(GL_NO_ERROR);
+ }
+
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
+ {
+ stream.readInt(&mLinkedAttribute[i].type);
+ stream.readString(&mLinkedAttribute[i].name);
+ stream.readInt(&mProgram->getShaderAttributes()[i].type);
+ stream.readString(&mProgram->getShaderAttributes()[i].name);
+ stream.readInt(&mSemanticIndex[i]);
+ }
+
+ initAttributesByLayout();
+
+ rx::LinkResult result = mProgram->load(mInfoLog, &stream);
+ if (result.error.isError() || !result.linkSuccess)
+ {
return result.error;
}
- mLinked = result.linkSuccess;
+ mLinked = true;
return Error(GL_NO_ERROR);
+#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED
+}
+
+Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const
+{
+ if (binaryFormat)
+ {
+ *binaryFormat = mProgram->getBinaryFormat();
+ }
+
+ BinaryOutputStream stream;
+
+ stream.writeInt(mProgram->getBinaryFormat());
+ stream.writeInt(ANGLE_MAJOR_VERSION);
+ stream.writeInt(ANGLE_MINOR_VERSION);
+ stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
+
+ // TODO: move to ProgramImpl
+ stream.writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
+
+ for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
+ {
+ stream.writeInt(mLinkedAttribute[i].type);
+ stream.writeString(mLinkedAttribute[i].name);
+ stream.writeInt(mProgram->getShaderAttributes()[i].type);
+ stream.writeString(mProgram->getShaderAttributes()[i].name);
+ stream.writeInt(mSemanticIndex[i]);
+ }
+
+ gl::Error error = mProgram->save(&stream);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ GLsizei streamLength = stream.length();
+ const void *streamData = stream.data();
+
+ if (streamLength > bufSize)
+ {
+ if (length)
+ {
+ *length = 0;
+ }
+
+ // TODO: This should be moved to the validation layer but computing the size of the binary before saving
+ // it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate
+ // sizes and then copy it.
+ return Error(GL_INVALID_OPERATION);
+ }
+
+ if (binary)
+ {
+ char *ptr = reinterpret_cast<char*>(binary);
+
+ memcpy(ptr, streamData, streamLength);
+ ptr += streamLength;
+
+ ASSERT(ptr - streamLength == binary);
+ }
+
+ if (length)
+ {
+ *length = streamLength;
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+GLint Program::getBinaryLength() const
+{
+ GLint length;
+ Error error = saveBinary(NULL, NULL, std::numeric_limits<GLint>::max(), &length);
+ if (error.isError())
+ {
+ return 0;
+ }
+
+ return length;
}
void Program::release()
@@ -346,19 +576,6 @@
return mRefCount;
}
-GLint Program::getProgramBinaryLength() const
-{
- ProgramBinary *programBinary = mProgramBinary.get();
- if (programBinary)
- {
- return programBinary->getLength();
- }
- else
- {
- return 0;
- }
-}
-
int Program::getInfoLogLength() const
{
return mInfoLog.getLength();
@@ -399,12 +616,64 @@
}
}
+GLuint Program::getAttributeLocation(const std::string &name)
+{
+ for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+ {
+ if (mLinkedAttribute[index].name == name)
+ {
+ return index;
+ }
+ }
+
+ return -1;
+}
+
+int Program::getSemanticIndex(int attributeIndex)
+{
+ ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
+
+ return mSemanticIndex[attributeIndex];
+}
+
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ if (mLinked)
{
- programBinary->getActiveAttribute(index, bufsize, length, size, type, name);
+ // Skip over inactive attributes
+ unsigned int activeAttribute = 0;
+ unsigned int attribute;
+ for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+ {
+ if (mLinkedAttribute[attribute].name.empty())
+ {
+ continue;
+ }
+
+ if (activeAttribute == index)
+ {
+ break;
+ }
+
+ activeAttribute++;
+ }
+
+ if (bufsize > 0)
+ {
+ const char *string = mLinkedAttribute[attribute].name.c_str();
+
+ strncpy(name, string, bufsize);
+ name[bufsize - 1] = '\0';
+
+ if (length)
+ {
+ *length = strlen(name);
+ }
+ }
+
+ *size = 1; // Always a single 'type' instance
+
+ *type = mLinkedAttribute[attribute].type;
}
else
{
@@ -412,7 +681,7 @@
{
name[0] = '\0';
}
-
+
if (length)
{
*length = 0;
@@ -425,36 +694,102 @@
GLint Program::getActiveAttributeCount()
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ int count = 0;
+
+ if (mLinked)
{
- return programBinary->getActiveAttributeCount();
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (!mLinkedAttribute[attributeIndex].name.empty())
+ {
+ count++;
+ }
+ }
}
- else
- {
- return 0;
- }
+
+ return count;
}
GLint Program::getActiveAttributeMaxLength()
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ int maxLength = 0;
+
+ if (mLinked)
{
- return programBinary->getActiveAttributeMaxLength();
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (!mLinkedAttribute[attributeIndex].name.empty())
+ {
+ maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
+ }
+ }
}
- else
+
+ return maxLength;
+}
+
+// Returns one more than the highest sampler index used.
+GLint Program::getUsedSamplerRange(SamplerType type)
+{
+ return mProgram->getUsedSamplerRange(type);
+}
+
+bool Program::usesPointSize() const
+{
+ return mProgram->usesPointSize();
+}
+
+GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
+{
+ return mProgram->getSamplerMapping(type, samplerIndex, caps);
+}
+
+GLenum Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+{
+ return mProgram->getSamplerTextureType(type, samplerIndex);
+}
+
+GLint Program::getFragDataLocation(const std::string &name) const
+{
+ std::string baseName(name);
+ unsigned int arrayIndex = ParseAndStripArrayIndex(&baseName);
+ for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
{
- return 0;
+ const VariableLocation &outputVariable = locationIt->second;
+ if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element))
+ {
+ return static_cast<GLint>(locationIt->first);
+ }
}
+ return -1;
}
void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ if (mLinked)
{
- return programBinary->getActiveUniform(index, bufsize, length, size, type, name);
+ ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount()
+ LinkedUniform *uniform = mProgram->getUniforms()[index];
+
+ if (bufsize > 0)
+ {
+ std::string string = uniform->name;
+ if (uniform->isArray())
+ {
+ string += "[0]";
+ }
+
+ strncpy(name, string.c_str(), bufsize);
+ name[bufsize - 1] = '\0';
+
+ if (length)
+ {
+ *length = strlen(name);
+ }
+ }
+
+ *size = uniform->elementCount();
+ *type = uniform->type;
}
else
{
@@ -475,10 +810,9 @@
GLint Program::getActiveUniformCount()
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ if (mLinked)
{
- return programBinary->getActiveUniformCount();
+ return mProgram->getUniforms().size();
}
else
{
@@ -488,15 +822,203 @@
GLint Program::getActiveUniformMaxLength()
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ int maxLength = 0;
+
+ if (mLinked)
{
- return programBinary->getActiveUniformMaxLength();
+ unsigned int numUniforms = mProgram->getUniforms().size();
+ for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
+ {
+ if (!mProgram->getUniforms()[uniformIndex]->name.empty())
+ {
+ int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1);
+ if (mProgram->getUniforms()[uniformIndex]->isArray())
+ {
+ length += 3; // Counting in "[0]".
+ }
+ maxLength = std::max(length, maxLength);
+ }
+ }
}
- else
+
+ return maxLength;
+}
+
+GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
+{
+ const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index];
+ switch (pname)
{
- return 0;
+ case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
+ case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount());
+ case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
+ case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex;
+ case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
+ case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
+ case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
+ case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
+ default:
+ UNREACHABLE();
+ break;
}
+ return 0;
+}
+
+bool Program::isValidUniformLocation(GLint location) const
+{
+ ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size()));
+ return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size()));
+}
+
+LinkedUniform *Program::getUniformByLocation(GLint location) const
+{
+ return mProgram->getUniformByLocation(location);
+}
+
+LinkedUniform *Program::getUniformByName(const std::string &name) const
+{
+ return mProgram->getUniformByName(name);
+}
+
+GLint Program::getUniformLocation(const std::string &name)
+{
+ return mProgram->getUniformLocation(name);
+}
+
+GLuint Program::getUniformIndex(const std::string &name)
+{
+ return mProgram->getUniformIndex(name);
+}
+
+void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform1fv(location, count, v);
+}
+
+void Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform2fv(location, count, v);
+}
+
+void Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform3fv(location, count, v);
+}
+
+void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform4fv(location, count, v);
+}
+
+void Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform1iv(location, count, v);
+}
+
+void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform2iv(location, count, v);
+}
+
+void Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform3iv(location, count, v);
+}
+
+void Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform4iv(location, count, v);
+}
+
+void Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform1uiv(location, count, v);
+}
+
+void Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform2uiv(location, count, v);
+}
+
+void Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform3uiv(location, count, v);
+}
+
+void Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform4uiv(location, count, v);
+}
+
+void Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix2fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix3fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix4fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
+}
+
+void Program::getUniformfv(GLint location, GLfloat *v)
+{
+ mProgram->getUniformfv(location, v);
+}
+
+void Program::getUniformiv(GLint location, GLint *v)
+{
+ mProgram->getUniformiv(location, v);
+}
+
+void Program::getUniformuiv(GLint location, GLuint *v)
+{
+ mProgram->getUniformuiv(location, v);
+}
+
+// Applies all the uniforms set for this program object to the renderer
+Error Program::applyUniforms()
+{
+ return mProgram->applyUniforms();
+}
+
+Error Program::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
+{
+ return mProgram->applyUniformBuffers(boundBuffers, caps);
}
void Program::flagForDeletion()
@@ -512,11 +1034,12 @@
void Program::validate(const Caps &caps)
{
mInfoLog.reset();
+ mValidated = false;
- ProgramBinary *programBinary = getProgramBinary();
- if (isLinked() && programBinary)
+ if (mLinked)
{
- programBinary->validate(mInfoLog, caps);
+ applyUniforms();
+ mValidated = mProgram->validateSamplers(&mInfoLog, caps);
}
else
{
@@ -524,43 +1047,114 @@
}
}
+bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps)
+{
+ return mProgram->validateSamplers(infoLog, caps);
+}
+
bool Program::isValidated() const
{
- ProgramBinary *programBinary = mProgramBinary.get();
- if (programBinary)
+ return mValidated;
+}
+
+void Program::updateSamplerMapping()
+{
+ return mProgram->updateSamplerMapping();
+}
+
+GLuint Program::getActiveUniformBlockCount()
+{
+ return mProgram->getUniformBlocks().size();
+}
+
+void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
+{
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
+
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
+
+ if (bufSize > 0)
{
- return programBinary->isValidated();
- }
- else
- {
- return false;
+ std::string string = uniformBlock.name;
+
+ if (uniformBlock.isArrayElement())
+ {
+ string += ArrayString(uniformBlock.elementIndex);
+ }
+
+ strncpy(uniformBlockName, string.c_str(), bufSize);
+ uniformBlockName[bufSize - 1] = '\0';
+
+ if (length)
+ {
+ *length = strlen(uniformBlockName);
+ }
}
}
-GLint Program::getActiveUniformBlockCount()
+void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
+
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
+
+ switch (pname)
{
- return static_cast<GLint>(programBinary->getActiveUniformBlockCount());
- }
- else
- {
- return 0;
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ *params = static_cast<GLint>(uniformBlock.dataSize);
+ break;
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ {
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
+ {
+ params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
+ }
+ }
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
+ break;
+ default: UNREACHABLE();
}
}
GLint Program::getActiveUniformBlockMaxLength()
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ int maxLength = 0;
+
+ if (mLinked)
{
- return static_cast<GLint>(programBinary->getActiveUniformBlockMaxLength());
+ unsigned int numUniformBlocks = mProgram->getUniformBlocks().size();
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
+ {
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
+ if (!uniformBlock.name.empty())
+ {
+ const int length = uniformBlock.name.length() + 1;
+
+ // Counting in "[0]".
+ const int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
+
+ maxLength = std::max(length + arrayLength, maxLength);
+ }
+ }
}
- else
- {
- return 0;
- }
+
+ return maxLength;
+}
+
+GLuint Program::getUniformBlockIndex(const std::string &name)
+{
+ return mProgram->getUniformBlockIndex(name);
}
void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
@@ -594,10 +1188,10 @@
void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary && index < programBinary->getTransformFeedbackVaryingCount())
+ if (mLinked)
{
- const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(index);
+ ASSERT(index < mProgram->getTransformFeedbackLinkedVaryings().size());
+ const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[index];
GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
if (length)
{
@@ -621,10 +1215,9 @@
GLsizei Program::getTransformFeedbackVaryingCount() const
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ if (mLinked)
{
- return static_cast<GLsizei>(programBinary->getTransformFeedbackVaryingCount());
+ return static_cast<GLsizei>(mProgram->getTransformFeedbackLinkedVaryings().size());
}
else
{
@@ -634,13 +1227,12 @@
GLsizei Program::getTransformFeedbackVaryingMaxLength() const
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ if (mLinked)
{
GLsizei maxSize = 0;
- for (size_t i = 0; i < programBinary->getTransformFeedbackVaryingCount(); i++)
+ for (size_t i = 0; i < mProgram->getTransformFeedbackLinkedVaryings().size(); i++)
{
- const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(i);
+ const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[i];
maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
}
@@ -654,15 +1246,430 @@
GLenum Program::getTransformFeedbackBufferMode() const
{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
+ return mTransformFeedbackBufferMode;
+}
+
+struct AttributeSorter
+{
+ AttributeSorter(const int(&semanticIndices)[MAX_VERTEX_ATTRIBS])
+ : originalIndices(semanticIndices)
{
- return programBinary->getTransformFeedbackBufferMode();
}
- else
+
+ bool operator()(int a, int b)
{
- return mTransformFeedbackBufferMode;
+ if (originalIndices[a] == -1) return false;
+ if (originalIndices[b] == -1) return true;
+ return (originalIndices[a] < originalIndices[b]);
}
+
+ const int(&originalIndices)[MAX_VERTEX_ATTRIBS];
+};
+
+void Program::initAttributesByLayout()
+{
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAttributesByLayout[i] = i;
+ }
+
+ std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
+}
+
+void Program::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
+{
+ rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
+
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ oldTranslatedAttributes[i] = attributes[i];
+ }
+
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ int oldIndex = mAttributesByLayout[i];
+ sortedSemanticIndices[i] = mSemanticIndex[oldIndex];
+ attributes[i] = oldTranslatedAttributes[oldIndex];
+ }
+}
+
+bool Program::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
+{
+ std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
+ std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
+
+ for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++)
+ {
+ PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
+ bool matched = false;
+
+ // Built-in varyings obey special rules
+ if (input->isBuiltIn())
+ {
+ continue;
+ }
+
+ for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
+ {
+ PackedVarying *output = &vertexVaryings[vertVaryingIndex];
+ if (output->name == input->name)
+ {
+ if (!linkValidateVaryings(infoLog, output->name, *input, *output))
+ {
+ return false;
+ }
+
+ output->registerIndex = input->registerIndex;
+ output->columnIndex = input->columnIndex;
+
+ matched = true;
+ break;
+ }
+ }
+
+ // We permit unmatched, unreferenced varyings
+ if (!matched && input->staticUse)
+ {
+ infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
+{
+ if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
+ {
+ return false;
+ }
+
+ if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
+ {
+ infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
+bool Program::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
+{
+ const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+
+ unsigned int usedLocations = 0;
+ const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
+
+ // Link attributes that have a binding location
+ for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
+ {
+ const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+ ASSERT(attribute.staticUse);
+
+ const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
+
+ mProgram->getShaderAttributes()[attributeIndex] = attribute;
+
+ if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
+ {
+ const int rows = VariableRegisterCount(attribute.type);
+
+ if (rows + location > MAX_VERTEX_ATTRIBS)
+ {
+ infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
+
+ return false;
+ }
+
+ for (int row = 0; row < rows; row++)
+ {
+ const int rowLocation = location + row;
+ sh::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation];
+
+ // In GLSL 3.00, attribute aliasing produces a link error
+ // In GLSL 1.00, attribute aliasing is allowed
+ if (mProgram->getShaderVersion() >= 300)
+ {
+ if (!linkedAttribute.name.empty())
+ {
+ infoLog.append("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), linkedAttribute.name.c_str(), rowLocation);
+ return false;
+ }
+ }
+
+ linkedAttribute = attribute;
+ usedLocations |= 1 << rowLocation;
+ }
+ }
+ }
+
+ // Link attributes that don't have a binding location
+ for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
+ {
+ const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+ ASSERT(attribute.staticUse);
+
+ const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
+
+ if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier
+ {
+ int rows = VariableRegisterCount(attribute.type);
+ int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
+
+ if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
+ {
+ infoLog.append("Too many active attributes (%s)", attribute.name.c_str());
+
+ return false; // Fail to link
+ }
+
+ mLinkedAttribute[availableIndex] = attribute;
+ }
+ }
+
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
+ {
+ int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
+ int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
+
+ for (int r = 0; r < rows; r++)
+ {
+ mSemanticIndex[attributeIndex++] = index++;
+ }
+ }
+
+ initAttributesByLayout();
+
+ return true;
+}
+
+bool Program::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
+{
+ const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
+ const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
+ // Check that interface blocks defined in the vertex and fragment shaders are identical
+ typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
+ UniformBlockMap linkedUniformBlocks;
+ for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
+ linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
+ }
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
+ UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
+ if (entry != linkedUniformBlocks.end())
+ {
+ const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
+ if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
+ {
+ return false;
+ }
+ }
+ }
+ for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+ {
+ if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+ {
+ return false;
+ }
+ }
+ }
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+ {
+ if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
+ const sh::InterfaceBlock &fragmentInterfaceBlock)
+{
+ const char* blockName = vertexInterfaceBlock.name.c_str();
+ // validate blocks for the same member types
+ if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
+ {
+ infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
+ return false;
+ }
+ if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
+ {
+ infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
+ return false;
+ }
+ if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
+ {
+ infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
+ return false;
+ }
+ const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+ {
+ const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
+ const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
+ if (vertexMember.name != fragmentMember.name)
+ {
+ infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
+ blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
+ return false;
+ }
+ std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+ if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable,
+ const sh::ShaderVariable &fragmentVariable, bool validatePrecision)
+{
+ if (vertexVariable.type != fragmentVariable.type)
+ {
+ infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str());
+ return false;
+ }
+ if (vertexVariable.arraySize != fragmentVariable.arraySize)
+ {
+ infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str());
+ return false;
+ }
+ if (validatePrecision && vertexVariable.precision != fragmentVariable.precision)
+ {
+ infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str());
+ return false;
+ }
+
+ if (vertexVariable.fields.size() != fragmentVariable.fields.size())
+ {
+ infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str());
+ return false;
+ }
+ const unsigned int numMembers = vertexVariable.fields.size();
+ for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
+ {
+ const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex];
+ const sh::ShaderVariable &fragmentMember = fragmentVariable.fields[memberIndex];
+
+ if (vertexMember.name != fragmentMember.name)
+ {
+ infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')",
+ memberIndex, variableName.c_str(),
+ vertexMember.name.c_str(), fragmentMember.name.c_str());
+ return false;
+ }
+
+ const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." +
+ vertexMember.name + "'";
+
+ if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool Program::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
+{
+ if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool Program::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
+{
+ if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
+ {
+ return false;
+ }
+
+ if (vertexVarying.interpolation != fragmentVarying.interpolation)
+ {
+ infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
+ const std::vector<std::string> &transformFeedbackVaryingNames,
+ GLenum transformFeedbackBufferMode,
+ std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+ const Caps &caps) const
+{
+ size_t totalComponents = 0;
+
+ // Gather the linked varyings that are used for transform feedback, they should all exist.
+ outTransformFeedbackLinkedVaryings->clear();
+ for (size_t i = 0; i < transformFeedbackVaryingNames.size(); i++)
+ {
+ bool found = false;
+ for (size_t j = 0; j < linkedVaryings.size(); j++)
+ {
+ if (transformFeedbackVaryingNames[i] == linkedVaryings[j].name)
+ {
+ for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++)
+ {
+ if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name)
+ {
+ infoLog.append("Two transform feedback varyings specify the same output variable (%s).", linkedVaryings[j].name.c_str());
+ return false;
+ }
+ }
+
+ size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
+ if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
+ componentCount > caps.maxTransformFeedbackSeparateComponents)
+ {
+ infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).",
+ linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents);
+ return false;
+ }
+
+ totalComponents += componentCount;
+
+ outTransformFeedbackLinkedVaryings->push_back(linkedVaryings[j]);
+ found = true;
+ break;
+ }
+ }
+
+ // All transform feedback varyings are expected to exist since packVaryings checks for them.
+ ASSERT(found);
+ }
+
+ if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents)
+ {
+ infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).",
+ totalComponents, caps.maxTransformFeedbackInterleavedComponents);
+ return false;
+ }
+
+ return true;
}
}
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 0253c2d..f60471d 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -10,13 +10,16 @@
#ifndef LIBANGLE_PROGRAM_H_
#define LIBANGLE_PROGRAM_H_
-#include "common/angleutils.h"
-#include "libANGLE/RefCountObject.h"
+#include "libANGLE/angletypes.h"
#include "libANGLE/Constants.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Error.h"
#include "libANGLE/export.h"
+#include "libANGLE/RefCountObject.h"
+
+#include "common/angleutils.h"
#include <GLES2/gl2.h>
+#include <GLSLANG/ShaderLang.h>
#include <vector>
#include <string>
@@ -25,6 +28,10 @@
namespace rx
{
class Renderer;
+class Renderer;
+struct TranslatedAttribute;
+class UniformStorage;
+class ProgramImpl;
}
namespace gl
@@ -33,6 +40,12 @@
struct Data;
class ResourceManager;
class Shader;
+class InfoLog;
+class AttributeBindings;
+class Buffer;
+class Framebuffer;
+struct UniformBlock;
+struct LinkedUniform;
extern const char * const g_fakepath;
@@ -66,13 +79,46 @@
char *mInfoLog;
};
+// Struct used for correlating uniforms/elements of uniform arrays to handles
+struct VariableLocation
+{
+ VariableLocation();
+ VariableLocation(const std::string &name, unsigned int element, unsigned int index);
+
+ std::string name;
+ unsigned int element;
+ unsigned int index;
+};
+
+struct LinkedVarying
+{
+ LinkedVarying();
+ LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
+ unsigned int semanticIndex, unsigned int semanticIndexCount);
+
+ // Original GL name
+ std::string name;
+
+ GLenum type;
+ GLsizei size;
+
+ // DirectX semantic information
+ std::string semanticName;
+ unsigned int semanticIndex;
+ unsigned int semanticIndexCount;
+};
+
class ANGLE_EXPORT Program
{
public:
- Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle);
-
+ Program(rx::ProgramImpl *impl, ResourceManager *manager, GLuint handle);
~Program();
+ GLuint id() const { return mHandle; }
+
+ rx::ProgramImpl *getImplementation() { return mProgram; }
+ const rx::ProgramImpl *getImplementation() const { return mProgram; }
+
bool attachShader(Shader *shader);
bool detachShader(Shader *shader);
int getAttachedShadersCount() const;
@@ -81,24 +127,75 @@
Error link(const Data &data);
bool isLinked();
- Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
- ProgramBinary *getProgramBinary() const;
+
+ Error loadBinary(GLenum binaryFormat, const void *binary, GLsizei length);
+ Error saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const;
+ GLint getBinaryLength() const;
int getInfoLogLength() const;
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
+ GLuint getAttributeLocation(const std::string &name);
+ int getSemanticIndex(int attributeIndex);
+
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLint getActiveAttributeCount();
GLint getActiveAttributeMaxLength();
+ GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps);
+ GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
+ GLint getUsedSamplerRange(SamplerType type);
+ bool usesPointSize() const;
+
+ GLint getFragDataLocation(const std::string &name) const;
+
void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLint getActiveUniformCount();
GLint getActiveUniformMaxLength();
+ GLint getActiveUniformi(GLuint index, GLenum pname) const;
+ bool isValidUniformLocation(GLint location) const;
+ LinkedUniform *getUniformByLocation(GLint location) const;
+ LinkedUniform *getUniformByName(const std::string &name) const;
- GLint getActiveUniformBlockCount();
+ GLint getUniformLocation(const std::string &name);
+ GLuint getUniformIndex(const std::string &name);
+ void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform1iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform2iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform3iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform4iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+
+ void getUniformfv(GLint location, GLfloat *params);
+ void getUniformiv(GLint location, GLint *params);
+ void getUniformuiv(GLint location, GLuint *params);
+
+ Error applyUniforms();
+ Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
+
+ void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
+ void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
+ GLuint getActiveUniformBlockCount();
GLint getActiveUniformBlockMaxLength();
+ GLuint getUniformBlockIndex(const std::string &name);
+
void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
@@ -108,6 +205,13 @@
GLsizei getTransformFeedbackVaryingMaxLength() const;
GLenum getTransformFeedbackBufferMode() const;
+ void initAttributesByLayout();
+ void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
+
+ static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader);
+ static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
+ static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
+
void addRef();
void release();
unsigned int getRefCount() const;
@@ -115,9 +219,9 @@
bool isFlaggedForDeletion() const;
void validate(const Caps &caps);
+ bool validateSamplers(InfoLog *infoLog, const Caps &caps);
bool isValidated() const;
-
- GLint getProgramBinaryLength() const;
+ void updateSamplerMapping();
private:
DISALLOW_COPY_AND_ASSIGN(Program);
@@ -125,6 +229,36 @@
void unlink(bool destroy = false);
void resetUniformBlockBindings();
+ bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
+ bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
+ bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
+ const sh::InterfaceBlock &fragmentInterfaceBlock);
+
+ static bool linkValidateVariablesBase(InfoLog &infoLog,
+ const std::string &variableName,
+ const sh::ShaderVariable &vertexVariable,
+ const sh::ShaderVariable &fragmentVariable,
+ bool validatePrecision);
+
+ static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
+ bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
+ const std::vector<std::string> &transformFeedbackVaryingNames,
+ GLenum transformFeedbackBufferMode,
+ std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+ const Caps &caps) const;
+ bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
+ void defineOutputVariables(Shader *fragmentShader);
+
+ rx::ProgramImpl *mProgram;
+
+ sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
+ int mSemanticIndex[MAX_VERTEX_ATTRIBS];
+ int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
+
+ std::map<int, VariableLocation> mOutputVariables;
+
+ bool mValidated;
+
Shader *mFragmentShader;
Shader *mVertexShader;
@@ -133,9 +267,8 @@
GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
std::vector<std::string> mTransformFeedbackVaryings;
- GLuint mTransformFeedbackBufferMode;
+ GLenum mTransformFeedbackBufferMode;
- BindingPointer<ProgramBinary> mProgramBinary;
bool mLinked;
bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
diff --git a/src/libANGLE/ProgramBinary.cpp b/src/libANGLE/ProgramBinary.cpp
deleted file mode 100644
index 9ecb58b..0000000
--- a/src/libANGLE/ProgramBinary.cpp
+++ /dev/null
@@ -1,1232 +0,0 @@
-//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Program.cpp: Implements the gl::Program class. Implements GL program objects
-// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
-
-#include "libANGLE/BinaryStream.h"
-#include "libANGLE/ProgramBinary.h"
-#include "libANGLE/Framebuffer.h"
-#include "libANGLE/FramebufferAttachment.h"
-#include "libANGLE/Renderbuffer.h"
-#include "libANGLE/renderer/ShaderExecutable.h"
-
-#include "libANGLE/Shader.h"
-#include "libANGLE/Program.h"
-#include "libANGLE/renderer/ProgramImpl.h"
-#include "libANGLE/renderer/d3d/ShaderD3D.h"
-#include "libANGLE/Context.h"
-#include "libANGLE/Buffer.h"
-#include "libANGLE/features.h"
-
-#include "common/blocklayout.h"
-#include "common/debug.h"
-#include "common/utilities.h"
-#include "common/platform.h"
-#include "common/version.h"
-
-namespace gl
-{
-
-namespace
-{
-
-unsigned int ParseAndStripArrayIndex(std::string* name)
-{
- unsigned int subscript = GL_INVALID_INDEX;
-
- // Strip any trailing array operator and retrieve the subscript
- size_t open = name->find_last_of('[');
- size_t close = name->find_last_of(']');
- if (open != std::string::npos && close == name->length() - 1)
- {
- subscript = atoi(name->substr(open + 1).c_str());
- name->erase(open);
- }
-
- return subscript;
-}
-
-}
-
-VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
- : name(name), element(element), index(index)
-{
-}
-
-LinkedVarying::LinkedVarying()
-{
-}
-
-LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
- unsigned int semanticIndex, unsigned int semanticIndexCount)
- : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount)
-{
-}
-
-LinkResult::LinkResult(bool linkSuccess, const Error &error)
- : linkSuccess(linkSuccess),
- error(error)
-{
-}
-
-unsigned int ProgramBinary::mCurrentSerial = 1;
-
-ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
- : RefCountObject(0),
- mProgram(impl),
- mValidated(false),
- mSerial(issueSerial())
-{
- ASSERT(impl);
-
- for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
- {
- mSemanticIndex[index] = -1;
- }
-}
-
-ProgramBinary::~ProgramBinary()
-{
- reset();
- SafeDelete(mProgram);
-}
-
-unsigned int ProgramBinary::getSerial() const
-{
- return mSerial;
-}
-
-unsigned int ProgramBinary::issueSerial()
-{
- return mCurrentSerial++;
-}
-
-GLuint ProgramBinary::getAttributeLocation(const char *name)
-{
- if (name)
- {
- for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
- {
- if (mLinkedAttribute[index].name == std::string(name))
- {
- return index;
- }
- }
- }
-
- return -1;
-}
-
-int ProgramBinary::getSemanticIndex(int attributeIndex)
-{
- ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
-
- return mSemanticIndex[attributeIndex];
-}
-
-// Returns one more than the highest sampler index used.
-GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
-{
- return mProgram->getUsedSamplerRange(type);
-}
-
-bool ProgramBinary::usesPointSize() const
-{
- return mProgram->usesPointSize();
-}
-
-GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
-{
- return mProgram->getSamplerMapping(type, samplerIndex, caps);
-}
-
-GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
-{
- return mProgram->getSamplerTextureType(type, samplerIndex);
-}
-
-GLint ProgramBinary::getUniformLocation(std::string name)
-{
- return mProgram->getUniformLocation(name);
-}
-
-GLuint ProgramBinary::getUniformIndex(std::string name)
-{
- return mProgram->getUniformIndex(name);
-}
-
-GLuint ProgramBinary::getUniformBlockIndex(std::string name)
-{
- return mProgram->getUniformBlockIndex(name);
-}
-
-UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
-{
- return mProgram->getUniformBlockByIndex(blockIndex);
-}
-
-GLint ProgramBinary::getFragDataLocation(const char *name) const
-{
- std::string baseName(name);
- unsigned int arrayIndex;
- arrayIndex = ParseAndStripArrayIndex(&baseName);
-
- for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
- {
- const VariableLocation &outputVariable = locationIt->second;
-
- if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element))
- {
- return static_cast<GLint>(locationIt->first);
- }
- }
-
- return -1;
-}
-
-size_t ProgramBinary::getTransformFeedbackVaryingCount() const
-{
- return mProgram->getTransformFeedbackLinkedVaryings().size();
-}
-
-const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const
-{
- return mProgram->getTransformFeedbackLinkedVaryings()[idx];
-}
-
-GLenum ProgramBinary::getTransformFeedbackBufferMode() const
-{
- return mProgram->getTransformFeedbackBufferMode();
-}
-
-void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform1fv(location, count, v);
-}
-
-void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform2fv(location, count, v);
-}
-
-void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform3fv(location, count, v);
-}
-
-void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform4fv(location, count, v);
-}
-
-void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform1iv(location, count, v);
-}
-
-void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform2iv(location, count, v);
-}
-
-void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform3iv(location, count, v);
-}
-
-void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform4iv(location, count, v);
-}
-
-void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform1uiv(location, count, v);
-}
-
-void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform2uiv(location, count, v);
-}
-
-void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform3uiv(location, count, v);
-}
-
-void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform4uiv(location, count, v);
-}
-
-void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix2fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix3fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix4fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
-}
-
-void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
-}
-
-void ProgramBinary::getUniformfv(GLint location, GLfloat *v) {
- mProgram->getUniformfv(location, v);
-}
-
-void ProgramBinary::getUniformiv(GLint location, GLint *v) {
- mProgram->getUniformiv(location, v);
-}
-
-void ProgramBinary::getUniformuiv(GLint location, GLuint *v) {
- mProgram->getUniformuiv(location, v);
-}
-
-void ProgramBinary::updateSamplerMapping()
-{
- return mProgram->updateSamplerMapping();
-}
-
-// Applies all the uniforms set for this program object to the renderer
-Error ProgramBinary::applyUniforms()
-{
- return mProgram->applyUniforms();
-}
-
-Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
-{
- return mProgram->applyUniformBuffers(boundBuffers, caps);
-}
-
-bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
-{
- std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
- std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
-
- for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++)
- {
- PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
- bool matched = false;
-
- // Built-in varyings obey special rules
- if (input->isBuiltIn())
- {
- continue;
- }
-
- for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
- {
- PackedVarying *output = &vertexVaryings[vertVaryingIndex];
- if (output->name == input->name)
- {
- if (!linkValidateVaryings(infoLog, output->name, *input, *output))
- {
- return false;
- }
-
- output->registerIndex = input->registerIndex;
- output->columnIndex = input->columnIndex;
-
- matched = true;
- break;
- }
- }
-
- // We permit unmatched, unreferenced varyings
- if (!matched && input->staticUse)
- {
- infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
- return false;
- }
- }
-
- return true;
-}
-
-LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
-{
-#if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_DISABLED
- return LinkResult(false, Error(GL_NO_ERROR));
-#else
- ASSERT(binaryFormat == mProgram->getBinaryFormat());
-
- reset();
-
- BinaryInputStream stream(binary, length);
-
- GLenum format = stream.readInt<GLenum>();
- if (format != mProgram->getBinaryFormat())
- {
- infoLog.append("Invalid program binary format.");
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- int majorVersion = stream.readInt<int>();
- int minorVersion = stream.readInt<int>();
- if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
- {
- infoLog.append("Invalid program binary version.");
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
- stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE);
- if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
- {
- infoLog.append("Invalid program binary version.");
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- int compileFlags = stream.readInt<int>();
- if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
- {
- infoLog.append("Mismatched compilation flags.");
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
- {
- stream.readInt(&mLinkedAttribute[i].type);
- stream.readString(&mLinkedAttribute[i].name);
- stream.readInt(&mProgram->getShaderAttributes()[i].type);
- stream.readString(&mProgram->getShaderAttributes()[i].name);
- stream.readInt(&mSemanticIndex[i]);
- }
-
- initAttributesByLayout();
-
- LinkResult result = mProgram->load(infoLog, &stream);
- if (result.error.isError() || !result.linkSuccess)
- {
- return result;
- }
-
- return LinkResult(true, Error(GL_NO_ERROR));
-#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED
-}
-
-Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
-{
- if (binaryFormat)
- {
- *binaryFormat = mProgram->getBinaryFormat();
- }
-
- BinaryOutputStream stream;
-
- stream.writeInt(mProgram->getBinaryFormat());
- stream.writeInt(ANGLE_MAJOR_VERSION);
- stream.writeInt(ANGLE_MINOR_VERSION);
- stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
- stream.writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
-
- for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
- {
- stream.writeInt(mLinkedAttribute[i].type);
- stream.writeString(mLinkedAttribute[i].name);
- stream.writeInt(mProgram->getShaderAttributes()[i].type);
- stream.writeString(mProgram->getShaderAttributes()[i].name);
- stream.writeInt(mSemanticIndex[i]);
- }
-
- mProgram->save(&stream);
-
- GLsizei streamLength = stream.length();
- const void *streamData = stream.data();
-
- if (streamLength > bufSize)
- {
- if (length)
- {
- *length = 0;
- }
-
- // TODO: This should be moved to the validation layer but computing the size of the binary before saving
- // it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate
- // sizes and then copy it.
- return Error(GL_INVALID_OPERATION);
- }
-
- if (binary)
- {
- char *ptr = (char*) binary;
-
- memcpy(ptr, streamData, streamLength);
- ptr += streamLength;
-
- ASSERT(ptr - streamLength == binary);
- }
-
- if (length)
- {
- *length = streamLength;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-GLint ProgramBinary::getLength()
-{
- GLint length;
- Error error = save(NULL, NULL, INT_MAX, &length);
- if (error.isError())
- {
- return 0;
- }
-
- return length;
-}
-
-LinkResult ProgramBinary::link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
- Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode)
-{
- if (!fragmentShader || !fragmentShader->isCompiled())
- {
- return LinkResult(false, Error(GL_NO_ERROR));
- }
- ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
-
- if (!vertexShader || !vertexShader->isCompiled())
- {
- return LinkResult(false, Error(GL_NO_ERROR));
- }
- ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
-
- reset();
-
- int registers;
- std::vector<LinkedVarying> linkedVaryings;
- LinkResult result = mProgram->link(data, infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
- ®isters, &linkedVaryings, &mOutputVariables);
- if (result.error.isError() || !result.linkSuccess)
- {
- return result;
- }
-
- if (!linkAttributes(infoLog, attributeBindings, vertexShader))
- {
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, *data.caps))
- {
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, *data.caps))
- {
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
- transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
- {
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
- // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
- result = mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers);
- if (result.error.isError() || !result.linkSuccess)
- {
- infoLog.append("Failed to create D3D shaders.");
- reset();
- return result;
- }
-
- return LinkResult(true, Error(GL_NO_ERROR));
-}
-
-bool ProgramBinary::linkUniformBlocks(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
- const gl::Caps &caps)
-{
- const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
- const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
-
- // Check that interface blocks defined in the vertex and fragment shaders are identical
- typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
- UniformBlockMap linkedUniformBlocks;
-
- for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
- linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
- }
-
- for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
- UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
- if (entry != linkedUniformBlocks.end())
- {
- const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
- if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
- {
- return false;
- }
- }
- }
-
- for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
-
- // Note: shared and std140 layouts are always considered active
- if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
- {
- if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
- {
- return false;
- }
- }
- }
-
- for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
-
- // Note: shared and std140 layouts are always considered active
- if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
- {
- if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
- {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
- const sh::InterfaceBlock &fragmentInterfaceBlock)
-{
- const char* blockName = vertexInterfaceBlock.name.c_str();
-
- // validate blocks for the same member types
- if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
- {
- infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
- return false;
- }
-
- if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
- {
- infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
- return false;
- }
-
- if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
- {
- infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
- return false;
- }
-
- const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
- {
- const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
- const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
-
- if (vertexMember.name != fragmentMember.name)
- {
- infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
- blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
- return false;
- }
-
- std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
- if (!gl::ProgramBinary::linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
- {
- return false;
- }
- }
-
- return true;
-}
-
-// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
-bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
-{
- const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
-
- unsigned int usedLocations = 0;
- const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
-
- // Link attributes that have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
- {
- const sh::Attribute &attribute = shaderAttributes[attributeIndex];
-
- ASSERT(attribute.staticUse);
-
- const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
-
- mProgram->getShaderAttributes()[attributeIndex] = attribute;
-
- if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
- {
- const int rows = VariableRegisterCount(attribute.type);
-
- if (rows + location > MAX_VERTEX_ATTRIBS)
- {
- infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
-
- return false;
- }
-
- for (int row = 0; row < rows; row++)
- {
- const int rowLocation = location + row;
- sh::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation];
-
- // In GLSL 3.00, attribute aliasing produces a link error
- // In GLSL 1.00, attribute aliasing is allowed
- if (mProgram->getShaderVersion() >= 300)
- {
- if (!linkedAttribute.name.empty())
- {
- infoLog.append("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), linkedAttribute.name.c_str(), rowLocation);
- return false;
- }
- }
-
- linkedAttribute = attribute;
- usedLocations |= 1 << rowLocation;
- }
- }
- }
-
- // Link attributes that don't have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
- {
- const sh::Attribute &attribute = shaderAttributes[attributeIndex];
-
- ASSERT(attribute.staticUse);
-
- const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
-
- if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier
- {
- int rows = VariableRegisterCount(attribute.type);
- int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
-
- if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
- {
- infoLog.append("Too many active attributes (%s)", attribute.name.c_str());
-
- return false; // Fail to link
- }
-
- mLinkedAttribute[availableIndex] = attribute;
- }
- }
-
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
- {
- int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
- int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
-
- for (int r = 0; r < rows; r++)
- {
- mSemanticIndex[attributeIndex++] = index++;
- }
- }
-
- initAttributesByLayout();
-
- return true;
-}
-
-bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable,
- const sh::ShaderVariable &fragmentVariable, bool validatePrecision)
-{
- if (vertexVariable.type != fragmentVariable.type)
- {
- infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str());
- return false;
- }
- if (vertexVariable.arraySize != fragmentVariable.arraySize)
- {
- infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str());
- return false;
- }
- if (validatePrecision && vertexVariable.precision != fragmentVariable.precision)
- {
- infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str());
- return false;
- }
-
- if (vertexVariable.fields.size() != fragmentVariable.fields.size())
- {
- infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str());
- return false;
- }
- const unsigned int numMembers = vertexVariable.fields.size();
- for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
- {
- const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex];
- const sh::ShaderVariable &fragmentMember = fragmentVariable.fields[memberIndex];
-
- if (vertexMember.name != fragmentMember.name)
- {
- infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')",
- memberIndex, variableName.c_str(),
- vertexMember.name.c_str(), fragmentMember.name.c_str());
- return false;
- }
-
- const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." +
- vertexMember.name + "'";
-
- if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
-{
- if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
- {
- return false;
- }
-
- return true;
-}
-
-bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
-{
- if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
- {
- return false;
- }
-
- if (vertexVarying.interpolation != fragmentVarying.interpolation)
- {
- infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str());
- return false;
- }
-
- return true;
-}
-
-bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
-{
- if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
- {
- return false;
- }
-
- if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
- {
- infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
- return false;
- }
-
- return true;
-}
-
-bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
- const std::vector<std::string> &transformFeedbackVaryingNames,
- GLenum transformFeedbackBufferMode,
- std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
- const Caps &caps) const
-{
- size_t totalComponents = 0;
-
- // Gather the linked varyings that are used for transform feedback, they should all exist.
- outTransformFeedbackLinkedVaryings->clear();
- for (size_t i = 0; i < transformFeedbackVaryingNames.size(); i++)
- {
- bool found = false;
- for (size_t j = 0; j < linkedVaryings.size(); j++)
- {
- if (transformFeedbackVaryingNames[i] == linkedVaryings[j].name)
- {
- for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++)
- {
- if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name)
- {
- infoLog.append("Two transform feedback varyings specify the same output variable (%s).", linkedVaryings[j].name.c_str());
- return false;
- }
- }
-
- size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
- if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
- componentCount > caps.maxTransformFeedbackSeparateComponents)
- {
- infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).",
- linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents);
- return false;
- }
-
- totalComponents += componentCount;
-
- outTransformFeedbackLinkedVaryings->push_back(linkedVaryings[j]);
- found = true;
- break;
- }
- }
-
- // All transform feedback varyings are expected to exist since packVaryings checks for them.
- ASSERT(found);
- }
-
- if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents)
- {
- infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).",
- totalComponents, caps.maxTransformFeedbackInterleavedComponents);
- return false;
- }
-
- return true;
-}
-
-bool ProgramBinary::isValidated() const
-{
- return mValidated;
-}
-
-void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
-{
- // Skip over inactive attributes
- unsigned int activeAttribute = 0;
- unsigned int attribute;
- for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
- {
- if (mLinkedAttribute[attribute].name.empty())
- {
- continue;
- }
-
- if (activeAttribute == index)
- {
- break;
- }
-
- activeAttribute++;
- }
-
- if (bufsize > 0)
- {
- const char *string = mLinkedAttribute[attribute].name.c_str();
-
- strncpy(name, string, bufsize);
- name[bufsize - 1] = '\0';
-
- if (length)
- {
- *length = strlen(name);
- }
- }
-
- *size = 1; // Always a single 'type' instance
-
- *type = mLinkedAttribute[attribute].type;
-}
-
-GLint ProgramBinary::getActiveAttributeCount() const
-{
- int count = 0;
-
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (!mLinkedAttribute[attributeIndex].name.empty())
- {
- count++;
- }
- }
-
- return count;
-}
-
-GLint ProgramBinary::getActiveAttributeMaxLength() const
-{
- int maxLength = 0;
-
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (!mLinkedAttribute[attributeIndex].name.empty())
- {
- maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
- }
- }
-
- return maxLength;
-}
-
-void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
-{
- ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount()
-
- if (bufsize > 0)
- {
- std::string string = mProgram->getUniforms()[index]->name;
-
- if (mProgram->getUniforms()[index]->isArray())
- {
- string += "[0]";
- }
-
- strncpy(name, string.c_str(), bufsize);
- name[bufsize - 1] = '\0';
-
- if (length)
- {
- *length = strlen(name);
- }
- }
-
- *size = mProgram->getUniforms()[index]->elementCount();
-
- *type = mProgram->getUniforms()[index]->type;
-}
-
-GLint ProgramBinary::getActiveUniformCount() const
-{
- return mProgram->getUniforms().size();
-}
-
-GLint ProgramBinary::getActiveUniformMaxLength() const
-{
- int maxLength = 0;
-
- unsigned int numUniforms = mProgram->getUniforms().size();
- for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
- {
- if (!mProgram->getUniforms()[uniformIndex]->name.empty())
- {
- int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1);
- if (mProgram->getUniforms()[uniformIndex]->isArray())
- {
- length += 3; // Counting in "[0]".
- }
- maxLength = std::max(length, maxLength);
- }
- }
-
- return maxLength;
-}
-
-GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
-{
- const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index];
-
- switch (pname)
- {
- case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
- case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount());
- case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
- case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex;
-
- case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
- case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
- case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
- case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
-
- default:
- UNREACHABLE();
- break;
- }
- return 0;
-}
-
-bool ProgramBinary::isValidUniformLocation(GLint location) const
-{
- ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size()));
- return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size()));
-}
-
-LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const
-{
- return mProgram->getUniformByLocation(location);
-}
-
-LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const
-{
- return mProgram->getUniformByName(name);
-}
-
-void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
-{
- ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
-
- const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
-
- if (bufSize > 0)
- {
- std::string string = uniformBlock.name;
-
- if (uniformBlock.isArrayElement())
- {
- string += ArrayString(uniformBlock.elementIndex);
- }
-
- strncpy(uniformBlockName, string.c_str(), bufSize);
- uniformBlockName[bufSize - 1] = '\0';
-
- if (length)
- {
- *length = strlen(uniformBlockName);
- }
- }
-}
-
-void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
-{
- ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
-
- const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
-
- switch (pname)
- {
- case GL_UNIFORM_BLOCK_DATA_SIZE:
- *params = static_cast<GLint>(uniformBlock.dataSize);
- break;
- case GL_UNIFORM_BLOCK_NAME_LENGTH:
- *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
- break;
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
- *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
- break;
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
- {
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
- {
- params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
- }
- }
- break;
- case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
- *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
- break;
- case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
- break;
- default: UNREACHABLE();
- }
-}
-
-GLuint ProgramBinary::getActiveUniformBlockCount() const
-{
- return mProgram->getUniformBlocks().size();
-}
-
-GLuint ProgramBinary::getActiveUniformBlockMaxLength() const
-{
- unsigned int maxLength = 0;
-
- unsigned int numUniformBlocks = mProgram->getUniformBlocks().size();
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
- {
- const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
- if (!uniformBlock.name.empty())
- {
- const unsigned int length = uniformBlock.name.length() + 1;
-
- // Counting in "[0]".
- const unsigned int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
-
- maxLength = std::max(length + arrayLength, maxLength);
- }
- }
-
- return maxLength;
-}
-
-void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
-{
- applyUniforms();
- if (!validateSamplers(&infoLog, caps))
- {
- mValidated = false;
- }
- else
- {
- mValidated = true;
- }
-}
-
-bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
-{
- return mProgram->validateSamplers(infoLog, caps);
-}
-
-struct AttributeSorter
-{
- AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
- : originalIndices(semanticIndices)
- {
- }
-
- bool operator()(int a, int b)
- {
- if (originalIndices[a] == -1) return false;
- if (originalIndices[b] == -1) return true;
- return (originalIndices[a] < originalIndices[b]);
- }
-
- const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
-};
-
-void ProgramBinary::initAttributesByLayout()
-{
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mAttributesByLayout[i] = i;
- }
-
- std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
-}
-
-void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
-{
- rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- oldTranslatedAttributes[i] = attributes[i];
- }
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- int oldIndex = mAttributesByLayout[i];
- sortedSemanticIndices[i] = mSemanticIndex[oldIndex];
- attributes[i] = oldTranslatedAttributes[oldIndex];
- }
-}
-
-void ProgramBinary::reset()
-{
- mOutputVariables.clear();
-
- mProgram->reset();
-
- mValidated = false;
-}
-
-}
diff --git a/src/libANGLE/ProgramBinary.h b/src/libANGLE/ProgramBinary.h
deleted file mode 100644
index 6365034..0000000
--- a/src/libANGLE/ProgramBinary.h
+++ /dev/null
@@ -1,238 +0,0 @@
-//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Program.h: Defines the gl::Program class. Implements GL program objects
-// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
-
-#ifndef LIBANGLE_PROGRAM_BINARY_H_
-#define LIBANGLE_PROGRAM_BINARY_H_
-
-#include "common/mathutil.h"
-#include "libANGLE/angletypes.h"
-#include "libANGLE/RefCountObject.h"
-#include "libANGLE/Uniform.h"
-#include "libANGLE/Shader.h"
-#include "libANGLE/Constants.h"
-#include "libANGLE/renderer/d3d/VertexDataManager.h"
-#include "libANGLE/renderer/d3d/DynamicHLSL.h"
-#include "libANGLE/export.h"
-
-#include "angle_gl.h"
-
-#include <string>
-#include <vector>
-
-namespace sh
-{
-class HLSLBlockEncoder;
-}
-
-#include <GLES3/gl3.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <string>
-#include <vector>
-
-namespace rx
-{
-class ShaderExecutable;
-struct TranslatedAttribute;
-class UniformStorage;
-class ProgramImpl;
-}
-
-namespace gl
-{
-struct Caps;
-class Shader;
-class InfoLog;
-class AttributeBindings;
-class Buffer;
-class Framebuffer;
-struct Data;
-
-// Struct used for correlating uniforms/elements of uniform arrays to handles
-struct VariableLocation
-{
- VariableLocation()
- {
- }
-
- VariableLocation(const std::string &name, unsigned int element, unsigned int index);
-
- std::string name;
- unsigned int element;
- unsigned int index;
-};
-
-struct LinkedVarying
-{
- LinkedVarying();
- LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
- unsigned int semanticIndex, unsigned int semanticIndexCount);
-
- // Original GL name
- std::string name;
-
- GLenum type;
- GLsizei size;
-
- // DirectX semantic information
- std::string semanticName;
- unsigned int semanticIndex;
- unsigned int semanticIndexCount;
-};
-
-struct LinkResult
-{
- bool linkSuccess;
- Error error;
-
- LinkResult(bool linkSuccess, const Error &error);
-};
-
-// This is the result of linking a program. It is the state that would be passed to ProgramBinary.
-class ANGLE_EXPORT ProgramBinary : public RefCountObject
-{
- public:
- explicit ProgramBinary(rx::ProgramImpl *impl);
- ~ProgramBinary();
-
- rx::ProgramImpl *getImplementation() { return mProgram; }
- const rx::ProgramImpl *getImplementation() const { return mProgram; }
-
- GLuint getAttributeLocation(const char *name);
- int getSemanticIndex(int attributeIndex);
-
- GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps);
- GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
- GLint getUsedSamplerRange(SamplerType type);
- bool usesPointSize() const;
-
- GLint getUniformLocation(std::string name);
- GLuint getUniformIndex(std::string name);
- GLuint getUniformBlockIndex(std::string name);
- void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
- void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
- void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
- void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
- void setUniform1iv(GLint location, GLsizei count, const GLint *v);
- void setUniform2iv(GLint location, GLsizei count, const GLint *v);
- void setUniform3iv(GLint location, GLsizei count, const GLint *v);
- void setUniform4iv(GLint location, GLsizei count, const GLint *v);
- void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
- void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
- void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
- void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
- void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
-
- void getUniformfv(GLint location, GLfloat *params);
- void getUniformiv(GLint location, GLint *params);
- void getUniformuiv(GLint location, GLuint *params);
-
- Error applyUniforms();
- Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
-
- LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
- Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
- GLint getLength();
-
- LinkResult link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
- Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode);
-
- void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
- GLint getActiveAttributeCount() const;
- GLint getActiveAttributeMaxLength() const;
-
- void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
- GLint getActiveUniformCount() const;
- GLint getActiveUniformMaxLength() const;
- GLint getActiveUniformi(GLuint index, GLenum pname) const;
- bool isValidUniformLocation(GLint location) const;
- LinkedUniform *getUniformByLocation(GLint location) const;
- LinkedUniform *getUniformByName(const std::string &name) const;
-
- void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
- void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
- GLuint getActiveUniformBlockCount() const;
- GLuint getActiveUniformBlockMaxLength() const;
- UniformBlock *getUniformBlockByIndex(GLuint blockIndex);
-
- GLint getFragDataLocation(const char *name) const;
-
- size_t getTransformFeedbackVaryingCount() const;
- const LinkedVarying &getTransformFeedbackVarying(size_t idx) const;
- GLenum getTransformFeedbackBufferMode() const;
-
- void validate(InfoLog &infoLog, const Caps &caps);
- bool validateSamplers(InfoLog *infoLog, const Caps &caps);
- bool isValidated() const;
- void updateSamplerMapping();
-
- unsigned int getSerial() const;
-
- void initAttributesByLayout();
- void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
-
- static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader);
- static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
- static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
-
- void reset();
-
- bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
- bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
- bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
- const sh::InterfaceBlock &fragmentInterfaceBlock);
-
- static bool linkValidateVariablesBase(InfoLog &infoLog,
- const std::string &variableName,
- const sh::ShaderVariable &vertexVariable,
- const sh::ShaderVariable &fragmentVariable,
- bool validatePrecision);
-
- static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
- bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
- const std::vector<std::string> &transformFeedbackVaryingNames,
- GLenum transformFeedbackBufferMode,
- std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
- const Caps &caps) const;
- bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
- void defineOutputVariables(Shader *fragmentShader);
-
- rx::ProgramImpl *mProgram;
-
- sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
- int mSemanticIndex[MAX_VERTEX_ATTRIBS];
- int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
-
- std::map<int, VariableLocation> mOutputVariables;
-
- bool mValidated;
-
- const unsigned int mSerial;
-
- static unsigned int issueSerial();
- static unsigned int mCurrentSerial;
-};
-
-}
-
-#endif // LIBANGLE_PROGRAM_BINARY_H_
diff --git a/src/libANGLE/ResourceManager.cpp b/src/libANGLE/ResourceManager.cpp
index 7cebe30..3ed77f1 100644
--- a/src/libANGLE/ResourceManager.cpp
+++ b/src/libANGLE/ResourceManager.cpp
@@ -106,7 +106,7 @@
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
- mProgramMap[handle] = new Program(mRenderer, this, handle);
+ mProgramMap[handle] = new Program(mRenderer->createProgram(), this, handle);
return handle;
}
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index dae55b4..0b1cab5 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -138,8 +138,7 @@
mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
- mCurrentProgramId = 0;
- mCurrentProgramBinary.set(NULL);
+ mProgram = NULL;
mReadFramebuffer = NULL;
mDrawFramebuffer = NULL;
@@ -163,6 +162,12 @@
mArrayBuffer.set(NULL);
mRenderbuffer.set(NULL);
+ if (mProgram)
+ {
+ mProgram->release();
+ }
+ mProgram = NULL;
+
mTransformFeedback.set(NULL);
for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
@@ -187,6 +192,8 @@
mPack.pixelBuffer.set(NULL);
mUnpack.pixelBuffer.set(NULL);
+
+ mProgram = NULL;
}
const RasterizerState &State::getRasterizerState() const
@@ -845,31 +852,27 @@
return false;
}
-void State::setCurrentProgram(GLuint programId, Program *newProgram)
+void State::setProgram(Program *newProgram)
{
- mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
- mCurrentProgramBinary.set(NULL);
-
- if (newProgram)
+ if (mProgram != newProgram)
{
- newProgram->addRef();
- mCurrentProgramBinary.set(newProgram->getProgramBinary());
+ if (mProgram)
+ {
+ mProgram->release();
+ }
+
+ mProgram = newProgram;
+
+ if (mProgram)
+ {
+ newProgram->addRef();
+ }
}
}
-void State::setCurrentProgramBinary(ProgramBinary *binary)
+Program *State::getProgram() const
{
- mCurrentProgramBinary.set(binary);
-}
-
-GLuint State::getCurrentProgramId() const
-{
- return mCurrentProgramId;
-}
-
-ProgramBinary *State::getCurrentProgramBinary() const
-{
- return mCurrentProgramBinary.get();
+ return mProgram;
}
void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
@@ -1214,7 +1217,7 @@
case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
- case GL_CURRENT_PROGRAM: *params = mCurrentProgramId; break;
+ case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index 4b78804..abd12b4 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -168,10 +168,8 @@
bool removeVertexArrayBinding(GLuint vertexArray);
// Program binding manipulation
- void setCurrentProgram(GLuint programId, Program *newProgram);
- void setCurrentProgramBinary(ProgramBinary *binary);
- GLuint getCurrentProgramId() const;
- ProgramBinary *getCurrentProgramBinary() const;
+ void setProgram(Program *newProgram);
+ Program *getProgram() const;
// Transform feedback object (not buffer) binding manipulation
void setTransformFeedbackBinding(TransformFeedback *transformFeedback);
@@ -285,8 +283,7 @@
Framebuffer *mReadFramebuffer;
Framebuffer *mDrawFramebuffer;
BindingPointer<Renderbuffer> mRenderbuffer;
- GLuint mCurrentProgramId;
- BindingPointer<ProgramBinary> mCurrentProgramBinary;
+ Program *mProgram;
typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector;
VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
diff --git a/src/libANGLE/angletypes.cpp b/src/libANGLE/angletypes.cpp
index 6f5d56b..16be27d 100644
--- a/src/libANGLE/angletypes.cpp
+++ b/src/libANGLE/angletypes.cpp
@@ -7,7 +7,7 @@
// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
#include "libANGLE/angletypes.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/State.h"
#include "libANGLE/VertexArray.h"
@@ -149,13 +149,13 @@
}
void VertexFormat::GetInputLayout(VertexFormat *inputLayout,
- ProgramBinary *programBinary,
+ Program *program,
const State &state)
{
const VertexAttribute *vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
- int semanticIndex = programBinary->getSemanticIndex(attributeIndex);
+ int semanticIndex = program->getSemanticIndex(attributeIndex);
if (semanticIndex != -1)
{
diff --git a/src/libANGLE/angletypes.h b/src/libANGLE/angletypes.h
index 4af82d5..21ede00 100644
--- a/src/libANGLE/angletypes.h
+++ b/src/libANGLE/angletypes.h
@@ -18,7 +18,7 @@
{
class Buffer;
class State;
-class ProgramBinary;
+class Program;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
@@ -233,7 +233,7 @@
VertexFormat(const VertexAttribute &attribute, GLenum currentValueType);
static void GetInputLayout(VertexFormat *inputLayout,
- ProgramBinary *programBinary,
+ Program *program,
const State& currentValues);
bool operator==(const VertexFormat &other) const;
diff --git a/src/libANGLE/renderer/ProgramImpl.cpp b/src/libANGLE/renderer/ProgramImpl.cpp
index 047691f..b4dfc45 100644
--- a/src/libANGLE/renderer/ProgramImpl.cpp
+++ b/src/libANGLE/renderer/ProgramImpl.cpp
@@ -34,6 +34,12 @@
}
+LinkResult::LinkResult(bool linkSuccess, const gl::Error &error)
+ : linkSuccess(linkSuccess),
+ error(error)
+{
+}
+
ProgramImpl::~ProgramImpl()
{
// Ensure that reset was called by the inherited class during destruction
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index bdb4044..c4b329b 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -12,7 +12,7 @@
#include "common/angleutils.h"
#include "libANGLE/BinaryStream.h"
#include "libANGLE/Constants.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/Shader.h"
#include "libANGLE/renderer/Renderer.h"
@@ -21,6 +21,13 @@
namespace rx
{
+struct LinkResult
+{
+ bool linkSuccess;
+ gl::Error error;
+ LinkResult(bool linkSuccess, const gl::Error &error);
+};
+
class ProgramImpl
{
public:
@@ -52,15 +59,15 @@
virtual GLenum getTransformFeedbackBufferMode() const = 0;
virtual GLenum getBinaryFormat() = 0;
- virtual gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
+ virtual LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
- virtual gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
- gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode,
- int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
- std::map<int, gl::VariableLocation> *outputVariables) = 0;
+ virtual LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables) = 0;
virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0;
virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0;
@@ -98,8 +105,8 @@
virtual void updateSamplerMapping() = 0;
virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0;
- virtual gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- int registers) = 0;
+ virtual LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers) = 0;
virtual bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps) = 0;
diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
index 3ad1ed5..8e0c2bd 100644
--- a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -10,7 +10,6 @@
#include "libANGLE/renderer/d3d/ShaderD3D.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/Program.h"
-#include "libANGLE/ProgramBinary.h"
#include "libANGLE/Shader.h"
#include "libANGLE/formatutils.h"
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 05707a8..e7317e6 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -11,7 +11,6 @@
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Program.h"
-#include "libANGLE/ProgramBinary.h"
#include "libANGLE/renderer/ShaderExecutable.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
@@ -148,6 +147,8 @@
{
}
+unsigned int ProgramD3D::mCurrentSerial = 1;
+
ProgramD3D::ProgramD3D(RendererD3D *renderer)
: ProgramImpl(),
mRenderer(renderer),
@@ -161,7 +162,8 @@
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mDirtySamplerMapping(true),
- mShaderVersion(100)
+ mShaderVersion(100),
+ mSerial(issueSerial())
{
mDynamicHLSL = new DynamicHLSL(renderer);
}
@@ -398,7 +400,7 @@
return true;
}
-gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
stream->readInt(&mShaderVersion);
@@ -428,7 +430,7 @@
if (stream->error())
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUniforms.resize(uniformCount);
@@ -461,7 +463,7 @@
if (stream->error())
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUniformIndex.resize(uniformIndexCount);
@@ -476,7 +478,7 @@
if (stream->error())
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUniformBlocks.resize(uniformBlockCount);
@@ -560,13 +562,13 @@
&shaderExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (!shaderExecutable)
{
infoLog.append("Could not create vertex shader.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
// generated converted input layout
@@ -598,13 +600,13 @@
&shaderExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (!shaderExecutable)
{
infoLog.append("Could not create pixel shader.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
// add new binary
@@ -624,13 +626,13 @@
&mGeometryExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (!mGeometryExecutable)
{
infoLog.append("Could not create geometry shader.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
stream->skip(geometryShaderSize);
}
@@ -642,12 +644,12 @@
if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
initializeUniformStorage();
- return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
+ return LinkResult(true, gl::Error(GL_NO_ERROR));
}
gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
@@ -917,8 +919,8 @@
return gl::Error(GL_NO_ERROR);
}
-gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- int registers)
+LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers)
{
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
@@ -929,7 +931,7 @@
gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey());
@@ -937,7 +939,7 @@
error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (usesGeometryShader())
@@ -950,7 +952,7 @@
ANGLE_D3D_WORKAROUND_NONE, &mGeometryExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
}
@@ -976,15 +978,15 @@
#endif
bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
- return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
+ return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
}
-gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
- gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode,
- int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
- std::map<int, gl::VariableLocation> *outputVariables)
+LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables)
{
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
@@ -1007,24 +1009,24 @@
if (*registers < 0)
{
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
- if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader))
+ if (!gl::Program::linkVaryings(infoLog, fragmentShader, vertexShader))
{
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings,
linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth))
{
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUsesPointSize = vertexShaderD3D->usesPointSize();
- return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
+ return LinkResult(true, gl::Error(GL_NO_ERROR));
}
void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const
@@ -1307,7 +1309,7 @@
{
const sh::Uniform &vertexUniform = *entry->second;
const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
- if (!gl::ProgramBinary::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
+ if (!gl::Program::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
@@ -1921,4 +1923,14 @@
mDirtySamplerMapping = true;
}
+unsigned int ProgramD3D::getSerial() const
+{
+ return mSerial;
+}
+
+unsigned int ProgramD3D::issueSerial()
+{
+ return mCurrentSerial++;
+}
+
}
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index cf5f9d2..7b6219a 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -11,6 +11,7 @@
#include "libANGLE/renderer/ProgramImpl.h"
#include "libANGLE/renderer/Workarounds.h"
+#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include <string>
#include <vector>
@@ -26,6 +27,7 @@
{
class RendererD3D;
class UniformStorage;
+class ShaderExecutable;
class ProgramD3D : public ProgramImpl
{
@@ -51,7 +53,7 @@
bool usesGeometryShader() const;
GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
- gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
+ LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
gl::Error save(gl::BinaryOutputStream *stream);
gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExectuable);
@@ -59,15 +61,15 @@
gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable);
ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; }
- gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- int registers);
+ LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers);
- gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
- gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode,
- int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
- std::map<int, gl::VariableLocation> *outputVariables);
+ LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables);
void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
@@ -113,6 +115,8 @@
void reset();
+ unsigned int getSerial() const;
+
private:
DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
@@ -212,6 +216,11 @@
bool mDirtySamplerMapping;
int mShaderVersion;
+
+ unsigned int mSerial;
+
+ static unsigned int issueSerial();
+ static unsigned int mCurrentSerial;
};
}
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/libANGLE/renderer/d3d/RendererD3D.cpp
index e31d61d..8312b8a 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -53,10 +53,10 @@
const GLvoid *indices, GLsizei instances,
const RangeUI &indexRange)
{
- ASSERT(data.state->getCurrentProgramId() != 0);
+ gl::Program *program = data.state->getProgram();
+ ASSERT(program != NULL);
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
+ program->updateSamplerMapping();
gl::Error error = generateSwizzles(data);
if (error.isError())
@@ -136,10 +136,10 @@
GLenum mode, GLint first,
GLsizei count, GLsizei instances)
{
- ASSERT(data.state->getCurrentProgramId() != 0);
+ gl::Program *program = data.state->getProgram();
+ ASSERT(program != NULL);
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
+ program->updateSamplerMapping();
gl::Error error = generateSwizzles(data);
if (error.isError())
@@ -209,14 +209,14 @@
gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type)
{
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ gl::Program *program = data.state->getProgram();
- size_t samplerRange = programBinary->getUsedSamplerRange(type);
+ size_t samplerRange = program->getUsedSamplerRange(type);
for (size_t i = 0; i < samplerRange; i++)
{
- GLenum textureType = programBinary->getSamplerTextureType(type, i);
- GLint textureUnit = programBinary->getSamplerMapping(type, i, *data.caps);
+ GLenum textureType = program->getSamplerTextureType(type, i);
+ GLint textureUnit = program->getSamplerMapping(type, i, *data.caps);
if (textureUnit != -1)
{
gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
@@ -355,20 +355,20 @@
// Applies the shaders and shader constants to the Direct3D device
gl::Error RendererD3D::applyShaders(const gl::Data &data, bool transformFeedbackActive)
{
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ gl::Program *program = data.state->getProgram();
gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
- gl::VertexFormat::GetInputLayout(inputLayout, programBinary, *data.state);
+ gl::VertexFormat::GetInputLayout(inputLayout, program, *data.state);
const gl::Framebuffer *fbo = data.state->getDrawFramebuffer();
- gl::Error error = applyShaders(programBinary, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ gl::Error error = applyShaders(program, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, transformFeedbackActive);
if (error.isError())
{
return error;
}
- return programBinary->applyUniforms();
+ return program->applyUniforms();
}
// For each Direct3D sampler of either the pixel or vertex stage,
@@ -377,13 +377,13 @@
gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType,
const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
{
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ gl::Program *program = data.state->getProgram();
- size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
+ size_t samplerRange = program->getUsedSamplerRange(shaderType);
for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
{
- GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
- GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, *data.caps);
+ GLenum textureType = program->getSamplerTextureType(shaderType, samplerIndex);
+ GLint textureUnit = program->getSamplerMapping(shaderType, samplerIndex, *data.caps);
if (textureUnit != -1)
{
gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
@@ -471,14 +471,13 @@
gl::Error RendererD3D::applyUniformBuffers(const gl::Data &data)
{
- gl::Program *programObject = data.resourceManager->getProgram(data.state->getCurrentProgramId());
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ gl::Program *program = data.state->getProgram();
std::vector<gl::Buffer*> boundBuffers;
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
{
- GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
+ GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
if (data.state->getIndexedUniformBuffer(blockBinding)->id() == 0)
{
@@ -493,7 +492,7 @@
}
}
- return programBinary->applyUniformBuffers(boundBuffers, *data.caps);
+ return program->applyUniformBuffers(boundBuffers, *data.caps);
}
bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode)
@@ -503,7 +502,7 @@
// ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
// which affects varying interpolation. Since the value of gl_PointSize is
// undefined when not written, just skip drawing to avoid unexpected results.
- if (!data.state->getCurrentProgramBinary()->usesPointSize())
+ if (!data.state->getProgram()->usesPointSize())
{
// This is stictly speaking not an error, but developers should be
// notified of risking undefined behavior.
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
index 323c7e9..6df0487 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -91,7 +91,7 @@
bool ignoreViewport) = 0;
virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
- virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive) = 0;
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
diff --git a/src/libANGLE/renderer/d3d/VertexDataManager.cpp b/src/libANGLE/renderer/d3d/VertexDataManager.cpp
index 64e58c3..37a3633 100644
--- a/src/libANGLE/renderer/d3d/VertexDataManager.cpp
+++ b/src/libANGLE/renderer/d3d/VertexDataManager.cpp
@@ -12,7 +12,7 @@
#include "libANGLE/renderer/d3d/VertexBuffer.h"
#include "libANGLE/renderer/Renderer.h"
#include "libANGLE/Buffer.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/State.h"
@@ -94,7 +94,7 @@
// Invalidate static buffers that don't contain matching attributes
for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
{
- translated[attributeIndex].active = (state.getCurrentProgramBinary()->getSemanticIndex(attributeIndex) != -1);
+ translated[attributeIndex].active = (state.getProgram()->getSemanticIndex(attributeIndex) != -1);
const gl::VertexAttribute &curAttrib = state.getVertexAttribState(attributeIndex);
if (translated[attributeIndex].active && curAttrib.enabled)
diff --git a/src/libANGLE/renderer/d3d/VertexDataManager.h b/src/libANGLE/renderer/d3d/VertexDataManager.h
index fe0c68b..a82749a 100644
--- a/src/libANGLE/renderer/d3d/VertexDataManager.h
+++ b/src/libANGLE/renderer/d3d/VertexDataManager.h
@@ -16,7 +16,6 @@
namespace gl
{
-class ProgramBinary;
class State;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
index ac9d99f..e2b4d7b 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -14,7 +14,7 @@
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/ProgramD3D.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/VertexAttribute.h"
#include "third_party/murmurhash/MurmurHash3.h"
@@ -87,10 +87,10 @@
}
gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
- gl::ProgramBinary *programBinary)
+ gl::Program *program)
{
int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
- programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices);
+ program->sortAttributesByLayout(attributes, sortedSemanticIndices);
if (!mDevice || !mDeviceContext)
{
@@ -113,7 +113,7 @@
// Record the type of the associated vertex shader vector in our key
// This will prevent mismatched vertex shaders from using the same input layout
GLint attributeSize;
- programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
+ program->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i];
@@ -138,7 +138,7 @@
{
gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetInputLayout(attributes, shaderInputLayout);
- ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(program->getImplementation());
ShaderExecutable *shader = NULL;
gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader);
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
index 2e48304..9cebee2 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
@@ -21,7 +21,7 @@
namespace gl
{
-class ProgramBinary;
+class Program;
}
namespace rx
@@ -39,7 +39,7 @@
void markDirty();
gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
- gl::ProgramBinary *programBinary);
+ gl::Program *program);
private:
DISALLOW_COPY_AND_ASSIGN(InputLayoutCache);
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 999d2ea..8cee038 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -14,7 +14,7 @@
#include "libANGLE/Display.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/State.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
@@ -1073,7 +1073,7 @@
return error;
}
- return mInputLayoutCache.applyVertexBuffers(attributes, state.getCurrentProgramBinary());
+ return mInputLayoutCache.applyVertexBuffers(attributes, state.getProgram());
}
gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
@@ -1478,10 +1478,10 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive)
{
- ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(program->getImplementation());
ShaderExecutable *vertexExe = NULL;
gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index fd83885..2562404 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -82,7 +82,7 @@
virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
- virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 47f6c31..fac523a 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -11,7 +11,7 @@
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/Workarounds.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/Framebuffer.h"
#include "common/debug.h"
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 02eaa9a..c4594d3 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -13,7 +13,7 @@
#include "libANGLE/Display.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/State.h"
#include "libANGLE/Surface.h"
@@ -1320,7 +1320,7 @@
return error;
}
- return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getCurrentProgramBinary(), instances, &mRepeatDraw);
+ return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getProgram(), instances, &mRepeatDraw);
}
// Applies the indices and element array bindings to the Direct3D 9 device
@@ -1719,13 +1719,13 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive)
{
ASSERT(!transformFeedbackActive);
ASSERT(!rasterizerDiscard);
- ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(program->getImplementation());
ShaderExecutable *vertexExe = NULL;
gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
@@ -1761,7 +1761,7 @@
// per-program, checking the program serial guarantees we upload fresh
// uniform data even if our shader pointers are the same.
// https://code.google.com/p/angleproject/issues/detail?id=661
- unsigned int programSerial = programBinary->getSerial();
+ unsigned int programSerial = programD3D->getSerial();
if (programSerial != mAppliedProgramSerial)
{
programD3D->dirtyAllUniforms();
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
index f47bbb8..72ef5c2 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -82,7 +82,7 @@
bool ignoreViewport);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
- virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
diff --git a/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
index 568273e..f9eded9 100644
--- a/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
@@ -9,7 +9,7 @@
#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h"
#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h"
#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
#include "libANGLE/VertexAttribute.h"
namespace rx
@@ -40,7 +40,7 @@
}
}
-gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
+gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw)
{
*repeatDraw = 1;
@@ -155,7 +155,7 @@
element->Type = d3d9VertexInfo.nativeFormat;
element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD;
- element->UsageIndex = programBinary->getSemanticIndex(i);
+ element->UsageIndex = program->getSemanticIndex(i);
element++;
}
}
diff --git a/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
index 3272e50..fbd6730 100644
--- a/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
+++ b/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
@@ -15,6 +15,7 @@
namespace gl
{
class VertexDataManager;
+class Program;
}
namespace rx
@@ -26,7 +27,7 @@
VertexDeclarationCache();
~VertexDeclarationCache();
- gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
+ gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw);
void markStateDirty();
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 695f94f..08ded1d 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -15,7 +15,8 @@
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/Query.h"
-#include "libANGLE/ProgramBinary.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Uniform.h"
#include "libANGLE/TransformFeedback.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/renderer/BufferImpl.h"
@@ -1058,8 +1059,8 @@
return false;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- if (!programBinary)
+ gl::Program *program = context->getState().getProgram();
+ if (!program)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1071,13 +1072,13 @@
return false;
}
- if (!programBinary->isValidUniformLocation(location))
+ if (!program->isValidUniformLocation(location))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- LinkedUniform *uniform = programBinary->getUniformByLocation(location);
+ LinkedUniform *uniform = program->getUniformByLocation(location);
// attempting to write an array to a non-array uniform is an INVALID_OPERATION
if (uniform->elementCount() == 1 && count > 1)
@@ -1461,14 +1462,14 @@
return false;
}
- if (state.getCurrentProgramId() == 0)
+ gl::Program *program = state.getProgram();
+ if (!program)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
- if (!programBinary->validateSamplers(NULL, context->getCaps()))
+ if (!program->validateSamplers(NULL, context->getCaps()))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1479,7 +1480,7 @@
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
- bool attribActive = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ bool attribActive = (program->getSemanticIndex(attributeIndex) != -1);
if (attribActive && attrib.enabled)
{
gl::Buffer *buffer = attrib.buffer.get();
@@ -1573,13 +1574,13 @@
// Verify there is at least one active attribute with a divisor of zero
const gl::State& state = context->getState();
- gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
+ gl::Program *program = state.getProgram();
const VertexArray *vao = state.getVertexArray();
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
- bool active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ bool active = (program->getSemanticIndex(attributeIndex) != -1);
if (active && attrib.divisor == 0)
{
return true;
@@ -1886,14 +1887,7 @@
return false;
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- if (!programBinary->isValidUniformLocation(location))
+ if (!programObject->isValidUniformLocation(location))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1921,10 +1915,9 @@
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
// sized queries -- ensure the provided buffer is large enough
- LinkedUniform *uniform = programBinary->getUniformByLocation(location);
+ LinkedUniform *uniform = programObject->getUniformByLocation(location);
size_t requiredBytes = VariableExternalSize(uniform->type);
if (static_cast<size_t>(bufSize) < requiredBytes)
{
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index b32965b..32f602c 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -74,8 +74,6 @@
'libANGLE/ImageIndex.cpp',
'libANGLE/Program.cpp',
'libANGLE/Program.h',
- 'libANGLE/ProgramBinary.cpp',
- 'libANGLE/ProgramBinary.h',
'libANGLE/Query.cpp',
'libANGLE/Query.h',
'libANGLE/RefCountObject.cpp',
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 71e4f30..a197e67 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -13,8 +13,8 @@
#include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Shader.h"
#include "libANGLE/Program.h"
-#include "libANGLE/ProgramBinary.h"
#include "libANGLE/Texture.h"
#include "libANGLE/Query.h"
#include "libANGLE/Context.h"
@@ -1996,14 +1996,13 @@
}
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programObject->isLinked() || !programBinary)
+ if (!programObject->isLinked())
{
context->recordError(gl::Error(GL_INVALID_OPERATION));
return -1;
}
- return programBinary->getAttributeLocation(name);
+ return programObject->getAttributeLocation(name);
}
return -1;
@@ -2546,7 +2545,7 @@
*params = programObject->getActiveUniformMaxLength();
return;
case GL_PROGRAM_BINARY_LENGTH_OES:
- *params = programObject->getProgramBinaryLength();
+ *params = programObject->getBinaryLength();
return;
case GL_ACTIVE_UNIFORM_BLOCKS:
*params = programObject->getActiveUniformBlockCount();
@@ -3218,10 +3217,8 @@
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
- programBinary->getUniformfv(location, params);
+ programObject->getUniformfv(location, params);
}
}
@@ -3239,10 +3236,8 @@
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
- programBinary->getUniformfv(location, params);
+ programObject->getUniformfv(location, params);
}
}
@@ -3261,10 +3256,8 @@
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
- programBinary->getUniformiv(location, params);
+ programObject->getUniformiv(location, params);
}
}
@@ -3282,10 +3275,8 @@
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
- programBinary->getUniformiv(location, params);
+ programObject->getUniformiv(location, params);
}
}
@@ -3317,14 +3308,13 @@
}
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programObject->isLinked() || !programBinary)
+ if (!programObject->isLinked())
{
context->recordError(gl::Error(GL_INVALID_OPERATION));
return -1;
}
- return programBinary->getUniformLocation(name);
+ return programObject->getUniformLocation(name);
}
return -1;
@@ -3659,7 +3649,7 @@
}
}
- gl::Error error = context->linkProgram(program);
+ gl::Error error = programObject->link(context->getData());
if (error.isError())
{
context->recordError(error);
@@ -4467,8 +4457,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform1fv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform1fv(location, count, v);
}
}
@@ -4489,8 +4479,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform1iv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform1iv(location, count, v);
}
}
@@ -4513,8 +4503,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform2fv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform2fv(location, count, v);
}
}
@@ -4537,8 +4527,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform2iv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform2iv(location, count, v);
}
}
@@ -4561,8 +4551,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform3fv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform3fv(location, count, v);
}
}
@@ -4585,8 +4575,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform3iv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform3iv(location, count, v);
}
}
@@ -4609,8 +4599,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform4fv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform4fv(location, count, v);
}
}
@@ -4633,8 +4623,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform4iv(location, count, v);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform4iv(location, count, v);
}
}
@@ -4651,8 +4641,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix2fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix2fv(location, count, transpose, value);
}
}
@@ -4669,8 +4659,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix3fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix3fv(location, count, transpose, value);
}
}
@@ -4687,8 +4677,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix4fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix4fv(location, count, transpose, value);
}
}
@@ -5628,8 +5618,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix2x3fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix2x3fv(location, count, transpose, value);
}
}
@@ -5646,8 +5636,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix3x2fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix3x2fv(location, count, transpose, value);
}
}
@@ -5664,8 +5654,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix2x4fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix2x4fv(location, count, transpose, value);
}
}
@@ -5682,8 +5672,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix4x2fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix4x2fv(location, count, transpose, value);
}
}
@@ -5700,8 +5690,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix3x4fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix3x4fv(location, count, transpose, value);
}
}
@@ -5718,8 +5708,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix4x3fv(location, count, transpose, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniformMatrix4x3fv(location, count, transpose, value);
}
}
@@ -6593,10 +6583,8 @@
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
- programBinary->getUniformuiv(location, params);
+ programObject->getUniformuiv(location, params);
}
}
@@ -6628,14 +6616,7 @@
return -1;
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
-
- return programBinary->getFragDataLocation(name);
+ return programObject->getFragDataLocation(name);
}
return 0;
@@ -6677,8 +6658,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform1uiv(location, count, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform1uiv(location, count, value);
}
}
@@ -6695,8 +6676,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform2uiv(location, count, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform2uiv(location, count, value);
}
}
@@ -6713,8 +6694,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform3uiv(location, count, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform3uiv(location, count, value);
}
}
@@ -6731,8 +6712,8 @@
return;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform4uiv(location, count, value);
+ gl::Program *program = context->getState().getProgram();
+ program->setUniform4uiv(location, count, value);
}
}
@@ -7030,8 +7011,7 @@
}
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programObject->isLinked() || !programBinary)
+ if (!programObject->isLinked())
{
for (int uniformId = 0; uniformId < uniformCount; uniformId++)
{
@@ -7042,7 +7022,7 @@
{
for (int uniformId = 0; uniformId < uniformCount; uniformId++)
{
- uniformIndices[uniformId] = programBinary->getUniformIndex(uniformNames[uniformId]);
+ uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
}
}
}
@@ -7101,9 +7081,7 @@
return;
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary && uniformCount > 0)
+ if (uniformCount > 0)
{
context->recordError(gl::Error(GL_INVALID_VALUE));
return;
@@ -7113,7 +7091,7 @@
{
const GLuint index = uniformIndices[uniformId];
- if (index >= (GLuint)programBinary->getActiveUniformCount())
+ if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
{
context->recordError(gl::Error(GL_INVALID_VALUE));
return;
@@ -7123,7 +7101,7 @@
for (int uniformId = 0; uniformId < uniformCount; uniformId++)
{
const GLuint index = uniformIndices[uniformId];
- params[uniformId] = programBinary->getActiveUniformi(index, pname);
+ params[uniformId] = programObject->getActiveUniformi(index, pname);
}
}
}
@@ -7157,13 +7135,7 @@
}
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- return GL_INVALID_INDEX;
- }
-
- return programBinary->getUniformBlockIndex(uniformBlockName);
+ return programObject->getUniformBlockIndex(uniformBlockName);
}
return 0;
@@ -7198,9 +7170,7 @@
}
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
+ if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
{
context->recordError(gl::Error(GL_INVALID_VALUE));
return;
@@ -7218,7 +7188,7 @@
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- programBinary->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
+ programObject->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
break;
default:
@@ -7258,15 +7228,13 @@
}
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
+ if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
{
context->recordError(gl::Error(GL_INVALID_VALUE));
return;
}
- programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
+ programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
}
}
@@ -7306,10 +7274,8 @@
}
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
// if never linked, there won't be any uniform blocks
- if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
+ if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
{
context->recordError(gl::Error(GL_INVALID_VALUE));
return;
@@ -8498,15 +8464,7 @@
return;
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Error error = programBinary->save(binaryFormat, binary, bufSize, length);
+ gl::Error error = programObject->saveBinary(binaryFormat, binary, bufSize, length);
if (error.isError())
{
context->recordError(error);
@@ -8538,7 +8496,7 @@
return;
}
- gl::Error error = context->setProgramBinary(program, binaryFormat, binary, length);
+ gl::Error error = programObject->loadBinary(binaryFormat, binary, length);
if (error.isError())
{
context->recordError(error);