Update Program, ProgramBinary and HLSLCompiler to use Error objects.
BUG=angle:520
Change-Id: Ibbe8c95780fecfb68f4558e99e3a761107da6aee
Reviewed-on: https://chromium-review.googlesource.com/220790
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 96f78ad..1a81620 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -107,6 +107,12 @@
{
}
+LinkResult::LinkResult(bool linkSuccess, const Error &error)
+ : linkSuccess(linkSuccess),
+ error(error)
+{
+}
+
unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
@@ -854,10 +860,10 @@
return true;
}
-bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
+LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
{
#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
#else
ASSERT(binaryFormat == mProgram->getBinaryFormat());
@@ -869,7 +875,7 @@
if (format != mProgram->getBinaryFormat())
{
infoLog.append("Invalid program binary format.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
int majorVersion = stream.readInt<int>();
@@ -877,7 +883,7 @@
if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
{
infoLog.append("Invalid program binary version.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
@@ -885,14 +891,14 @@
if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
{
infoLog.append("Invalid program binary version.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
int compileFlags = stream.readInt<int>();
if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
{
infoLog.append("Mismatched compilation flags.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
@@ -932,7 +938,7 @@
if (stream.error())
{
infoLog.append("Invalid program binary.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
mUniforms.resize(uniformCount);
@@ -965,7 +971,7 @@
if (stream.error())
{
infoLog.append("Invalid program binary.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
mUniformBlocks.resize(uniformBlockCount);
@@ -994,7 +1000,7 @@
if (stream.error())
{
infoLog.append("Invalid program binary.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
mUniformIndex.resize(uniformIndexCount);
@@ -1005,18 +1011,19 @@
stream.readInt(&mUniformIndex[uniformIndexIndex].index);
}
- if (!mProgram->load(infoLog, &stream))
+ LinkResult result = mProgram->load(infoLog, &stream);
+ if (result.error.isError() || !result.linkSuccess)
{
- return false;
+ return result;
}
mProgram->initializeUniformStorage(mUniforms);
- return true;
+ return LinkResult(true, Error(GL_NO_ERROR));
#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
}
-bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
+Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
{
if (binaryFormat)
{
@@ -1108,15 +1115,7 @@
stream.writeInt(mUniformIndex[i].index);
}
- if (!mProgram->save(&stream))
- {
- if (length)
- {
- *length = 0;
- }
-
- return false;
- }
+ mProgram->save(&stream);
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
@@ -1128,7 +1127,10 @@
*length = 0;
}
- return false;
+ // 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)
@@ -1146,34 +1148,33 @@
*length = streamLength;
}
- return true;
+ return Error(GL_NO_ERROR);
}
GLint ProgramBinary::getLength()
{
GLint length;
- if (save(NULL, NULL, INT_MAX, &length))
- {
- return length;
- }
- else
+ Error error = save(NULL, NULL, INT_MAX, &length);
+ if (error.isError())
{
return 0;
}
+
+ return length;
}
-bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
+LinkResult ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
+ const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
{
if (!fragmentShader || !fragmentShader->isCompiled())
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
if (!vertexShader || !vertexShader->isCompiled())
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
@@ -1187,22 +1188,21 @@
int registers;
std::vector<LinkedVarying> linkedVaryings;
- if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
- ®isters, &linkedVaryings, &mOutputVariables, caps))
+ LinkResult result = mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
+ ®isters, &linkedVaryings, &mOutputVariables, caps);
+ if (result.error.isError() || !result.linkSuccess)
{
- return false;
+ return result;
}
- bool success = true;
-
if (!linkAttributes(infoLog, attributeBindings, vertexShader))
{
- success = false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
{
- success = false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
// special case for gl_DepthRange, the only built-in uniform (also a struct)
@@ -1217,28 +1217,26 @@
if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
{
- success = false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), caps))
{
- success = false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
- if (success)
+ // 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)
{
- // 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.
- if (!mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers))
- {
- infoLog.append("Failed to create D3D shaders.");
- success = false;
- reset();
- }
+ infoLog.append("Failed to create D3D shaders.");
+ reset();
+ return result;
}
- return success;
+ return LinkResult(true, Error(GL_NO_ERROR));
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices