u_transfer.c revision 43995c9470dd38cf80a60a169f5875de6798863f
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 */ 10void 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 71out: 72 if (map) 73 pipe_transfer_unmap(pipe, transfer); 74 75 if (transfer) 76 pipe_transfer_destroy(pipe, transfer); 77} 78 79 80boolean 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 89void 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 97struct 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 118void u_default_transfer_unmap( struct pipe_context *pipe, 119 struct pipe_transfer *transfer ) 120{ 121} 122 123void u_default_transfer_destroy(struct pipe_context *pipe, 124 struct pipe_transfer *transfer) 125{ 126 FREE(transfer); 127} 128