Home | History | Annotate | Download | only in util
      1 #include "pipe/p_context.h"
      2 #include "util/u_rect.h"
      3 #include "util/u_inlines.h"
      4 #include "util/u_transfer.h"
      5 #include "util/u_memory.h"
      6 
      7 /* One-shot transfer operation with data supplied in a user
      8  * pointer.  XXX: strides??
      9  */
     10 void u_default_transfer_inline_write( struct pipe_context *pipe,
     11                                       struct pipe_resource *resource,
     12                                       unsigned level,
     13                                       unsigned usage,
     14                                       const struct pipe_box *box,
     15                                       const void *data,
     16                                       unsigned stride,
     17                                       unsigned layer_stride)
     18 {
     19    struct pipe_transfer *transfer = NULL;
     20    uint8_t *map = NULL;
     21 
     22    assert(!(usage & PIPE_TRANSFER_READ));
     23 
     24    /* the write flag is implicit by the nature of transfer_inline_write */
     25    usage |= PIPE_TRANSFER_WRITE;
     26 
     27    /* transfer_inline_write implicitly discards the rewritten buffer range */
     28    if (box->x == 0 && box->width == resource->width0) {
     29       usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
     30    } else {
     31       usage |= PIPE_TRANSFER_DISCARD_RANGE;
     32    }
     33 
     34    transfer = pipe->get_transfer(pipe,
     35                                  resource,
     36                                  level,
     37                                  usage,
     38                                  box );
     39    if (transfer == NULL)
     40       goto out;
     41 
     42    map = pipe_transfer_map(pipe, transfer);
     43    if (map == NULL)
     44       goto out;
     45 
     46    if (resource->target == PIPE_BUFFER) {
     47       assert(box->height == 1);
     48       assert(box->depth == 1);
     49 
     50       memcpy(map, data, box->width);
     51    }
     52    else {
     53       const uint8_t *src_data = data;
     54       unsigned i;
     55 
     56       for (i = 0; i < box->depth; i++) {
     57          util_copy_rect(map,
     58                         resource->format,
     59                         transfer->stride, /* bytes */
     60                         0, 0,
     61                         box->width,
     62                         box->height,
     63                         src_data,
     64                         stride,       /* bytes */
     65                         0, 0);
     66          map += transfer->layer_stride;
     67          src_data += layer_stride;
     68       }
     69    }
     70 
     71 out:
     72    if (map)
     73       pipe_transfer_unmap(pipe, transfer);
     74 
     75    if (transfer)
     76       pipe_transfer_destroy(pipe, transfer);
     77 }
     78 
     79 
     80 boolean u_default_resource_get_handle(struct pipe_screen *screen,
     81                                       struct pipe_resource *resource,
     82                                       struct winsys_handle *handle)
     83 {
     84    return FALSE;
     85 }
     86 
     87 
     88 
     89 void u_default_transfer_flush_region( struct pipe_context *pipe,
     90                                       struct pipe_transfer *transfer,
     91                                       const struct pipe_box *box)
     92 {
     93    /* This is a no-op implementation, nothing to do.
     94     */
     95 }
     96 
     97 struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
     98                                               struct pipe_resource *resource,
     99                                               unsigned level,
    100                                               unsigned usage,
    101                                               const struct pipe_box *box)
    102 {
    103    struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer);
    104    if (transfer == NULL)
    105       return NULL;
    106 
    107    transfer->resource = resource;
    108    transfer->level = level;
    109    transfer->usage = usage;
    110    transfer->box = *box;
    111 
    112    /* Note strides are zero, this is ok for buffers, but not for
    113     * textures 2d & higher at least.
    114     */
    115    return transfer;
    116 }
    117 
    118 void u_default_transfer_unmap( struct pipe_context *pipe,
    119                                struct pipe_transfer *transfer )
    120 {
    121 }
    122 
    123 void u_default_transfer_destroy(struct pipe_context *pipe,
    124                                 struct pipe_transfer *transfer)
    125 {
    126    FREE(transfer);
    127 }
    128