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