Commit ff5b2d51 by Geoff Lang Committed by Commit Bot

Add a GL_ANGLE_robust_client_memory extension.

This allows specifying data size to all GL functions that provide a pointer to client memory and a length parameter for all functions in which the driver writes to client memory. BUG=angleproject:1354 Change-Id: Ia68be1576b957cb529c87b5e0d1bd638c7dbd371 Reviewed-on: https://chromium-review.googlesource.com/382012 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 5eeff0e4
Name
ANGLE_robust_client_memory
Name Strings
GL_ANGLE_robust_client_memory
Contributors
Geoff Lang, Google
Contacts
Geoff Lang, Google (geofflang 'at' google.com)
Status
Draft
Version
Version 1, September 26, 2016
Number
OpenGL ES Extension #??
Dependencies
OpenGL ES 2.0 is required.
This extension is written against the wording of the OpenGL ES
3.2 specification.
Interacts with GL_KHR_debug, GL_EXT_disjoint_timer_queries,
GL_KHR_robustness.
Overview
This extension adds overloads of many OpenGL ES functions that read from
and write to client memory to ensure that all reads and writes done by the
OpenGL ES implementation are safe. When the OpenGL ES API is exposed to
users through complex bindings such as WebGL, allowing undefined behaviour
that may result in crashing the implementation is not acceptable.
New Types
None
New Procedures and Functions
void GetBooleanvRobustANGLE(enum pname, sizei bufSize, sizei *length, boolean *data)
void GetBufferParameterivRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, int *params)
void GetFloatvRobustANGLE(enum pname, sizei bufSize, sizei *length, float *data)
void GetFramebufferAttachmentParameterivRobustANGLE(enum target, enum attachment, enum pname, sizei bufSize, sizei *length, int *params)
void GetIntegervRobustANGLE(enum pname, sizei bufSize, sizei *length, int *data)
void GetProgramivRobustANGLE(uint program, enum pname, sizei bufSize, sizei *length, int *params)
void GetRenderbufferParameterivRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, int *params)
void GetShaderivRobustANGLE(uint shader, enum pname, sizei bufSize, sizei *length, int *params)
void GetTexParameterfvRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, float *params)
void GetTexParameterivRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, int *params)
void GetUniformfvRobustANGLE(uint program, int location, sizei bufSize, sizei *length, float *params)
void GetUniformivRobustANGLE(uint program, int location, sizei bufSize, sizei *length, int *params)
void GetVertexAttribfvRobustANGLE(uint index, enum pname, sizei bufSize, sizei *length, float *params)
void GetVertexAttribivRobustANGLE(uint index, enum pname, sizei bufSize, sizei *length, int *params)
void GetVertexAttribPointervRobustANGLE(uint index, enum pname, sizei bufSize, sizei *length, void **pointer)
void ReadPixelsRobustANGLE(int x, int y, sizei width, sizei height, enum format, enum type, sizei bufSize, sizei *length, void *pixels)
void TexImage2DRobustANGLE(enum target, int level, int internalformat, sizei width, sizei height, int border, enum format, enum type, sizei bufSize, const void *pixels)
void TexParameterfvRobustANGLE(enum target, enum pname, sizei bufSize, const GLfloat *params)
void TexParameterivRobustANGLE(enum target, enum pname, sizei bufSize, const GLint *params)
void TexSubImage2DRobustANGLE(enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, enum type, sizei bufSize, const void *pixels)
void TexImage3DRobustANGLE(enum target, int level, int internalformat, sizei width, sizei height, sizei depth, int border, enum format, enum type, sizei bufSize, const void *pixels);
void TexSubImage3DRobustANGLE(enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, enum type, sizei bufSize, const void *pixels);
void GetQueryivRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, int *params)
void GetQueryObjectuivRobustANGLE(uint id, enum pname, sizei bufSize, sizei *length, uint *params)
void GetBufferPointervRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, void **params)
void GetIntegeri_vRobustANGLE(enum target, uint index, sizei bufSize, sizei *length, int *data)
void GetVertexAttribIivRobustANGLE(uint index, enum pname, sizei bufSize, sizei *length, int *params)
void GetVertexAttribIuivRobustANGLE(uint index, enum pname, sizei bufSize, sizei *length, uint *params)
void GetUniformuivRobustANGLE(uint program, int location, sizei bufSize, sizei *length, uint *params)
void GetActiveUniformBlockivRobustANGLE(uint program, uint uniformBlockIndex, enum pname, sizei bufSize, sizei *length, int *params)
void GetInteger64vRobustANGLE(enum pname, sizei bufSize, sizei *length, int64 *data)
void GetInteger64i_vRobustANGLE(enum target, uint index, sizei bufSize, sizei *length, int64 *data)
void GetBufferParameteri64vRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, int64 *params)
void SamplerParameterivRobustANGLE(uint sampler, enum pname, sizei bufSize, const GLint *param)
void SamplerParameterfvRobustANGLE(uint sampler, enum pname, sizei bufSize, const GLfloat *param)
void GetSamplerParameterivRobustANGLE(uint sampler, enum pname, sizei bufSize, sizei *length, int *params)
void GetSamplerParameterfvRobustANGLE(uint sampler, enum pname, sizei bufSize, sizei *length, float *params)
void GetFramebufferParameterivRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, int *params)
void GetProgramInterfaceivRobustANGLE(uint program, enum programInterface, enum pname, sizei bufSize, sizei *length, int *params)
void GetBooleani_vRobustANGLE(enum target, uint index, sizei bufSize, sizei *length, boolean *data)
void GetMultisamplefvRobustANGLE(enum pname, uint index, sizei bufSize, sizei *length, float *val)
void GetTexLevelParameterivRobustANGLE(enum target, int level, enum pname, sizei bufSize, sizei *length, int *params)
void GetTexLevelParameterfvRobustANGLE(enum target, int level, enum pname, sizei bufSize, sizei *length, float *params)
void GetPointervRobustANGLERobustANGLE(enum pname, sizei bufSize, sizei *length, void **params)
void ReadnPixelsRobustANGLE(int x, int y, sizei width, sizei height, enum format, enum type, sizei bufSize, sizei *length, void *data)
void GetnUniformfvRobustANGLE(uint program, int location, sizei bufSize, sizei *length, float *params)
void GetnUniformivRobustANGLE(uint program, int location, sizei bufSize, sizei *length, int *params)
void GetnUniformuivRobustANGLE(uint program, int location, sizei bufSize, sizei *length, uint *params)
void TexParameterIivRobustANGLE(enum target, enum pname, sizei bufSize, const GLint *params)
void TexParameterIuivRobustANGLE(enum target, enum pname, sizei bufSize, const GLuint *params)
void GetTexParameterIivRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, int *params)
void GetTexParameterIuivRobustANGLE(enum target, enum pname, sizei bufSize, sizei *length, uint *params)
void SamplerParameterIivRobustANGLE(uint sampler, enum pname, sizei bufSize, const GLint *param)
void SamplerParameterIuivRobustANGLE(uint sampler, enum pname, sizei bufSize, const GLuint *param)
void GetSamplerParameterIivRobustANGLE(uint sampler, enum pname, sizei bufSize, sizei *length, int *params)
void GetSamplerParameterIuivRobustANGLE(uint sampler, enum pname, sizei bufSize, sizei *length, uint *params)
void GetQueryObjectivRobustANGLE(uint id, enum pname, sizei bufSize, sizei *length, int *params)
void GetQueryObjecti64vRobustANGLE(uint id, enum pname, sizei bufSize, sizei *length, int64 *params)
void GetQueryObjectui64vRobustANGLE(uint id, enum pname, sizei bufSize, sizei *length, uint64 *params)
New Tokens
None
Additions to the OpenGL ES Specification:
The xRobustANGLE entry points perform additional validation using <bufSize>
to indicate the maximum number of values that can be read from or written
to the provided buffer. INVALID_OPERATION is generated if <bufSize> is not
large enough. The optional <length> specifies an address of a variable to
recieve the number of values written to the buffer. When an error is
generated 0 will be written to <length>.
Calls to "xRobustANGLE" will generate errors under the same conditions as
"x". Any instances of undefined behaviour in "x" will also be undefined in
"xRobustANGLE". For example, it is invalid to call
GetPointervRobustANGLERobustANGLE without first verifying that the context
is at least OpenGL ES version 3.2 or the GL_KHR_debug extension is present.
Issues
1) Should additional entry points be added to specify sizes of client side
data provided to the VertexAttribPointer functions?
2) Should <length> be allowed to be null?
RESOLVED: Yes, <length> will not be written to when it is a null
pointer.
3) Should <bufSize> be specified in bytes or values (uint, int, float,
etc)?
There is no consistancy in current entry points for this. For example,
glGetnUniformuiv indicates that bufSize is in bytes while GetSynciv
uses values despite GetnUniformuiv having a clear value type.
RESOLOVED: <bufSize> always indicates size in values. Functions that
specify data by void* such as TexImage2DRobustANGLE treat the client
data as bytes.
Revision History
Rev. Date Author Changes
---- ------------- --------- -------------------------------------------
1 Sept 26, 2016 geofflang Initial version
2 Sept 28, 2016 geofflang Changed name from ANGLE_robust_queries to
ANGLE_robust_client_memory, added issue 3.
...@@ -168,6 +168,7 @@ Extensions::Extensions() ...@@ -168,6 +168,7 @@ Extensions::Extensions()
copyTexture(false), copyTexture(false),
webglCompatibility(false), webglCompatibility(false),
bindGeneratesResource(false), bindGeneratesResource(false),
robustClientMemory(false),
colorBufferFloat(false), colorBufferFloat(false),
multisampleCompatibility(false), multisampleCompatibility(false),
framebufferMixedSamples(false), framebufferMixedSamples(false),
...@@ -581,6 +582,7 @@ const ExtensionInfoMap &GetExtensionInfoMap() ...@@ -581,6 +582,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture); map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture);
map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility); map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility);
map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource); map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource);
map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory);
map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibility); map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibility);
map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples); map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples);
map["GL_EXT_texture_norm16"] = esOnlyExtension(&Extensions::textureNorm16); map["GL_EXT_texture_norm16"] = esOnlyExtension(&Extensions::textureNorm16);
......
...@@ -299,6 +299,9 @@ struct Extensions ...@@ -299,6 +299,9 @@ struct Extensions
// GL_CHROMIUM_bind_generates_resource // GL_CHROMIUM_bind_generates_resource
bool bindGeneratesResource; bool bindGeneratesResource;
// GL_ANGLE_robust_client_memory
bool robustClientMemory;
// ES3 Extension support // ES3 Extension support
// GL_EXT_color_buffer_float // GL_EXT_color_buffer_float
......
...@@ -2417,6 +2417,9 @@ void Context::initCaps(bool webGLContext) ...@@ -2417,6 +2417,9 @@ void Context::initCaps(bool webGLContext)
mExtensions.maxDebugGroupStackDepth = 1024; mExtensions.maxDebugGroupStackDepth = 1024;
mExtensions.maxLabelLength = 1024; mExtensions.maxLabelLength = 1024;
// Explicitly enable GL_ANGLE_robust_client_memory
mExtensions.robustClientMemory = true;
// Apply implementation limits // Apply implementation limits
mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
......
//
// Copyright (c) 2016 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.
//
// queryutils.cpp: Utilities for querying values from GL objects
#include "libANGLE/queryutils.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Program.h"
namespace gl
{
void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
GLenum attachment,
GLenum pname,
GLint *params)
{
ASSERT(framebuffer);
const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
if (attachmentObject == nullptr)
{
// ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
// is NONE, then querying any other pname will generate INVALID_ENUM.
// ES 3.0.2 spec pg 235 states that if the attachment type is none,
// GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
// INVALID_OPERATION for all other pnames
switch (pname)
{
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
*params = GL_NONE;
break;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
*params = 0;
break;
default:
UNREACHABLE();
break;
}
return;
}
switch (pname)
{
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
*params = attachmentObject->type();
break;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
*params = attachmentObject->id();
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
*params = attachmentObject->mipLevel();
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
*params = attachmentObject->cubeMapFace();
break;
case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
*params = attachmentObject->getRedSize();
break;
case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
*params = attachmentObject->getGreenSize();
break;
case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
*params = attachmentObject->getBlueSize();
break;
case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
*params = attachmentObject->getAlphaSize();
break;
case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
*params = attachmentObject->getDepthSize();
break;
case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
*params = attachmentObject->getStencilSize();
break;
case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
*params = attachmentObject->getComponentType();
break;
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
*params = attachmentObject->getColorEncoding();
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
*params = attachmentObject->layer();
break;
default:
UNREACHABLE();
break;
}
}
void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
{
ASSERT(buffer != nullptr);
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 QueryProgramiv(const Program *program, GLenum pname, GLint *params)
{
ASSERT(program != nullptr);
switch (pname)
{
case GL_DELETE_STATUS:
*params = program->isFlaggedForDeletion();
return;
case GL_LINK_STATUS:
*params = program->isLinked();
return;
case GL_VALIDATE_STATUS:
*params = program->isValidated();
return;
case GL_INFO_LOG_LENGTH:
*params = program->getInfoLogLength();
return;
case GL_ATTACHED_SHADERS:
*params = program->getAttachedShadersCount();
return;
case GL_ACTIVE_ATTRIBUTES:
*params = program->getActiveAttributeCount();
return;
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = program->getActiveAttributeMaxLength();
return;
case GL_ACTIVE_UNIFORMS:
*params = program->getActiveUniformCount();
return;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
*params = program->getActiveUniformMaxLength();
return;
case GL_PROGRAM_BINARY_LENGTH_OES:
*params = program->getBinaryLength();
return;
case GL_ACTIVE_UNIFORM_BLOCKS:
*params = program->getActiveUniformBlockCount();
return;
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
*params = program->getActiveUniformBlockMaxLength();
break;
case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
*params = program->getTransformFeedbackBufferMode();
break;
case GL_TRANSFORM_FEEDBACK_VARYINGS:
*params = program->getTransformFeedbackVaryingCount();
break;
case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
*params = program->getTransformFeedbackVaryingMaxLength();
break;
case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
*params = program->getBinaryRetrievableHint();
break;
default:
UNREACHABLE();
break;
}
}
}
//
// Copyright (c) 2016 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.
//
// queryutils.h: Utilities for querying values from GL objects
#ifndef LIBANGLE_QUERYUTILS_H_
#define LIBANGLE_QUERYUTILS_H_
#include "angle_gl.h"
#include "common/angleutils.h"
namespace gl
{
class Buffer;
class Framebuffer;
class Program;
void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
GLenum attachment,
GLenum pname,
GLint *params);
void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params);
void QueryProgramiv(const Program *program, GLenum pname, GLint *params);
}
#endif // LIBANGLE_QUERYUTILS_H_
...@@ -37,7 +37,7 @@ bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum ta ...@@ -37,7 +37,7 @@ bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum ta
bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target); bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target);
bool ValidFramebufferTarget(GLenum target); bool ValidFramebufferTarget(GLenum target);
bool ValidBufferTarget(const ValidationContext *context, GLenum target); bool ValidBufferTarget(const ValidationContext *context, GLenum target);
bool ValidBufferParameter(const Context *context, GLenum pname); bool ValidBufferParameter(const ValidationContext *context, GLenum pname, GLsizei *numParams);
bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level); bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level);
bool ValidImageSizeParameters(const Context *context, bool ValidImageSizeParameters(const Context *context,
GLenum target, GLenum target,
...@@ -50,6 +50,16 @@ bool ValidCompressedImageSize(const ValidationContext *context, ...@@ -50,6 +50,16 @@ bool ValidCompressedImageSize(const ValidationContext *context,
GLenum internalFormat, GLenum internalFormat,
GLsizei width, GLsizei width,
GLsizei height); GLsizei height);
bool ValidImageDataSize(ValidationContext *context,
GLenum textureTarget,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum internalFormat,
GLenum type,
const GLvoid *pixels,
GLsizei imageSize);
bool ValidQueryType(const Context *context, GLenum queryType); bool ValidQueryType(const Context *context, GLenum queryType);
// Returns valid program if id is a valid program name // Returns valid program if id is a valid program name
...@@ -131,6 +141,12 @@ bool ValidateStateQuery(ValidationContext *context, ...@@ -131,6 +141,12 @@ bool ValidateStateQuery(ValidationContext *context,
GLenum *nativeType, GLenum *nativeType,
unsigned int *numParams); unsigned int *numParams);
bool ValidateRobustStateQuery(ValidationContext *context,
GLenum pname,
GLsizei bufSize,
GLenum *nativeType,
unsigned int *numParams);
bool ValidateCopyTexImageParametersBase(ValidationContext *context, bool ValidateCopyTexImageParametersBase(ValidationContext *context,
GLenum target, GLenum target,
GLint level, GLint level,
...@@ -273,6 +289,37 @@ bool ValidateEnable(Context *context, GLenum cap); ...@@ -273,6 +289,37 @@ bool ValidateEnable(Context *context, GLenum cap);
bool ValidateDisable(Context *context, GLenum cap); bool ValidateDisable(Context *context, GLenum cap);
bool ValidateIsEnabled(Context *context, GLenum cap); bool ValidateIsEnabled(Context *context, GLenum cap);
bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize);
bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
GLenum target,
GLenum attachment,
GLenum pname,
GLsizei *numParams);
bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context,
GLenum target,
GLenum attachment,
GLenum pname,
GLsizei bufSize,
GLsizei *numParams);
bool ValidateGetBufferParameteriv(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei *numParams);
bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
GLenum target,
GLenum pname,
GLsizei bufSize,
GLsizei *numParams);
bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLsizei *numParams);
bool ValidateGetProgramivRobustANGLE(Context *context,
GLuint program,
GLenum pname,
GLsizei bufSize,
GLsizei *numParams);
// Error messages shared here for use in testing. // Error messages shared here for use in testing.
extern const char *g_ExceedsMaxElementErrorMessage; extern const char *g_ExceedsMaxElementErrorMessage;
} // namespace gl } // namespace gl
......
...@@ -285,9 +285,21 @@ bool IsValidCopyTextureSourceTarget(Context *context, GLenum target) ...@@ -285,9 +285,21 @@ bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
} // anonymous namespace } // anonymous namespace
bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, bool ValidateES2TexImageParameters(Context *context,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum target,
GLint border, GLenum format, GLenum type, const GLvoid *pixels) GLint level,
GLenum internalformat,
bool isCompressed,
bool isSubImage,
GLint xoffset,
GLint yoffset,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
GLsizei imageSize,
const GLvoid *pixels)
{ {
if (!ValidTexture2DDestinationTarget(context, target)) if (!ValidTexture2DDestinationTarget(context, target))
{ {
...@@ -692,6 +704,12 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, ...@@ -692,6 +704,12 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level,
} }
} }
if (!ValidImageDataSize(context, target, width, height, 1, internalformat, type, pixels,
imageSize))
{
return false;
}
return true; return true;
} }
...@@ -1962,12 +1980,43 @@ bool ValidateTexImage2D(Context *context, ...@@ -1962,12 +1980,43 @@ bool ValidateTexImage2D(Context *context,
if (context->getClientMajorVersion() < 3) if (context->getClientMajorVersion() < 3)
{ {
return ValidateES2TexImageParameters(context, target, level, internalformat, false, false, return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
0, 0, width, height, border, format, type, pixels); 0, 0, width, height, border, format, type, -1, pixels);
}
ASSERT(context->getClientMajorVersion() >= 3);
return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
0, 0, width, height, 1, border, format, type, -1,
pixels);
}
bool ValidateTexImage2DRobust(Context *context,
GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
GLsizei bufSize,
const GLvoid *pixels)
{
if (!ValidateRobustEntryPoint(context, bufSize))
{
return false;
}
if (context->getClientMajorVersion() < 3)
{
return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
0, 0, width, height, border, format, type, bufSize,
pixels);
} }
ASSERT(context->getClientMajorVersion() >= 3); ASSERT(context->getClientMajorVersion() >= 3);
return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0, return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
0, 0, width, height, 1, border, format, type, pixels); 0, 0, width, height, 1, border, format, type, bufSize,
pixels);
} }
bool ValidateTexSubImage2D(Context *context, bool ValidateTexSubImage2D(Context *context,
...@@ -1985,12 +2034,13 @@ bool ValidateTexSubImage2D(Context *context, ...@@ -1985,12 +2034,13 @@ bool ValidateTexSubImage2D(Context *context,
if (context->getClientMajorVersion() < 3) if (context->getClientMajorVersion() < 3)
{ {
return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset, return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
yoffset, width, height, 0, format, type, pixels); yoffset, width, height, 0, format, type, -1, pixels);
} }
ASSERT(context->getClientMajorVersion() >= 3); ASSERT(context->getClientMajorVersion() >= 3);
return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset, return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
yoffset, 0, width, height, 1, 0, format, type, pixels); yoffset, 0, width, height, 1, 0, format, type, -1,
pixels);
} }
bool ValidateCompressedTexImage2D(Context *context, bool ValidateCompressedTexImage2D(Context *context,
...@@ -2006,7 +2056,7 @@ bool ValidateCompressedTexImage2D(Context *context, ...@@ -2006,7 +2056,7 @@ bool ValidateCompressedTexImage2D(Context *context,
if (context->getClientMajorVersion() < 3) if (context->getClientMajorVersion() < 3)
{ {
if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0, if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
0, width, height, border, GL_NONE, GL_NONE, data)) 0, width, height, border, GL_NONE, GL_NONE, -1, data))
{ {
return false; return false;
} }
...@@ -2015,7 +2065,7 @@ bool ValidateCompressedTexImage2D(Context *context, ...@@ -2015,7 +2065,7 @@ bool ValidateCompressedTexImage2D(Context *context,
{ {
ASSERT(context->getClientMajorVersion() >= 3); ASSERT(context->getClientMajorVersion() >= 3);
if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0, if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
0, 0, width, height, 1, border, GL_NONE, GL_NONE, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
data)) data))
{ {
return false; return false;
...@@ -2054,7 +2104,7 @@ bool ValidateCompressedTexSubImage2D(Context *context, ...@@ -2054,7 +2104,7 @@ bool ValidateCompressedTexSubImage2D(Context *context,
if (context->getClientMajorVersion() < 3) if (context->getClientMajorVersion() < 3)
{ {
if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset, if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
yoffset, width, height, 0, GL_NONE, GL_NONE, data)) yoffset, width, height, 0, GL_NONE, GL_NONE, -1, data))
{ {
return false; return false;
} }
...@@ -2063,7 +2113,7 @@ bool ValidateCompressedTexSubImage2D(Context *context, ...@@ -2063,7 +2113,7 @@ bool ValidateCompressedTexSubImage2D(Context *context,
{ {
ASSERT(context->getClientMajorVersion() >= 3); ASSERT(context->getClientMajorVersion() >= 3);
if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset, if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, -1,
data)) data))
{ {
return false; return false;
......
...@@ -18,9 +18,21 @@ class Context; ...@@ -18,9 +18,21 @@ class Context;
class ValidationContext; class ValidationContext;
class Texture; class Texture;
bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, bool ValidateES2TexImageParameters(Context *context,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum target,
GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLint level,
GLenum internalformat,
bool isCompressed,
bool isSubImage,
GLint xoffset,
GLint yoffset,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
GLsizei imageSize,
const GLvoid *pixels);
bool ValidateES2CopyTexImageParameters(ValidationContext *context, bool ValidateES2CopyTexImageParameters(ValidationContext *context,
GLenum target, GLenum target,
...@@ -137,6 +149,17 @@ bool ValidateTexImage2D(Context *context, ...@@ -137,6 +149,17 @@ bool ValidateTexImage2D(Context *context,
GLenum format, GLenum format,
GLenum type, GLenum type,
const GLvoid *pixels); const GLvoid *pixels);
bool ValidateTexImage2DRobust(Context *context,
GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
GLsizei bufSize,
const GLvoid *pixels);
bool ValidateTexSubImage2D(Context *context, bool ValidateTexSubImage2D(Context *context,
GLenum target, GLenum target,
GLint level, GLint level,
......
...@@ -297,6 +297,7 @@ bool ValidateES3TexImageParametersBase(Context *context, ...@@ -297,6 +297,7 @@ bool ValidateES3TexImageParametersBase(Context *context,
GLint border, GLint border,
GLenum format, GLenum format,
GLenum type, GLenum type,
GLsizei imageSize,
const GLvoid *pixels) const GLvoid *pixels)
{ {
// Validate image size // Validate image size
...@@ -475,43 +476,24 @@ bool ValidateES3TexImageParametersBase(Context *context, ...@@ -475,43 +476,24 @@ bool ValidateES3TexImageParametersBase(Context *context,
} }
} }
if (!ValidImageDataSize(context, target, width, height, 1, actualInternalFormat, type, pixels,
imageSize))
{
return false;
}
// Check for pixel unpack buffer related API errors // Check for pixel unpack buffer related API errors
gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER); gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
if (pixelUnpackBuffer != nullptr) if (pixelUnpackBuffer != nullptr)
{ {
// ...the data would be unpacked from the buffer object such that the memory reads required
// would exceed the data store size.
GLenum sizedFormat = GetSizedInternalFormat(actualInternalFormat, type);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat);
const gl::Extents size(width, height, depth);
const auto &unpack = context->getGLState().getUnpackState();
bool targetIs3D = target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D);
if (endByteOrErr.isError())
{
context->handleError(endByteOrErr.getError());
return false;
}
CheckedNumeric<size_t> checkedEndByte(endByteOrErr.getResult());
CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
checkedEndByte += checkedOffset;
if (!checkedEndByte.IsValid() ||
(checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
{
// Overflow past the end of the buffer
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
// ...data is not evenly divisible into the number of bytes needed to store in memory a datum // ...data is not evenly divisible into the number of bytes needed to store in memory a datum
// indicated by type. // indicated by type.
if (!isCompressed) if (!isCompressed)
{ {
size_t offset = reinterpret_cast<size_t>(pixels);
size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes); size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
if ((checkedOffset.ValueOrDie() % dataBytesPerPixel) != 0) if ((offset % dataBytesPerPixel) != 0)
{ {
context->handleError( context->handleError(
Error(GL_INVALID_OPERATION, "Reads would overflow the pixel unpack buffer.")); Error(GL_INVALID_OPERATION, "Reads would overflow the pixel unpack buffer."));
...@@ -545,6 +527,7 @@ bool ValidateES3TexImage2DParameters(Context *context, ...@@ -545,6 +527,7 @@ bool ValidateES3TexImage2DParameters(Context *context,
GLint border, GLint border,
GLenum format, GLenum format,
GLenum type, GLenum type,
GLsizei imageSize,
const GLvoid *pixels) const GLvoid *pixels)
{ {
if (!ValidTexture2DDestinationTarget(context, target)) if (!ValidTexture2DDestinationTarget(context, target))
...@@ -555,7 +538,7 @@ bool ValidateES3TexImage2DParameters(Context *context, ...@@ -555,7 +538,7 @@ bool ValidateES3TexImage2DParameters(Context *context,
return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed,
isSubImage, xoffset, yoffset, zoffset, width, height, isSubImage, xoffset, yoffset, zoffset, width, height,
depth, border, format, type, pixels); depth, border, format, type, imageSize, pixels);
} }
bool ValidateES3TexImage3DParameters(Context *context, bool ValidateES3TexImage3DParameters(Context *context,
...@@ -583,7 +566,7 @@ bool ValidateES3TexImage3DParameters(Context *context, ...@@ -583,7 +566,7 @@ bool ValidateES3TexImage3DParameters(Context *context,
return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed,
isSubImage, xoffset, yoffset, zoffset, width, height, isSubImage, xoffset, yoffset, zoffset, width, height,
depth, border, format, type, pixels); depth, border, format, type, -1, pixels);
} }
struct EffectiveInternalFormatInfo struct EffectiveInternalFormatInfo
......
...@@ -32,6 +32,7 @@ bool ValidateES3TexImageParametersBase(ValidationContext *context, ...@@ -32,6 +32,7 @@ bool ValidateES3TexImageParametersBase(ValidationContext *context,
GLint border, GLint border,
GLenum format, GLenum format,
GLenum type, GLenum type,
GLsizei imageSize,
const GLvoid *pixels); const GLvoid *pixels);
bool ValidateES3TexStorageParameters(Context *context, bool ValidateES3TexStorageParameters(Context *context,
...@@ -57,6 +58,7 @@ bool ValidateES3TexImage2DParameters(Context *context, ...@@ -57,6 +58,7 @@ bool ValidateES3TexImage2DParameters(Context *context,
GLint border, GLint border,
GLenum format, GLenum format,
GLenum type, GLenum type,
GLsizei imageSize,
const GLvoid *pixels); const GLvoid *pixels);
bool ValidateES3TexImage3DParameters(Context *context, bool ValidateES3TexImage3DParameters(Context *context,
......
...@@ -158,6 +158,8 @@ ...@@ -158,6 +158,8 @@
'libANGLE/histogram_macros.h', 'libANGLE/histogram_macros.h',
'libANGLE/queryconversions.cpp', 'libANGLE/queryconversions.cpp',
'libANGLE/queryconversions.h', 'libANGLE/queryconversions.h',
'libANGLE/queryutils.cpp',
'libANGLE/queryutils.h',
'libANGLE/renderer/BufferImpl.h', 'libANGLE/renderer/BufferImpl.h',
'libANGLE/renderer/CompilerImpl.h', 'libANGLE/renderer/CompilerImpl.h',
'libANGLE/renderer/ContextImpl.cpp', 'libANGLE/renderer/ContextImpl.cpp',
......
...@@ -1475,6 +1475,67 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char * ...@@ -1475,6 +1475,67 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *
// GL_ANGLE_webgl_compatibility // GL_ANGLE_webgl_compatibility
INSERT_PROC_ADDRESS(gl, EnableExtensionANGLE); INSERT_PROC_ADDRESS(gl, EnableExtensionANGLE);
// GL_ANGLE_robust_client_memory
INSERT_PROC_ADDRESS(gl, GetBooleanvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetBufferParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetFloatvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetIntegervRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetProgramivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetRenderbufferParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetShaderivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetTexParameterfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetTexParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetUniformfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetUniformivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetVertexAttribfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetVertexAttribivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetVertexAttribPointervRobustANGLE);
INSERT_PROC_ADDRESS(gl, ReadPixelsRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexImage2DRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexParameterfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexSubImage2DRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexImage3DRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexSubImage3DRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetQueryivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetQueryObjectuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetBufferPointervRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetIntegeri_vRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetVertexAttribIivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetVertexAttribIuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetUniformuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetInteger64vRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetInteger64i_vRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetBufferParameteri64vRobustANGLE);
INSERT_PROC_ADDRESS(gl, SamplerParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, SamplerParameterfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetSamplerParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetSamplerParameterfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetFramebufferParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetProgramInterfaceivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetBooleani_vRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetMultisamplefvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetTexLevelParameterivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetPointervRobustANGLERobustANGLE);
INSERT_PROC_ADDRESS(gl, ReadnPixelsRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetnUniformfvRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetnUniformivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetnUniformuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexParameterIivRobustANGLE);
INSERT_PROC_ADDRESS(gl, TexParameterIuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetTexParameterIivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetTexParameterIuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, SamplerParameterIivRobustANGLE);
INSERT_PROC_ADDRESS(gl, SamplerParameterIuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetSamplerParameterIivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetSamplerParameterIuivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetQueryObjectivRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vRobustANGLE);
INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vRobustANGLE);
// GLES3 core // GLES3 core
INSERT_PROC_ADDRESS(gl, ReadBuffer); INSERT_PROC_ADDRESS(gl, ReadBuffer);
INSERT_PROC_ADDRESS(gl, DrawRangeElements); INSERT_PROC_ADDRESS(gl, DrawRangeElements);
......
...@@ -2125,7 +2125,8 @@ void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa ...@@ -2125,7 +2125,8 @@ void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa
return; return;
} }
if (!ValidBufferParameter(context, pname)) GLsizei numParams = 0;
if (!ValidBufferParameter(context, pname, &numParams))
{ {
context->handleError(Error(GL_INVALID_ENUM)); context->handleError(Error(GL_INVALID_ENUM));
return; return;
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
'<(angle_path)/src/tests/gl_tests/ProgramBinaryTest.cpp', '<(angle_path)/src/tests/gl_tests/ProgramBinaryTest.cpp',
'<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp', '<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp',
'<(angle_path)/src/tests/gl_tests/RendererTest.cpp', '<(angle_path)/src/tests/gl_tests/RendererTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustClientMemoryTest.cpp',
'<(angle_path)/src/tests/gl_tests/SimpleOperationTest.cpp', '<(angle_path)/src/tests/gl_tests/SimpleOperationTest.cpp',
'<(angle_path)/src/tests/gl_tests/SixteenBppTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/SixteenBppTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/SRGBTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/SRGBTextureTest.cpp',
......
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