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)
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);
} // namespace gl
......
......@@ -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
void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
......@@ -396,35 +430,12 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
{
ASSERT(buffer != nullptr);
QueryBufferParameterBase(buffer, pname, params);
}
switch (pname)
{
case GL_BUFFER_USAGE:
*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 QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
{
QueryBufferParameterBase(buffer, pname, params);
}
void QueryProgramiv(const Program *program, GLenum pname, GLint *params)
......
......@@ -30,6 +30,7 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
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 QueryRenderbufferiv(const Renderbuffer *renderbuffer, GLenum pname, GLint *params);
void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params);
......
......@@ -1067,6 +1067,95 @@ bool ValidateGetActiveUniformBlockivBase(Context *context,
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
bool ValidTextureTarget(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)
{
const auto &caps = context->getCaps();
......@@ -4436,50 +4492,62 @@ bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *c
bool ValidateGetBufferParameteriv(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei *numParams)
GLint *params)
{
// Initialize result
*numParams = 0;
return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
}
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;
}
if (!ValidBufferParameter(context, pname, numParams))
if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
{
context->handleError(Error(GL_INVALID_ENUM));
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 true;
}
bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei bufSize,
GLsizei *numParams)
bool ValidateGetBufferParameteri64v(ValidationContext *context,
GLenum target,
GLenum pname,
GLint64 *params)
{
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))
{
return false;
}
if (!ValidateGetBufferParameteriv(context, target, pname, numParams))
if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
{
return false;
}
if (!ValidateRobustBufferSize(context, bufSize, *numParams))
if (!ValidateRobustBufferSize(context, bufSize, *length))
{
return false;
}
......
......@@ -372,12 +372,24 @@ bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *c
bool ValidateGetBufferParameteriv(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei *numParams);
GLint *params);
bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
GLenum target,
GLenum pname,
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 ValidateGetProgramivRobustANGLE(Context *context,
......
......@@ -1360,9 +1360,8 @@ void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params
Context *context = GetValidGlobalContext();
if (context)
{
GLsizei numParams = 0;
if (!context->skipValidation() &&
!ValidateGetBufferParameteriv(context, target, pname, &numParams))
!ValidateGetBufferParameteriv(context, target, pname, params))
{
return;
}
......
......@@ -2013,14 +2013,14 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target,
if (context)
{
GLsizei numParams = 0;
if (!ValidateGetBufferParameteriv(context, target, pname, &numParams))
if (!ValidateGetBufferParameterivRobustANGLE(context, target, pname, bufSize, &numParams,
params))
{
return;
}
Buffer *buffer = context->getGLState().getTargetBuffer(target);
QueryBufferParameteriv(buffer, pname, params);
SetRobustLengthParam(length, numParams);
}
}
......@@ -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,
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,
......
......@@ -2038,56 +2038,14 @@ void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa
Context *context = GetValidGlobalContext();
if (context)
{
if (context->getClientMajorVersion() < 3)
{
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))
if (!context->skipValidation() &&
!ValidateGetBufferParameteri64v(context, target, pname, params))
{
context->handleError(Error(GL_INVALID_ENUM));
return;
}
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));
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;
}
QueryBufferParameteri64v(buffer, pname, params);
}
}
......
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