mesa: rework _mesa_lookup_vao_err to allow usage from EXT_dsa
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Fri, 25 Oct 2019 13:20:09 +0000 (15:20 +0200)
committerPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Tue, 5 Nov 2019 12:58:28 +0000 (13:58 +0100)
ARB_dsa and EXT_dsa slightly differs when an uninitialized VAO
is requested.
In this case ARB_dsa fails while EXT_dsa requires to initialize
the object.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/mesa/main/arrayobj.c
src/mesa/main/arrayobj.h
src/mesa/main/varray.c

index a6d48f5ffedf946d5ed22575a377048a3ca80d8a..331dc1a3c68db9fe1a9cd4f6522238d68708287f 100644 (file)
@@ -229,12 +229,17 @@ _mesa_lookup_vao(struct gl_context *ctx, GLuint id)
 /**
  * Looks up the array object for the given ID.
  *
- * Unlike _mesa_lookup_vao, this function generates a GL_INVALID_OPERATION
+ * While _mesa_lookup_vao doesn't generate an error if the object does not
+ * exist, this function comes in two variants.
+ * If is_ext_dsa is false, this function generates a GL_INVALID_OPERATION
  * error if the array object does not exist. It also returns the default
  * array object when ctx is a compatibility profile context and id is zero.
+ * If is_ext_dsa is true, 0 is not a valid name. If the name exists but
+ * the object has never been bound, it is initialized.
  */
 struct gl_vertex_array_object *
-_mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller)
+_mesa_lookup_vao_err(struct gl_context *ctx, GLuint id,
+                     bool is_ext_dsa, const char *caller)
 {
    /* The ARB_direct_state_access specification says:
     *
@@ -243,10 +248,11 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller)
     *     the name of the vertex array object."
     */
    if (id == 0) {
-      if (ctx->API == API_OPENGL_CORE) {
+      if (is_ext_dsa || ctx->API == API_OPENGL_CORE) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "%s(zero is not valid vaobj name in a core profile "
-                     "context)", caller);
+                     "%s(zero is not valid vaobj name%s)",
+                     caller,
+                     is_ext_dsa ? "" : " in a core profile context");
          return NULL;
       }
 
@@ -267,12 +273,23 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller)
           *     [compatibility profile: zero or] the name of an existing
           *     vertex array object."
           */
-         if (!vao || !vao->EverBound) {
+         if (!vao || (!is_ext_dsa && !vao->EverBound)) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
                         "%s(non-existent vaobj=%u)", caller, id);
             return NULL;
          }
 
+         /* The EXT_direct_state_access specification says:
+         *
+         *    "If the vertex array object named by the vaobj parameter has not
+         *     been previously bound but has been generated (without subsequent
+         *     deletion) by GenVertexArrays, the GL first creates a new state
+         *     vector in the same manner as when BindVertexArray creates a new
+         *     vertex array object."
+         */
+         if (vao && is_ext_dsa && !vao->EverBound)
+            vao->EverBound = true;
+
          _mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, vao);
       }
 
@@ -1273,7 +1290,7 @@ vertex_array_element_buffer(struct gl_context *ctx, GLuint vaobj, GLuint buffer,
        *     VertexArrayElementBuffer if <vaobj> is not [compatibility profile:
        *     zero or] the name of an existing vertex array object."
        */
-      vao =_mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayElementBuffer");
+      vao =_mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayElementBuffer");
       if (!vao)
          return;
    } else {
@@ -1333,7 +1350,7 @@ _mesa_GetVertexArrayiv(GLuint vaobj, GLenum pname, GLint *param)
     *    [compatibility profile: zero or] the name of an existing
     *    vertex array object."
     */
-   vao =_mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayiv");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayiv");
    if (!vao)
       return;
 
index 7516bae9e396d6e1147bc660dc8fd5b6bc13150c..584e6d818cfa61168a990b02a31330d4314dfebe 100644 (file)
@@ -50,7 +50,8 @@ extern struct gl_vertex_array_object *
 _mesa_lookup_vao(struct gl_context *ctx, GLuint id);
 
 extern struct gl_vertex_array_object *
-_mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller);
+_mesa_lookup_vao_err(struct gl_context *ctx, GLuint id,
+                     bool is_ext_dsa, const char *caller);
 
 extern struct gl_vertex_array_object *
 _mesa_new_vao(struct gl_context *ctx, GLuint name);
index dd54be979d4f5c9d1b7bba8b23efb02f142782bf..963775edad698b98e22b13c7ebe6b1635c0e4636 100644 (file)
@@ -1265,7 +1265,7 @@ _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
     *    [compatibility profile: zero or] the name of an existing vertex
     *    array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glEnableVertexArrayAttrib");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glEnableVertexArrayAttrib");
    if (!vao)
       return;
 
@@ -1341,7 +1341,7 @@ _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
     *    [compatibility profile: zero or] the name of an existing vertex
     *    array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glDisableVertexArrayAttrib");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glDisableVertexArrayAttrib");
    if (!vao)
       return;
 
@@ -1648,7 +1648,7 @@ _mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index,
     *     [compatibility profile: zero or] the name of an existing
     *     vertex array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexediv");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexediv");
    if (!vao)
       return;
 
@@ -1711,7 +1711,7 @@ _mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index,
     *     [compatibility profile: zero or] the name of an existing
     *     vertex array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexed64iv");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexed64iv");
    if (!vao)
       return;
 
@@ -2310,7 +2310,7 @@ _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
     *    if <vaobj> is not [compatibility profile: zero or] the name of an
     *    existing vertex array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffer");
    if (!vao)
       return;
 
@@ -2516,7 +2516,7 @@ _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
     *    if <vaobj> is not [compatibility profile: zero or] the name of an
     *    existing vertex array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffers");
    if (!vao)
       return;
 
@@ -2644,7 +2644,7 @@ vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
        *   VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
        *   zero or] the name of an existing vertex array object."
        */
-      vao = _mesa_lookup_vao_err(ctx, vaobj, func);
+      vao = _mesa_lookup_vao_err(ctx, false, vaobj, func);
       if (!vao)
          return;
 
@@ -2808,7 +2808,7 @@ _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingI
     *    if <vaobj> is not [compatibility profile: zero or] the name of an
     *    existing vertex array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayAttribBinding");
    if (!vao)
       return;
 
@@ -2903,7 +2903,7 @@ _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
     *    if <vaobj> is not [compatibility profile: zero or] the name of an
     *    existing vertex array object."
     */
-   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor");
+   vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayBindingDivisor");
    if (!vao)
        return;