Commit bc781f31 by Austin Kinross Committed by Jamie Madill

Re-re-land "Add GL_OES_vertex_array_object to D3D11 and GL renderers"

+ Include fixed validation logic for GL_UNPACK_SKIP_IMAGES and GL_UNPACK_ROW_LENGTH + Include fix for Clang build break BUG=angleproject:1186 Change-Id: I403a066e29614f532db6931755265d2ee088d442 Reviewed-on: https://chromium-review.googlesource.com/308746Tested-by: 's avatarAustin Kinross <aukinros@microsoft.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 5296141b
......@@ -141,6 +141,7 @@ Extensions::Extensions()
eglImageExternalEssl3(false),
unpackSubimage(false),
packSubimage(false),
vertexArrayObject(false),
colorBufferFloat(false)
{
}
......@@ -201,6 +202,7 @@ std::vector<std::string> Extensions::getStrings() const
InsertExtensionString("GL_EXT_unpack_subimage", unpackSubimage, &extensionStrings);
InsertExtensionString("GL_NV_pack_subimage", packSubimage, &extensionStrings);
InsertExtensionString("GL_EXT_color_buffer_float", colorBufferFloat, &extensionStrings);
InsertExtensionString("GL_OES_vertex_array_object", vertexArrayObject, &extensionStrings);
// clang-format on
return extensionStrings;
......
......@@ -239,6 +239,9 @@ struct Extensions
// NV_pack_subimage
bool packSubimage;
// GL_OES_vertex_array_object
bool vertexArrayObject;
// ES3 Extension support
// GL_EXT_color_buffer_float
......
......@@ -1107,26 +1107,6 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
}
}
return true;
case GL_PACK_ROW_LENGTH:
case GL_PACK_SKIP_ROWS:
case GL_PACK_SKIP_PIXELS:
if ((mClientVersion < 3) && !mExtensions.packSubimage)
{
return false;
}
*type = GL_INT;
*numParams = 1;
return true;
case GL_UNPACK_ROW_LENGTH:
case GL_UNPACK_SKIP_ROWS:
case GL_UNPACK_SKIP_PIXELS:
if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
{
return false;
}
*type = GL_INT;
*numParams = 1;
return true;
case GL_MAX_VIEWPORT_DIMS:
{
*type = GL_INT;
......@@ -1199,6 +1179,39 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
return true;
}
// Check for ES3.0+ parameter names which are also exposed as ES2 extensions
switch (pname)
{
case GL_PACK_ROW_LENGTH:
case GL_PACK_SKIP_ROWS:
case GL_PACK_SKIP_PIXELS:
if ((mClientVersion < 3) && !mExtensions.packSubimage)
{
return false;
}
*type = GL_INT;
*numParams = 1;
return true;
case GL_UNPACK_ROW_LENGTH:
case GL_UNPACK_SKIP_ROWS:
case GL_UNPACK_SKIP_PIXELS:
if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
{
return false;
}
*type = GL_INT;
*numParams = 1;
return true;
case GL_VERTEX_ARRAY_BINDING:
if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
{
return false;
}
*type = GL_INT;
*numParams = 1;
return true;
}
if (mClientVersion < 3)
{
return false;
......@@ -1224,7 +1237,6 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
case GL_MAX_VARYING_COMPONENTS:
case GL_VERTEX_ARRAY_BINDING:
case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
case GL_MIN_PROGRAM_TEXEL_OFFSET:
......@@ -1237,14 +1249,8 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
case GL_PACK_ROW_LENGTH:
case GL_PACK_SKIP_ROWS:
case GL_PACK_SKIP_PIXELS:
case GL_UNPACK_ROW_LENGTH:
case GL_UNPACK_IMAGE_HEIGHT:
case GL_UNPACK_SKIP_IMAGES:
case GL_UNPACK_SKIP_ROWS:
case GL_UNPACK_SKIP_PIXELS:
{
*type = GL_INT;
*numParams = 1;
......
......@@ -1215,6 +1215,7 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
extensions->eglImage = true;
extensions->unpackSubimage = true;
extensions->packSubimage = true;
extensions->vertexArrayObject = true;
// D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
// D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't support gl_FrontFacing.
......
......@@ -576,6 +576,7 @@ void GenerateCaps(IDirect3D9 *d3d9,
extensions->eglImage = true;
extensions->unpackSubimage = true;
extensions->packSubimage = true;
extensions->vertexArrayObject = true;
// D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil
// state.
......
......@@ -578,6 +578,9 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM
extensions->debugMarker =
functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_KHR_debug") ||
functions->isAtLeastGLES(gl::Version(3, 2)) || functions->hasGLESExtension("GL_KHR_debug");
// ANGLE emulates vertex array objects in its GL layer
extensions->vertexArrayObject = true;
}
void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds)
......
......@@ -2173,4 +2173,41 @@ bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
return true;
}
bool ValidateBindVertexArrayBase(Context *context, GLuint array)
{
VertexArray *vao = context->getVertexArray(array);
if (!vao)
{
// The default VAO should always exist
ASSERT(array != 0);
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
return true;
}
bool ValidateDeleteVertexArraysBase(Context *context, GLsizei n)
{
if (n < 0)
{
context->recordError(Error(GL_INVALID_VALUE));
return false;
}
return true;
}
bool ValidateGenVertexArraysBase(Context *context, GLsizei n)
{
if (n < 0)
{
context->recordError(Error(GL_INVALID_VALUE));
return false;
}
return true;
}
}
......@@ -141,6 +141,10 @@ bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
egl::Display *display,
GLenum target,
egl::Image *image);
bool ValidateBindVertexArrayBase(Context *context, GLuint array);
bool ValidateDeleteVertexArraysBase(Context *context, GLsizei n);
bool ValidateGenVertexArraysBase(Context *context, GLsizei n);
}
#endif // LIBANGLE_VALIDATION_ES_H_
......@@ -993,4 +993,48 @@ bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs)
return true;
}
bool ValidateBindVertexArrayOES(Context *context, GLuint array)
{
if (!context->getExtensions().vertexArrayObject)
{
context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
return false;
}
return ValidateBindVertexArrayBase(context, array);
}
bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n)
{
if (!context->getExtensions().vertexArrayObject)
{
context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
return false;
}
return ValidateDeleteVertexArraysBase(context, n);
}
bool ValidateGenVertexArraysOES(Context *context, GLsizei n)
{
if (!context->getExtensions().vertexArrayObject)
{
context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
return false;
}
return ValidateGenVertexArraysBase(context, n);
}
bool ValidateIsVertexArrayOES(Context *context)
{
if (!context->getExtensions().vertexArrayObject)
{
context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
return false;
}
return true;
}
}
......@@ -33,6 +33,11 @@ bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numA
const GLenum *attachments);
bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs);
bool ValidateBindVertexArrayOES(Context *context, GLuint array);
bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n);
bool ValidateGenVertexArraysOES(Context *context, GLsizei n);
bool ValidateIsVertexArrayOES(Context *context);
}
#endif // LIBANGLE_VALIDATION_ES2_H_
......@@ -1299,4 +1299,48 @@ bool ValidateCompressedTexImage3D(Context *context,
return true;
}
bool ValidateBindVertexArray(Context *context, GLuint array)
{
if (context->getClientVersion() < 3)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
return ValidateBindVertexArrayBase(context, array);
}
bool ValidateDeleteVertexArrays(Context *context, GLsizei n)
{
if (context->getClientVersion() < 3)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
return ValidateDeleteVertexArraysBase(context, n);
}
bool ValidateGenVertexArrays(Context *context, GLsizei n)
{
if (context->getClientVersion() < 3)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
return ValidateGenVertexArraysBase(context, n);
}
bool ValidateIsVertexArray(Context *context)
{
if (context->getClientVersion() < 3)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
return true;
}
}
......@@ -54,6 +54,11 @@ bool ValidateCompressedTexImage3D(Context *context,
GLint border,
GLsizei imageSize,
const GLvoid *data);
bool ValidateBindVertexArray(Context *context, GLuint array);
bool ValidateDeleteVertexArrays(Context *context, GLsizei n);
bool ValidateGenVertexArrays(Context *context, GLsizei n);
bool ValidateIsVertexArray(Context *context);
}
#endif // LIBANGLE_VALIDATION_ES3_H_
......@@ -1341,6 +1341,12 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *
INSERT_PROC_ADDRESS(gl, EGLImageTargetTexture2DOES);
INSERT_PROC_ADDRESS(gl, EGLImageTargetRenderbufferStorageOES);
// GL_OES_vertex_array_object
INSERT_PROC_ADDRESS(gl, BindVertexArrayOES);
INSERT_PROC_ADDRESS(gl, DeleteVertexArraysOES);
INSERT_PROC_ADDRESS(gl, GenVertexArraysOES);
INSERT_PROC_ADDRESS(gl, IsVertexArrayOES);
// GLES3 core
INSERT_PROC_ADDRESS(gl, ReadBuffer);
INSERT_PROC_ADDRESS(gl, DrawRangeElements);
......
......@@ -1202,4 +1202,86 @@ ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target
}
}
}
void GL_APIENTRY BindVertexArrayOES(GLuint array)
{
EVENT("(GLuint array = %u)", array);
Context *context = GetValidGlobalContext();
if (context)
{
if (!ValidateBindVertexArrayOES(context, array))
{
return;
}
context->bindVertexArray(array);
}
}
void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
{
EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
Context *context = GetValidGlobalContext();
if (context)
{
if (!ValidateDeleteVertexArraysOES(context, n))
{
return;
}
for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
{
if (arrays[arrayIndex] != 0)
{
context->deleteVertexArray(arrays[arrayIndex]);
}
}
}
}
void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays)
{
EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
Context *context = GetValidGlobalContext();
if (context)
{
if (!ValidateGenVertexArraysOES(context, n))
{
return;
}
for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
{
arrays[arrayIndex] = context->createVertexArray();
}
}
}
GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array)
{
EVENT("(GLuint array = %u)", array);
Context *context = GetValidGlobalContext();
if (context)
{
if (!ValidateIsVertexArrayOES(context))
{
return GL_FALSE;
}
if (array == 0)
{
return GL_FALSE;
}
VertexArray *vao = context->getVertexArray(array);
return (vao != nullptr ? GL_TRUE : GL_FALSE);
}
return GL_FALSE;
}
}
......@@ -85,6 +85,12 @@ ANGLE_EXPORT void GL_APIENTRY PopGroupMarkerEXT();
ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target,
GLeglImageOES image);
// GL_OES_vertex_array_object
ANGLE_EXPORT void GL_APIENTRY BindVertexArrayOES(GLuint array);
ANGLE_EXPORT void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays);
ANGLE_EXPORT void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays);
ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array);
}
#endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_
......@@ -806,19 +806,8 @@ void GL_APIENTRY BindVertexArray(GLuint array)
Context *context = GetValidGlobalContext();
if (context)
{
if (context->getClientVersion() < 3)
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
VertexArray *vao = context->getVertexArray(array);
if (!vao)
if (!ValidateBindVertexArray(context, array))
{
// The default VAO should always exist
ASSERT(array != 0);
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
......@@ -833,15 +822,8 @@ void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays)
Context *context = GetValidGlobalContext();
if (context)
{
if (context->getClientVersion() < 3)
if (!ValidateDeleteVertexArrays(context, n))
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
if (n < 0)
{
context->recordError(Error(GL_INVALID_VALUE));
return;
}
......@@ -862,15 +844,8 @@ void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays)
Context *context = GetValidGlobalContext();
if (context)
{
if (context->getClientVersion() < 3)
if (!ValidateGenVertexArrays(context, n))
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
if (n < 0)
{
context->recordError(Error(GL_INVALID_VALUE));
return;
}
......@@ -888,9 +863,8 @@ GLboolean GL_APIENTRY IsVertexArray(GLuint array)
Context *context = GetValidGlobalContext();
if (context)
{
if (context->getClientVersion() < 3)
if (!ValidateIsVertexArray(context))
{
context->recordError(Error(GL_INVALID_OPERATION));
return GL_FALSE;
}
......
......@@ -1439,4 +1439,24 @@ void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImag
{
return gl::EGLImageTargetRenderbufferStorageOES(target, image);
}
void GL_APIENTRY glBindVertexArrayOES(GLuint array)
{
return gl::BindVertexArrayOES(array);
}
void GL_APIENTRY glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
{
return gl::DeleteVertexArraysOES(n, arrays);
}
void GL_APIENTRY glGenVertexArraysOES(GLsizei n, GLuint *arrays)
{
return gl::GenVertexArraysOES(n, arrays);
}
GLboolean GL_APIENTRY glIsVertexArrayOES(GLuint array)
{
return gl::IsVertexArrayOES(array);
}
}
......@@ -183,6 +183,10 @@ EXPORTS
glPopGroupMarkerEXT @296
glEGLImageTargetTexture2DOES @297
glEGLImageTargetRenderbufferStorageOES @298
glBindVertexArrayOES @299
glDeleteVertexArraysOES @300
glGenVertexArraysOES @301
glIsVertexArrayOES @302
; GLES 3.0 Functions
glReadBuffer @180
......
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