u_transfer.c revision 848b8605
1#include "pipe/p_context.h"
2#include "util/u_surface.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 (resource->target == PIPE_BUFFER &&
29       box->x == 0 && box->width == resource->width0) {
30      usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
31   } else {
32      usage |= PIPE_TRANSFER_DISCARD_RANGE;
33   }
34
35   map = pipe->transfer_map(pipe,
36                            resource,
37                            level,
38                            usage,
39                            box, &transfer);
40   if (map == NULL)
41      return;
42
43   if (resource->target == PIPE_BUFFER) {
44      assert(box->height == 1);
45      assert(box->depth == 1);
46
47      memcpy(map, data, box->width);
48   }
49   else {
50      const uint8_t *src_data = data;
51
52      util_copy_box(map,
53		    resource->format,
54		    transfer->stride, /* bytes */
55		    transfer->layer_stride, /* bytes */
56                    0, 0, 0,
57		    box->width,
58		    box->height,
59		    box->depth,
60		    src_data,
61		    stride,       /* bytes */
62		    layer_stride, /* bytes */
63		    0, 0, 0);
64   }
65
66   pipe_transfer_unmap(pipe, transfer);
67}
68
69
70boolean u_default_resource_get_handle(struct pipe_screen *screen,
71                                      struct pipe_resource *resource,
72                                      struct winsys_handle *handle)
73{
74   return FALSE;
75}
76
77
78
79void u_default_transfer_flush_region( struct pipe_context *pipe,
80                                      struct pipe_transfer *transfer,
81                                      const struct pipe_box *box)
82{
83   /* This is a no-op implementation, nothing to do.
84    */
85}
86
87void u_default_transfer_unmap( struct pipe_context *pipe,
88                               struct pipe_transfer *transfer )
89{
90}
91
92
93static INLINE struct u_resource *
94u_resource( struct pipe_resource *res )
95{
96   return (struct u_resource *)res;
97}
98
99boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
100                                   struct pipe_resource *resource,
101                                   struct winsys_handle *handle)
102{
103   struct u_resource *ur = u_resource(resource);
104   return ur->vtbl->resource_get_handle(screen, resource, handle);
105}
106
107void u_resource_destroy_vtbl(struct pipe_screen *screen,
108                             struct pipe_resource *resource)
109{
110   struct u_resource *ur = u_resource(resource);
111   ur->vtbl->resource_destroy(screen, resource);
112}
113
114void *u_transfer_map_vtbl(struct pipe_context *context,
115                          struct pipe_resource *resource,
116                          unsigned level,
117                          unsigned usage,
118                          const struct pipe_box *box,
119                          struct pipe_transfer **transfer)
120{
121   struct u_resource *ur = u_resource(resource);
122   return ur->vtbl->transfer_map(context, resource, level, usage, box,
123                                 transfer);
124}
125
126void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
127                                   struct pipe_transfer *transfer,
128                                   const struct pipe_box *box)
129{
130   struct u_resource *ur = u_resource(transfer->resource);
131   ur->vtbl->transfer_flush_region(pipe, transfer, box);
132}
133
134void u_transfer_unmap_vtbl( struct pipe_context *pipe,
135                            struct pipe_transfer *transfer )
136{
137   struct u_resource *ur = u_resource(transfer->resource);
138   ur->vtbl->transfer_unmap(pipe, transfer);
139}
140
141void u_transfer_inline_write_vtbl( struct pipe_context *pipe,
142                                   struct pipe_resource *resource,
143                                   unsigned level,
144                                   unsigned usage,
145                                   const struct pipe_box *box,
146                                   const void *data,
147                                   unsigned stride,
148                                   unsigned layer_stride)
149{
150   struct u_resource *ur = u_resource(resource);
151   ur->vtbl->transfer_inline_write(pipe,
152                                   resource,
153                                   level,
154                                   usage,
155                                   box,
156                                   data,
157                                   stride,
158                                   layer_stride);
159}
160
161
162
163
164