st/mesa: implement ARB_buffer_storage
authorMarek Olšák <marek.olsak@amd.com>
Mon, 27 Jan 2014 20:45:54 +0000 (21:45 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 25 Feb 2014 15:05:41 +0000 (16:05 +0100)
Reviewed-by: Fredrik Höglund <fredrik@kde.org>
src/mesa/state_tracker/st_cb_bufferobjects.c
src/mesa/state_tracker/st_cb_texturebarrier.c
src/mesa/state_tracker/st_extensions.c

index 347dc90b26988e3223ab95668933d35a1f7003ee..bf4c71f721ed18eb12028edd369a3329cd93e490 100644 (file)
@@ -182,7 +182,7 @@ st_bufferobj_data(struct gl_context *ctx,
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
    struct st_buffer_object *st_obj = st_buffer_object(obj);
-   unsigned bind, pipe_usage;
+   unsigned bind, pipe_usage, pipe_flags = 0;
 
    if (size && data && st_obj->buffer &&
        st_obj->Base.Size == size &&
@@ -229,24 +229,41 @@ st_bufferobj_data(struct gl_context *ctx,
       bind = 0;
    }
 
-   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;
-      break;
+   /* Set usage. */
+   if (st_obj->Base.Immutable) {
+      /* BufferStorage */
+      if (storageFlags & GL_CLIENT_STORAGE_BIT)
+         pipe_usage = PIPE_USAGE_STAGING;
+      else
+         pipe_usage = PIPE_USAGE_DEFAULT;
    }
+   else {
+      /* 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;
+         break;
+      }
+   }
+
+   /* Set flags. */
+   if (storageFlags & GL_MAP_PERSISTENT_BIT)
+      pipe_flags |= PIPE_RESOURCE_FLAG_MAP_PERSISTENT;
+   if (storageFlags & GL_MAP_COHERENT_BIT)
+      pipe_flags |= PIPE_RESOURCE_FLAG_MAP_COHERENT;
 
    pipe_resource_reference( &st_obj->buffer, NULL );
 
@@ -255,8 +272,20 @@ st_bufferobj_data(struct gl_context *ctx,
    }
 
    if (size != 0) {
-      st_obj->buffer = pipe_buffer_create(pipe->screen, bind,
-                                          pipe_usage, size);
+      struct pipe_resource buffer;
+
+      memset(&buffer, 0, sizeof buffer);
+      buffer.target = PIPE_BUFFER;
+      buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
+      buffer.bind = bind;
+      buffer.usage = pipe_usage;
+      buffer.flags = pipe_flags;
+      buffer.width0 = size;
+      buffer.height0 = 1;
+      buffer.depth0 = 1;
+      buffer.array_size = 1;
+
+      st_obj->buffer = pipe->screen->resource_create(pipe->screen, &buffer);
 
       if (!st_obj->buffer) {
          /* out of memory */
@@ -309,6 +338,12 @@ st_bufferobj_map_range(struct gl_context *ctx,
    if (access & GL_MAP_UNSYNCHRONIZED_BIT)
       flags |= PIPE_TRANSFER_UNSYNCHRONIZED;
 
+   if (access & GL_MAP_PERSISTENT_BIT)
+      flags |= PIPE_TRANSFER_PERSISTENT;
+
+   if (access & GL_MAP_COHERENT_BIT)
+      flags |= PIPE_TRANSFER_COHERENT;
+
    /* ... other flags ...
     */
 
@@ -399,8 +434,8 @@ st_copy_buffer_subdata(struct gl_context *ctx,
       return;
 
    /* buffer should not already be mapped */
-   assert(!src->Pointer);
-   assert(!dst->Pointer);
+   assert(!_mesa_check_disallowed_mapping(src));
+   assert(!_mesa_check_disallowed_mapping(dst));
 
    u_box_1d(readOffset, size, &box);
 
index 2f1a22b588866e0e2a889d54d34c82fd01d5b84c..dd4dde74c864cd910e4c12547359aeeb79359e5c 100644 (file)
@@ -54,7 +54,24 @@ st_TextureBarrier(struct gl_context *ctx)
 }
 
 
+/**
+ * Called via ctx->Driver.MemoryBarrier()
+ */
+static void
+st_MemoryBarrier(struct gl_context *ctx, GLbitfield barriers)
+{
+   struct pipe_context *pipe = st_context(ctx)->pipe;
+   unsigned flags = 0;
+
+   if (barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT)
+      flags |= PIPE_BARRIER_MAPPED_BUFFER;
+
+   if (flags && pipe->memory_barrier)
+      pipe->memory_barrier(pipe, flags);
+}
+
 void st_init_texture_barrier_functions(struct dd_function_table *functions)
 {
    functions->TextureBarrier = st_TextureBarrier;
+   functions->MemoryBarrier = st_MemoryBarrier;
 }
index 47b975b5bf086457bd8cbbc8228e79069961d9e0..d053efbb20f513d574b2647087e9c6053d156548 100644 (file)
@@ -376,6 +376,7 @@ void st_init_extensions(struct st_context *st)
 
    static const struct st_extension_cap_mapping cap_mapping[] = {
       { o(ARB_base_instance),                PIPE_CAP_START_INSTANCE                   },
+      { o(ARB_buffer_storage),               PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT },
       { o(ARB_depth_clamp),                  PIPE_CAP_DEPTH_CLIP_DISABLE               },
       { o(ARB_depth_texture),                PIPE_CAP_TEXTURE_SHADOW_MAP               },
       { o(ARB_draw_buffers_blend),           PIPE_CAP_INDEP_BLEND_FUNC                 },