Implement the robust GetActiveUniformBlockiv entry point.
BUG=angleproject:1354
Change-Id: I2e8051910f50dc040f6be4922142364d36788c4e
Reviewed-on: https://chromium-review.googlesource.com/399041
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 961ff3c..3629f05 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -1619,44 +1619,6 @@
}
}
-void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
-{
- ASSERT(
- uniformBlockIndex <
- mState.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
-
- const UniformBlock &uniformBlock = mState.mUniformBlocks[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.isArray ? 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.vertexStaticUse);
- break;
- case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- *params = static_cast<GLint>(uniformBlock.fragmentStaticUse);
- break;
- default: UNREACHABLE();
- }
-}
-
GLint Program::getActiveUniformBlockMaxLength() const
{
int maxLength = 0;
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 93573ea..5a17e92 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -327,7 +327,6 @@
void getUniformuiv(GLint location, GLuint *params) const;
void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
- void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
GLuint getActiveUniformBlockCount() const;
GLint getActiveUniformBlockMaxLength() const;
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index 9914029..904c22f 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -17,6 +17,7 @@
#include "libANGLE/Sampler.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Texture.h"
+#include "libANGLE/Uniform.h"
#include "libANGLE/VertexAttribute.h"
namespace gl
@@ -624,6 +625,46 @@
QueryVertexAttribBase(attrib, currentValueData.UnsignedIntValues, pname, params);
}
+void QueryActiveUniformBlockiv(const Program *program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ const UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
+ switch (pname)
+ {
+ case GL_UNIFORM_BLOCK_BINDING:
+ *params = ConvertToGLint(program->getUniformBlockBinding(uniformBlockIndex));
+ break;
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ *params = ConvertToGLint(uniformBlock.dataSize);
+ break;
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ *params = ConvertToGLint(uniformBlock.nameWithArrayIndex().size() + 1);
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ *params = ConvertToGLint(uniformBlock.memberUniformIndexes.size());
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ for (size_t blockMemberIndex = 0;
+ blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
+ {
+ params[blockMemberIndex] =
+ ConvertToGLint(uniformBlock.memberUniformIndexes[blockMemberIndex]);
+ }
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ *params = ConvertToGLint(uniformBlock.vertexStaticUse);
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ *params = ConvertToGLint(uniformBlock.fragmentStaticUse);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
void SetTexParameterf(Texture *texture, GLenum pname, GLfloat param)
{
SetTexParameterBase(texture, pname, ¶m);
diff --git a/src/libANGLE/queryutils.h b/src/libANGLE/queryutils.h
index e2709e9..58c4e13 100644
--- a/src/libANGLE/queryutils.h
+++ b/src/libANGLE/queryutils.h
@@ -21,6 +21,7 @@
class Sampler;
class Shader;
class Texture;
+struct UniformBlock;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
@@ -54,6 +55,11 @@
GLenum pname,
GLuint *params);
+void QueryActiveUniformBlockiv(const Program *program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params);
+
void SetTexParameterf(Texture *texture, GLenum pname, GLfloat param);
void SetTexParameterfv(Texture *texture, GLenum pname, const GLfloat *params);
void SetTexParameteri(Texture *texture, GLenum pname, GLint param);
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 9c96f78..76815ee 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -1003,6 +1003,70 @@
return true;
}
+bool ValidateGetActiveUniformBlockivBase(Context *context,
+ GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->handleError(
+ Error(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0."));
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+ {
+ context->handleError(
+ Error(GL_INVALID_VALUE, "uniformBlockIndex exceeds active uniform block count."));
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_UNIFORM_BLOCK_BINDING:
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ break;
+
+ default:
+ context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
+ return false;
+ }
+
+ if (length)
+ {
+ if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
+ {
+ const UniformBlock &uniformBlock =
+ programObject->getUniformBlockByIndex(uniformBlockIndex);
+ *length = static_cast<GLsizei>(uniformBlock.memberUniformIndexes.size());
+ }
+ else
+ {
+ *length = 1;
+ }
+ }
+
+ return true;
+}
+
} // anonymous namespace
bool ValidTextureTarget(const ValidationContext *context, GLenum target)
@@ -4934,4 +4998,39 @@
return true;
}
+bool ValidateGetActiveUniformBlockiv(Context *context,
+ GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ return ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, nullptr);
+}
+
+bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
+ GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, bufSize))
+ {
+ return false;
+ }
+
+ if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, length))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, bufSize, *length))
+ {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace gl
diff --git a/src/libANGLE/validationES.h b/src/libANGLE/validationES.h
index de12674..8731870 100644
--- a/src/libANGLE/validationES.h
+++ b/src/libANGLE/validationES.h
@@ -511,6 +511,19 @@
GLsizei *length,
GLuint *params);
+bool ValidateGetActiveUniformBlockiv(Context *context,
+ GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params);
+bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
+ GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+
// Error messages shared here for use in testing.
extern const char *g_ExceedsMaxElementErrorMessage;
} // namespace gl
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index b4b5083..b38973c 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -2770,7 +2770,21 @@
"(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLsizei bufsize "
"= %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)",
program, uniformBlockIndex, pname, bufSize, length, params);
- UNIMPLEMENTED();
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ GLsizei writeLength = 0;
+ if (!ValidateGetActiveUniformBlockivRobustANGLE(context, program, uniformBlockIndex, pname,
+ bufSize, &writeLength, params))
+ {
+ return;
+ }
+
+ const Program *programObject = context->getProgram(program);
+ QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
+ SetRobustLengthParam(length, writeLength);
+ }
}
ANGLE_EXPORT void GL_APIENTRY GetInteger64vRobustANGLE(GLenum pname,
diff --git a/src/libGLESv2/entry_points_gles_3_0.cpp b/src/libGLESv2/entry_points_gles_3_0.cpp
index 263f916..9ab9c66 100644
--- a/src/libGLESv2/entry_points_gles_3_0.cpp
+++ b/src/libGLESv2/entry_points_gles_3_0.cpp
@@ -1624,43 +1624,14 @@
Context *context = GetValidGlobalContext();
if (context)
{
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return;
- }
- Program *programObject = GetValidProgram(context, program);
-
- if (!programObject)
+ if (!context->skipValidation() &&
+ !ValidateGetActiveUniformBlockiv(context, program, uniformBlockIndex, pname, params))
{
return;
}
- if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
- {
- context->handleError(Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (pname)
- {
- case GL_UNIFORM_BLOCK_BINDING:
- *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
- break;
-
- case GL_UNIFORM_BLOCK_DATA_SIZE:
- case GL_UNIFORM_BLOCK_NAME_LENGTH:
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
- case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
- case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- programObject->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM));
- return;
- }
+ const Program *programObject = context->getProgram(program);
+ QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
}
}