mesa: add support for memory object creation/import/delete
[mesa.git] / src / mesa / main / transformfeedback.c
index 96f3df1c961e2bb558bea7dd3ad1440475c3485a..fdc3152a091915f5c3f240b2f69396f24988bd3c 100644 (file)
@@ -72,8 +72,8 @@ _mesa_transform_feedback_is_using_program(struct gl_context *ctx,
    callback_data.found = false;
    callback_data.prog = shProg->last_vert_prog;
 
-   _mesa_HashWalk(ctx->TransformFeedback.Objects,
-                  active_xfb_object_references_program, &callback_data);
+   _mesa_HashWalkLocked(ctx->TransformFeedback.Objects,
+                        active_xfb_object_references_program, &callback_data);
 
    /* Also check DefaultObject, as it's not in the Objects hash table. */
    active_xfb_object_references_program(0, ctx->TransformFeedback.DefaultObject,
@@ -110,16 +110,12 @@ reference_transform_feedback_object(struct gl_transform_feedback_object **ptr,
    assert(!*ptr);
 
    if (obj) {
+      assert(obj->RefCount > 0);
+
       /* reference new object */
-      if (obj->RefCount == 0) {
-         _mesa_problem(NULL, "referencing deleted transform feedback object");
-         *ptr = NULL;
-      }
-      else {
-         obj->RefCount++;
-         obj->EverBound = GL_TRUE;
-         *ptr = obj;
-      }
+      obj->RefCount++;
+      obj->EverBound = GL_TRUE;
+      *ptr = obj;
    }
 }
 
@@ -545,19 +541,16 @@ bind_buffer_range(struct gl_context *ctx,
 
 
 /**
- * Specify a buffer object to receive transform feedback results.  Plus,
- * specify the starting offset to place the results, and max size.
+ * Validate the buffer object to receive transform feedback results.  Plus,
+ * validate the starting offset to place the results, and max size.
  * Called from the glBindBufferRange() and glTransformFeedbackBufferRange
  * functions.
  */
-void
-_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
-                                           struct gl_transform_feedback_object *obj,
-                                           GLuint index,
-                                           struct gl_buffer_object *bufObj,
-                                           GLintptr offset,
-                                           GLsizeiptr size,
-                                           bool dsa)
+bool
+_mesa_validate_buffer_range_xfb(struct gl_context *ctx,
+                                struct gl_transform_feedback_object *obj,
+                                GLuint index, struct gl_buffer_object *bufObj,
+                                GLintptr offset, GLsizeiptr size, bool dsa)
 {
    const char *gl_methd_name;
    if (dsa)
@@ -569,7 +562,7 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
    if (obj->Active) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)",
                   gl_methd_name);
-      return;
+      return false;
    }
 
    if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
@@ -579,21 +572,21 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
        */
       _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)",
                   gl_methd_name, index);
-      return;
+      return false;
    }
 
    if (size & 0x3) {
       /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */
       _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be a multiple of "
                   "four)", gl_methd_name, (int) size);
-      return;
+      return false;
    }  
 
    if (offset & 0x3) {
       /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */
       _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be a multiple "
                   "of four)", gl_methd_name, (int) offset);
-      return;
+      return false;
    }
 
    if (offset < 0) {
@@ -606,7 +599,7 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
       _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be >= 0)",
                   gl_methd_name,
                   (int) offset);
-      return;
+      return false;
    }
 
    if (size <= 0 && (dsa || bufObj != ctx->Shared->NullBufferObj)) {
@@ -620,10 +613,10 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
        */
       _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be > 0)",
                   gl_methd_name, (int) size);
-      return;
+      return false;
    }
 
-   bind_buffer_range(ctx, obj, index, bufObj, offset, size, dsa);
+   return true;
 }
 
 
@@ -747,8 +740,13 @@ _mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer,
       return;
    }
 
-   _mesa_bind_buffer_range_transform_feedback(ctx, obj, index, bufObj, offset,
-                                              size, true);
+   if (!_mesa_validate_buffer_range_xfb(ctx, obj, index, bufObj, offset,
+                                        size, true))
+      return;
+
+   /* The per-attribute binding point */
+   _mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset,
+                                        size);
 }
 
 /**
@@ -802,7 +800,7 @@ _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,
       return;
    }
 
-   bind_buffer_range(ctx, obj, index, bufObj, offset, 0, false);
+   _mesa_bind_buffer_range_xfb(ctx, obj, index, bufObj, offset, 0);
 }
 
 
@@ -969,7 +967,7 @@ _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
    }
    else
       return (struct gl_transform_feedback_object *)
-         _mesa_HashLookup(ctx->TransformFeedback.Objects, name);
+         _mesa_HashLookupLocked(ctx->TransformFeedback.Objects, name);
 }
 
 static void
@@ -1004,7 +1002,8 @@ create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids,
             return;
          }
          ids[i] = first + i;
-         _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj);
+         _mesa_HashInsertLocked(ctx->TransformFeedback.Objects, first + i,
+                                obj);
          if (dsa) {
             /* this is normally done at bind time in the non-dsa case */
             obj->EverBound = GL_TRUE;
@@ -1136,7 +1135,7 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names)
                            names[i]);
                return;
             }
-            _mesa_HashRemove(ctx->TransformFeedback.Objects, names[i]);
+            _mesa_HashRemoveLocked(ctx->TransformFeedback.Objects, names[i]);
             /* unref, but object may not be deleted until later */
             if (obj == ctx->TransformFeedback.CurrentObject) {
                reference_transform_feedback_object(