u_blitter: add a msaa parameter to util_blitter_clear
[mesa.git] / src / gallium / auxiliary / util / u_transfer.c
index 7e72a59ee00a97e1381f62e349c6aabbfe2346b8..5bc47b09f3850ce9e4ed38a17af688e2015d27d1 100644 (file)
 #include "pipe/p_context.h"
-#include "util/u_rect.h"
+#include "util/u_surface.h"
 #include "util/u_inlines.h"
 #include "util/u_transfer.h"
 #include "util/u_memory.h"
 
-/* One-shot transfer operation with data supplied in a user
- * pointer.  XXX: strides??
- */
-void u_default_transfer_inline_write( struct pipe_context *pipe,
-                                      struct pipe_resource *resource,
-                                      unsigned level,
-                                      unsigned usage,
-                                      const struct pipe_box *box,
-                                      const void *data,
-                                      unsigned stride,
-                                      unsigned layer_stride)
+void u_default_buffer_subdata(struct pipe_context *pipe,
+                              struct pipe_resource *resource,
+                              unsigned usage, unsigned offset,
+                              unsigned size, const void *data)
 {
    struct pipe_transfer *transfer = NULL;
+   struct pipe_box box;
    uint8_t *map = NULL;
-   const uint8_t *src_data = data;
-   unsigned i;
-
-   transfer = pipe->get_transfer(pipe,
-                                 resource,
-                                 level,
-                                 usage,
-                                 box );
-   if (transfer == NULL)
-      goto out;
-
-   map = pipe_transfer_map(pipe, transfer);
-   if (map == NULL)
-      goto out;
-
-   for (i = 0; i < box->depth; i++) {
-      util_copy_rect(map,
-                     resource->format,
-                     transfer->stride, /* bytes */
-                     0, 0,
-                     box->width,
-                     box->height,
-                     src_data,
-                     stride,       /* bytes */
-                     0, 0);
-      map += transfer->layer_stride;
-      src_data += layer_stride;
+
+   assert(!(usage & PIPE_TRANSFER_READ));
+
+   /* the write flag is implicit by the nature of buffer_subdata */
+   usage |= PIPE_TRANSFER_WRITE;
+
+   /* buffer_subdata implicitly discards the rewritten buffer range.
+    * PIPE_TRANSFER_MAP_DIRECTLY supresses that.
+    */
+   if (!(usage & PIPE_TRANSFER_MAP_DIRECTLY)) {
+      if (offset == 0 && size == resource->width0) {
+         usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
+      } else {
+         usage |= PIPE_TRANSFER_DISCARD_RANGE;
+      }
    }
 
-out:
-   if (map)
-      pipe_transfer_unmap(pipe, transfer);
+   u_box_1d(offset, size, &box);
+
+   map = pipe->transfer_map(pipe, resource, 0, usage, &box, &transfer);
+   if (!map)
+      return;
+
+   memcpy(map, data, size);
+   pipe_transfer_unmap(pipe, transfer);
+}
+
+void u_default_texture_subdata(struct pipe_context *pipe,
+                               struct pipe_resource *resource,
+                               unsigned level,
+                               unsigned usage,
+                               const struct pipe_box *box,
+                               const void *data,
+                               unsigned stride,
+                               unsigned layer_stride)
+{
+   struct pipe_transfer *transfer = NULL;
+   const uint8_t *src_data = data;
+   uint8_t *map = NULL;
 
-   if (transfer)
-      pipe_transfer_destroy(pipe, transfer);
+   assert(!(usage & PIPE_TRANSFER_READ));
+
+   /* the write flag is implicit by the nature of texture_subdata */
+   usage |= PIPE_TRANSFER_WRITE;
+
+   /* texture_subdata implicitly discards the rewritten buffer range */
+   usage |= PIPE_TRANSFER_DISCARD_RANGE;
+
+   map = pipe->transfer_map(pipe,
+                            resource,
+                            level,
+                            usage,
+                            box, &transfer);
+   if (!map)
+      return;
+
+   util_copy_box(map,
+                 resource->format,
+                 transfer->stride, /* bytes */
+                 transfer->layer_stride, /* bytes */
+                 0, 0, 0,
+                 box->width,
+                 box->height,
+                 box->depth,
+                 src_data,
+                 stride,       /* bytes */
+                 layer_stride, /* bytes */
+                 0, 0, 0);
+
+   pipe_transfer_unmap(pipe, transfer);
 }
 
 
-boolean u_default_resource_get_handle(struct pipe_screen *screen,
-                                      struct pipe_resource *resource,
-                                      struct winsys_handle *handle)
+bool u_default_resource_get_handle(UNUSED struct pipe_screen *screen,
+                                   UNUSED struct pipe_resource *resource,
+                                   UNUSED struct winsys_handle *handle)
 {
    return FALSE;
 }
 
 
 
-void u_default_transfer_flush_region( struct pipe_context *pipe,
-                                      struct pipe_transfer *transfer,
-                                      const struct pipe_box *box)
+void u_default_transfer_flush_region(UNUSED struct pipe_context *pipe,
+                                     UNUSED struct pipe_transfer *transfer,
+                                     UNUSED const struct pipe_box *box)
 {
    /* This is a no-op implementation, nothing to do.
     */
 }
 
-struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
-                                              struct pipe_resource *resource,
-                                              unsigned level,
-                                              unsigned usage,
-                                              const struct pipe_box *box)
+void u_default_transfer_unmap(UNUSED struct pipe_context *pipe,
+                              UNUSED struct pipe_transfer *transfer)
 {
-   struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer);
-   if (transfer == NULL)
-      return NULL;
+}
 
-   transfer->resource = resource;
-   transfer->level = level;
-   transfer->usage = usage;
-   transfer->box = *box;
 
-   /* Note strides are zero, this is ok for buffers, but not for
-    * textures 2d & higher at least. 
-    */
-   return transfer;
+static inline struct u_resource *
+u_resource( struct pipe_resource *res )
+{
+   return (struct u_resource *)res;
+}
+
+bool u_resource_get_handle_vtbl(struct pipe_screen *screen,
+                                UNUSED struct pipe_context *ctx,
+                                struct pipe_resource *resource,
+                                struct winsys_handle *handle,
+                                UNUSED unsigned usage)
+{
+   struct u_resource *ur = u_resource(resource);
+   return ur->vtbl->resource_get_handle(screen, resource, handle);
+}
+
+void u_resource_destroy_vtbl(struct pipe_screen *screen,
+                             struct pipe_resource *resource)
+{
+   struct u_resource *ur = u_resource(resource);
+   ur->vtbl->resource_destroy(screen, resource);
 }
 
-void u_default_transfer_unmap( struct pipe_context *pipe,
-                               struct pipe_transfer *transfer )
+void *u_transfer_map_vtbl(struct pipe_context *context,
+                          struct pipe_resource *resource,
+                          unsigned level,
+                          unsigned usage,
+                          const struct pipe_box *box,
+                          struct pipe_transfer **transfer)
 {
+   struct u_resource *ur = u_resource(resource);
+   return ur->vtbl->transfer_map(context, resource, level, usage, box,
+                                 transfer);
 }
 
-void u_default_transfer_destroy(struct pipe_context *pipe,
-                                struct pipe_transfer *transfer)
+void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
+                                   struct pipe_transfer *transfer,
+                                   const struct pipe_box *box)
 {
-   FREE(transfer);
+   struct u_resource *ur = u_resource(transfer->resource);
+   ur->vtbl->transfer_flush_region(pipe, transfer, box);
 }
 
-void u_default_redefine_user_buffer(struct pipe_context *ctx,
-                                    struct pipe_resource *resource,
-                                    unsigned offset,
-                                    unsigned size)
+void u_transfer_unmap_vtbl( struct pipe_context *pipe,
+                            struct pipe_transfer *transfer )
 {
-   resource->width0 = MAX2(resource->width0, offset + size);
+   struct u_resource *ur = u_resource(transfer->resource);
+   ur->vtbl->transfer_unmap(pipe, transfer);
 }