st/mesa: fix fallout from xfb changes.
[mesa.git] / src / mesa / state_tracker / st_cb_bufferobjects.c
index e0cb979f2313dcfa8b01540857e0ebbcb2fe2ef0..202b4eeeefa63ee606dd793c29e98a6f8141a0c6 100644 (file)
  * internal structure where somehow shared.
  */
 static struct gl_buffer_object *
-st_bufferobj_alloc(struct gl_context *ctx, GLuint name, GLenum target)
+st_bufferobj_alloc(struct gl_context *ctx, GLuint name)
 {
    struct st_buffer_object *st_obj = ST_CALLOC_STRUCT(st_buffer_object);
 
    if (!st_obj)
       return NULL;
 
-   _mesa_initialize_buffer_object(ctx, &st_obj->Base, name, target);
+   _mesa_initialize_buffer_object(ctx, &st_obj->Base, name);
 
    return &st_obj->Base;
 }
@@ -83,8 +83,7 @@ st_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj)
    if (st_obj->buffer)
       pipe_resource_reference(&st_obj->buffer, NULL);
 
-   free(st_obj->Base.Label);
-   free(st_obj);
+   _mesa_delete_buffer_object(ctx, obj);
 }
 
 
@@ -104,9 +103,9 @@ st_bufferobj_subdata(struct gl_context *ctx,
    struct st_buffer_object *st_obj = st_buffer_object(obj);
 
    /* we may be called from VBO code, so double-check params here */
-   ASSERT(offset >= 0);
-   ASSERT(size >= 0);
-   ASSERT(offset + size <= obj->Size);
+   assert(offset >= 0);
+   assert(size >= 0);
+   assert(offset + size <= obj->Size);
 
    if (!size)
       return;
@@ -148,9 +147,9 @@ st_bufferobj_get_subdata(struct gl_context *ctx,
    struct st_buffer_object *st_obj = st_buffer_object(obj);
 
    /* we may be called from VBO code, so double-check params here */
-   ASSERT(offset >= 0);
-   ASSERT(size >= 0);
-   ASSERT(offset + size <= obj->Size);
+   assert(offset >= 0);
+   assert(size >= 0);
+   assert(offset + size <= obj->Size);
 
    if (!size)
       return;
@@ -183,24 +182,31 @@ st_bufferobj_data(struct gl_context *ctx,
 {
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
+   struct pipe_screen *screen = pipe->screen;
    struct st_buffer_object *st_obj = st_buffer_object(obj);
    unsigned bind, pipe_usage, pipe_flags = 0;
 
-   if (size && data && st_obj->buffer &&
+   if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD &&
+       size && st_obj->buffer &&
        st_obj->Base.Size == size &&
        st_obj->Base.Usage == usage &&
        st_obj->Base.StorageFlags == storageFlags) {
-      /* Just discard the old contents and write new data.
-       * This should be the same as creating a new buffer, but we avoid
-       * a lot of validation in Mesa.
-       */
-      struct pipe_box box;
-
-      u_box_1d(0, size, &box);
-      pipe->transfer_inline_write(pipe, st_obj->buffer, 0,
-                                  PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE,
-                                  &box, data, 0, 0);
-      return GL_TRUE;
+      if (data) {
+         /* Just discard the old contents and write new data.
+          * This should be the same as creating a new buffer, but we avoid
+          * a lot of validation in Mesa.
+          */
+         struct pipe_box box;
+
+         u_box_1d(0, size, &box);
+         pipe->transfer_inline_write(pipe, st_obj->buffer, 0,
+                                    PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE,
+                                    &box, data, 0, 0);
+         return GL_TRUE;
+      } else if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER)) {
+         pipe->invalidate_resource(pipe, st_obj->buffer);
+         return GL_TRUE;
+      }
    }
 
    st_obj->Base.Size = size;
@@ -228,8 +234,16 @@ st_bufferobj_data(struct gl_context *ctx,
       bind = PIPE_BIND_CONSTANT_BUFFER;
       break;
    case GL_DRAW_INDIRECT_BUFFER:
+   case GL_PARAMETER_BUFFER_ARB:
       bind = PIPE_BIND_COMMAND_ARGS_BUFFER;
       break;
+   case GL_ATOMIC_COUNTER_BUFFER:
+   case GL_SHADER_STORAGE_BUFFER:
+      bind = PIPE_BIND_SHADER_BUFFER;
+      break;
+   case GL_QUERY_BUFFER:
+      bind = PIPE_BIND_QUERY_BUFFER;
+      break;
    default:
       bind = 0;
    }
@@ -246,20 +260,29 @@ st_bufferobj_data(struct gl_context *ctx,
       /* BufferData */
       switch (usage) {
       case GL_STATIC_DRAW:
-      case GL_STATIC_READ:
       case GL_STATIC_COPY:
       default:
         pipe_usage = PIPE_USAGE_DEFAULT;
          break;
       case GL_DYNAMIC_DRAW:
-      case GL_DYNAMIC_READ:
       case GL_DYNAMIC_COPY:
          pipe_usage = PIPE_USAGE_DYNAMIC;
          break;
       case GL_STREAM_DRAW:
-      case GL_STREAM_READ:
       case GL_STREAM_COPY:
-         pipe_usage = PIPE_USAGE_STREAM;
+         /* XXX: Remove this test and fall-through when we have PBO unpacking
+          * acceleration. Right now, PBO unpacking is done by the CPU, so we
+          * have to make sure CPU reads are fast.
+          */
+         if (target != GL_PIXEL_UNPACK_BUFFER_ARB) {
+            pipe_usage = PIPE_USAGE_STREAM;
+            break;
+         }
+         /* fall through */
+      case GL_STATIC_READ:
+      case GL_DYNAMIC_READ:
+      case GL_STREAM_READ:
+         pipe_usage = PIPE_USAGE_STAGING;
          break;
       }
    }
@@ -291,16 +314,22 @@ st_bufferobj_data(struct gl_context *ctx,
       buffer.depth0 = 1;
       buffer.array_size = 1;
 
-      st_obj->buffer = pipe->screen->resource_create(pipe->screen, &buffer);
+      if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
+         st_obj->buffer =
+            screen->resource_from_user_memory(screen, &buffer, (void*)data);
+      }
+      else {
+         st_obj->buffer = screen->resource_create(screen, &buffer);
+
+         if (st_obj->buffer && data)
+            pipe_buffer_write(pipe, st_obj->buffer, 0, size, data);
+      }
 
       if (!st_obj->buffer) {
          /* out of memory */
          st_obj->Base.Size = 0;
          return GL_FALSE;
       }
-
-      if (data)
-         pipe_buffer_write(pipe, st_obj->buffer, 0, size, data);
    }
 
    /* BufferData may change an array or uniform buffer, need to update it */
@@ -310,6 +339,31 @@ st_bufferobj_data(struct gl_context *ctx,
 }
 
 
+/**
+ * Called via glInvalidateBuffer(Sub)Data.
+ */
+static void
+st_bufferobj_invalidate(struct gl_context *ctx,
+                        struct gl_buffer_object *obj,
+                        GLintptr offset,
+                        GLsizeiptr size)
+{
+   struct st_context *st = st_context(ctx);
+   struct pipe_context *pipe = st->pipe;
+   struct st_buffer_object *st_obj = st_buffer_object(obj);
+
+   /* We ignore partial invalidates. */
+   if (offset != 0 || size != obj->Size)
+      return;
+
+   /* Nothing to invalidate. */
+   if (!st_obj->buffer)
+      return;
+
+   pipe->invalidate_resource(pipe, st_obj->buffer);
+}
+
+
 /**
  * Called via glMapBufferRange().
  */
@@ -468,8 +522,8 @@ st_clear_buffer_subdata(struct gl_context *ctx,
    static const char zeros[16] = {0};
 
    if (!pipe->clear_buffer) {
-      _mesa_buffer_clear_subdata(ctx, offset, size,
-                                 clearValue, clearValueSize, bufObj);
+      _mesa_ClearBufferSubData_sw(ctx, offset, size,
+                                  clearValue, clearValueSize, bufObj);
       return;
    }
 
@@ -495,7 +549,8 @@ st_bufferobj_validate_usage(struct st_context *st,
 
 
 void
-st_init_bufferobject_functions(struct dd_function_table *functions)
+st_init_bufferobject_functions(struct pipe_screen *screen,
+                               struct dd_function_table *functions)
 {
    /* plug in default driver fallbacks (such as for ClearBufferSubData) */
    _mesa_init_buffer_object_functions(functions);
@@ -511,7 +566,6 @@ st_init_bufferobject_functions(struct dd_function_table *functions)
    functions->CopyBufferSubData = st_copy_buffer_subdata;
    functions->ClearBufferSubData = st_clear_buffer_subdata;
 
-   /* For GL_APPLE_vertex_array_object */
-   functions->NewArrayObject = _mesa_new_vao;
-   functions->DeleteArrayObject = _mesa_delete_vao;
+   if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER))
+      functions->InvalidateBufferSubData = st_bufferobj_invalidate;
 }