Commit ebebe1c7 by Geoff Lang Committed by Commit Bot

Implement robust GetBufferParameter entry points.

BUG=angleproject:1354 Change-Id: I979c8768975380dba7f0b256b2729b2147ff7984 Reviewed-on: https://chromium-review.googlesource.com/399042 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 6899b87f
...@@ -132,6 +132,12 @@ ParamType ConvertFromGLboolean(GLboolean param) ...@@ -132,6 +132,12 @@ ParamType ConvertFromGLboolean(GLboolean param)
return static_cast<ParamType>(param ? GL_TRUE : GL_FALSE); return static_cast<ParamType>(param ? GL_TRUE : GL_FALSE);
} }
template <typename ParamType>
ParamType ConvertFromGLint64(GLint64 param)
{
return clampCast<ParamType>(param);
}
unsigned int ParseAndStripArrayIndex(std::string *name); unsigned int ParseAndStripArrayIndex(std::string *name);
} // namespace gl } // namespace gl
......
...@@ -297,6 +297,40 @@ void QueryVertexAttribBase(const VertexAttribute &attrib, ...@@ -297,6 +297,40 @@ void QueryVertexAttribBase(const VertexAttribute &attrib,
} }
} }
template <typename ParamType>
void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
{
ASSERT(buffer != nullptr);
switch (pname)
{
case GL_BUFFER_USAGE:
*params = ConvertFromGLenum<ParamType>(buffer->getUsage());
break;
case GL_BUFFER_SIZE:
*params = ConvertFromGLint64<ParamType>(buffer->getSize());
break;
case GL_BUFFER_ACCESS_FLAGS:
*params = ConvertFromGLuint<ParamType>(buffer->getAccessFlags());
break;
case GL_BUFFER_ACCESS_OES:
*params = ConvertFromGLenum<ParamType>(buffer->getAccess());
break;
case GL_BUFFER_MAPPED:
*params = ConvertFromGLboolean<ParamType>(buffer->isMapped());
break;
case GL_BUFFER_MAP_OFFSET:
*params = ConvertFromGLint64<ParamType>(buffer->getMapOffset());
break;
case GL_BUFFER_MAP_LENGTH:
*params = ConvertFromGLint64<ParamType>(buffer->getMapLength());
break;
default:
UNREACHABLE();
break;
}
}
} // anonymous namespace } // anonymous namespace
void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
...@@ -396,35 +430,12 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, ...@@ -396,35 +430,12 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params) void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
{ {
ASSERT(buffer != nullptr); QueryBufferParameterBase(buffer, pname, params);
}
switch (pname) void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
{ {
case GL_BUFFER_USAGE: QueryBufferParameterBase(buffer, pname, params);
*params = static_cast<GLint>(buffer->getUsage());
break;
case GL_BUFFER_SIZE:
*params = clampCast<GLint>(buffer->getSize());
break;
case GL_BUFFER_ACCESS_FLAGS:
*params = buffer->getAccessFlags();
break;
case GL_BUFFER_ACCESS_OES:
*params = buffer->getAccess();
break;
case GL_BUFFER_MAPPED:
*params = static_cast<GLint>(buffer->isMapped());
break;
case GL_BUFFER_MAP_OFFSET:
*params = clampCast<GLint>(buffer->getMapOffset());
break;
case GL_BUFFER_MAP_LENGTH:
*params = clampCast<GLint>(buffer->getMapLength());
break;
default:
UNREACHABLE();
break;
}
} }
void QueryProgramiv(const Program *program, GLenum pname, GLint *params) void QueryProgramiv(const Program *program, GLenum pname, GLint *params)
......
...@@ -30,6 +30,7 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, ...@@ -30,6 +30,7 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
GLenum pname, GLenum pname,
GLint *params); GLint *params);
void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params); void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params);
void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params);
void QueryProgramiv(const Program *program, GLenum pname, GLint *params); void QueryProgramiv(const Program *program, GLenum pname, GLint *params);
void QueryRenderbufferiv(const Renderbuffer *renderbuffer, GLenum pname, GLint *params); void QueryRenderbufferiv(const Renderbuffer *renderbuffer, GLenum pname, GLint *params);
void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params); void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params);
......
...@@ -1067,6 +1067,95 @@ bool ValidateGetActiveUniformBlockivBase(Context *context, ...@@ -1067,6 +1067,95 @@ bool ValidateGetActiveUniformBlockivBase(Context *context,
return true; return true;
} }
bool ValidateGetBufferParameterBase(ValidationContext *context,
GLenum target,
GLenum pname,
bool pointerVersion,
GLsizei *numParams)
{
if (numParams)
{
*numParams = 0;
}
if (!ValidBufferTarget(context, target))
{
context->handleError(Error(GL_INVALID_ENUM, "Invalid buffer target."));
return false;
}
const Buffer *buffer = context->getGLState().getTargetBuffer(target);
if (!buffer)
{
// A null buffer means that "0" is bound to the requested buffer target
context->handleError(Error(GL_INVALID_OPERATION, "No buffer bound."));
return false;
}
const Extensions &extensions = context->getExtensions();
switch (pname)
{
case GL_BUFFER_USAGE:
case GL_BUFFER_SIZE:
break;
case GL_BUFFER_ACCESS_OES:
if (!extensions.mapBuffer)
{
context->handleError(
Error(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_OES_map_buffer."));
return false;
}
break;
case GL_BUFFER_MAPPED:
static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
!extensions.mapBufferRange)
{
context->handleError(Error(
GL_INVALID_ENUM,
"pname requires OpenGL ES 3.0, GL_OES_map_buffer or GL_EXT_map_buffer_range."));
return false;
}
break;
case GL_BUFFER_MAP_POINTER:
if (!pointerVersion)
{
context->handleError(
Error(GL_INVALID_ENUM,
"GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv."));
return false;
}
break;
case GL_BUFFER_ACCESS_FLAGS:
case GL_BUFFER_MAP_OFFSET:
case GL_BUFFER_MAP_LENGTH:
if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
{
context->handleError(Error(
GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range."));
return false;
}
break;
default:
context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
return false;
}
// All buffer parameter queries return one value.
if (numParams)
{
*numParams = 1;
}
return true;
}
} // anonymous namespace } // anonymous namespace
bool ValidTextureTarget(const ValidationContext *context, GLenum target) bool ValidTextureTarget(const ValidationContext *context, GLenum target)
...@@ -1192,39 +1281,6 @@ bool ValidBufferTarget(const ValidationContext *context, GLenum target) ...@@ -1192,39 +1281,6 @@ bool ValidBufferTarget(const ValidationContext *context, GLenum target)
} }
} }
bool ValidBufferParameter(const ValidationContext *context, GLenum pname, GLsizei *numParams)
{
// All buffer parameter queries return one value.
*numParams = 1;
const Extensions &extensions = context->getExtensions();
switch (pname)
{
case GL_BUFFER_USAGE:
case GL_BUFFER_SIZE:
return true;
case GL_BUFFER_ACCESS_OES:
return extensions.mapBuffer;
case GL_BUFFER_MAPPED:
static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
return (context->getClientMajorVersion() >= 3) || extensions.mapBuffer ||
extensions.mapBufferRange;
// GL_BUFFER_MAP_POINTER is a special case, and may only be
// queried with GetBufferPointerv
case GL_BUFFER_ACCESS_FLAGS:
case GL_BUFFER_MAP_OFFSET:
case GL_BUFFER_MAP_LENGTH:
return (context->getClientMajorVersion() >= 3) || extensions.mapBufferRange;
default:
return false;
}
}
bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level) bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level)
{ {
const auto &caps = context->getCaps(); const auto &caps = context->getCaps();
...@@ -4436,50 +4492,62 @@ bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *c ...@@ -4436,50 +4492,62 @@ bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *c
bool ValidateGetBufferParameteriv(ValidationContext *context, bool ValidateGetBufferParameteriv(ValidationContext *context,
GLenum target, GLenum target,
GLenum pname, GLenum pname,
GLsizei *numParams) GLint *params)
{ {
// Initialize result return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
*numParams = 0; }
if (!ValidBufferTarget(context, target)) bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei bufSize,
GLsizei *length,
GLint *params)
{
if (!ValidateRobustEntryPoint(context, bufSize))
{ {
context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
if (!ValidBufferParameter(context, pname, numParams)) if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
{ {
context->handleError(Error(GL_INVALID_ENUM));
return false; return false;
} }
if (context->getGLState().getTargetBuffer(target) == nullptr) if (!ValidateRobustBufferSize(context, bufSize, *length))
{ {
// A null buffer means that "0" is bound to the requested buffer target
context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
return true; return true;
} }
bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context, bool ValidateGetBufferParameteri64v(ValidationContext *context,
GLenum target, GLenum target,
GLenum pname, GLenum pname,
GLsizei bufSize, GLint64 *params)
GLsizei *numParams) {
return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
}
bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei bufSize,
GLsizei *length,
GLint64 *params)
{ {
if (!ValidateRobustEntryPoint(context, bufSize)) if (!ValidateRobustEntryPoint(context, bufSize))
{ {
return false; return false;
} }
if (!ValidateGetBufferParameteriv(context, target, pname, numParams)) if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
{ {
return false; return false;
} }
if (!ValidateRobustBufferSize(context, bufSize, *numParams)) if (!ValidateRobustBufferSize(context, bufSize, *length))
{ {
return false; return false;
} }
......
...@@ -372,12 +372,24 @@ bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *c ...@@ -372,12 +372,24 @@ bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *c
bool ValidateGetBufferParameteriv(ValidationContext *context, bool ValidateGetBufferParameteriv(ValidationContext *context,
GLenum target, GLenum target,
GLenum pname, GLenum pname,
GLsizei *numParams); GLint *params);
bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context, bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
GLenum target, GLenum target,
GLenum pname, GLenum pname,
GLsizei bufSize, GLsizei bufSize,
GLsizei *numParams); GLsizei *length,
GLint *params);
bool ValidateGetBufferParameteri64v(ValidationContext *context,
GLenum target,
GLenum pname,
GLint64 *params);
bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei bufSize,
GLsizei *length,
GLint64 *params);
bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLsizei *numParams); bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLsizei *numParams);
bool ValidateGetProgramivRobustANGLE(Context *context, bool ValidateGetProgramivRobustANGLE(Context *context,
......
...@@ -1360,9 +1360,8 @@ void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params ...@@ -1360,9 +1360,8 @@ void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) if (context)
{ {
GLsizei numParams = 0;
if (!context->skipValidation() && if (!context->skipValidation() &&
!ValidateGetBufferParameteriv(context, target, pname, &numParams)) !ValidateGetBufferParameteriv(context, target, pname, params))
{ {
return; return;
} }
......
...@@ -2013,14 +2013,14 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target, ...@@ -2013,14 +2013,14 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target,
if (context) if (context)
{ {
GLsizei numParams = 0; GLsizei numParams = 0;
if (!ValidateGetBufferParameteriv(context, target, pname, &numParams)) if (!ValidateGetBufferParameterivRobustANGLE(context, target, pname, bufSize, &numParams,
params))
{ {
return; return;
} }
Buffer *buffer = context->getGLState().getTargetBuffer(target); Buffer *buffer = context->getGLState().getTargetBuffer(target);
QueryBufferParameteriv(buffer, pname, params); QueryBufferParameteriv(buffer, pname, params);
SetRobustLengthParam(length, numParams); SetRobustLengthParam(length, numParams);
} }
} }
...@@ -2852,7 +2852,21 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target, ...@@ -2852,7 +2852,21 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target,
{ {
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", target, pname, EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", target, pname,
bufSize, length, params); bufSize, length, params);
UNIMPLEMENTED();
Context *context = GetValidGlobalContext();
if (context)
{
GLsizei numParams = 0;
if (!ValidateGetBufferParameteri64vRobustANGLE(context, target, pname, bufSize, &numParams,
params))
{
return;
}
Buffer *buffer = context->getGLState().getTargetBuffer(target);
QueryBufferParameteri64v(buffer, pname, params);
SetRobustLengthParam(length, numParams);
}
} }
ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler, ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler,
......
...@@ -2038,56 +2038,14 @@ void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa ...@@ -2038,56 +2038,14 @@ void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) if (context)
{ {
if (context->getClientMajorVersion() < 3) if (!context->skipValidation() &&
{ !ValidateGetBufferParameteri64v(context, target, pname, params))
context->handleError(Error(GL_INVALID_OPERATION));
return;
}
if (!ValidBufferTarget(context, target))
{
context->handleError(Error(GL_INVALID_ENUM));
return;
}
GLsizei numParams = 0;
if (!ValidBufferParameter(context, pname, &numParams))
{ {
context->handleError(Error(GL_INVALID_ENUM));
return; return;
} }
Buffer *buffer = context->getGLState().getTargetBuffer(target); Buffer *buffer = context->getGLState().getTargetBuffer(target);
QueryBufferParameteri64v(buffer, pname, params);
if (!buffer)
{
// A null buffer means that "0" is bound to the requested buffer target
context->handleError(Error(GL_INVALID_OPERATION));
return;
}
switch (pname)
{
case GL_BUFFER_USAGE:
*params = static_cast<GLint64>(buffer->getUsage());
break;
case GL_BUFFER_SIZE:
*params = buffer->getSize();
break;
case GL_BUFFER_ACCESS_FLAGS:
*params = static_cast<GLint64>(buffer->getAccessFlags());
break;
case GL_BUFFER_MAPPED:
*params = static_cast<GLint64>(buffer->isMapped());
break;
case GL_BUFFER_MAP_OFFSET:
*params = buffer->getMapOffset();
break;
case GL_BUFFER_MAP_LENGTH:
*params = buffer->getMapLength();
break;
default: UNREACHABLE(); break;
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment