1287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "pipe/p_context.h"
2287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "util/u_rect.h"
3287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "util/u_inlines.h"
4287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "util/u_transfer.h"
5287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "util/u_memory.h"
6287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
7287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/* One-shot transfer operation with data supplied in a user
8287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * pointer.  XXX: strides??
9287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */
10287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellvoid u_default_transfer_inline_write( struct pipe_context *pipe,
114c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      struct pipe_resource *resource,
124c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      unsigned level,
134c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      unsigned usage,
144c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      const struct pipe_box *box,
154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      const void *data,
164c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      unsigned stride,
174c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      unsigned layer_stride)
18287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
19287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_transfer *transfer = NULL;
20287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   uint8_t *map = NULL;
214c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
22615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák   assert(!(usage & PIPE_TRANSFER_READ));
23615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák
24615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák   /* the write flag is implicit by the nature of transfer_inline_write */
25615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák   usage |= PIPE_TRANSFER_WRITE;
26615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák
27615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák   /* transfer_inline_write implicitly discards the rewritten buffer range */
28615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák   if (box->x == 0 && box->width == resource->width0) {
29615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák      usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
30615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák   } else {
31615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák      usage |= PIPE_TRANSFER_DISCARD_RANGE;
32615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák   }
33615baedc778039a2dcd08bbc1b3006c9e5a111dcMarek Olšák
344c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   transfer = pipe->get_transfer(pipe,
354c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 resource,
364c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 level,
374c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 usage,
384c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 box );
39287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (transfer == NULL)
40287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      goto out;
41287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
42287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   map = pipe_transfer_map(pipe, transfer);
43287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (map == NULL)
44287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      goto out;
45287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
46335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák   if (resource->target == PIPE_BUFFER) {
47335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák      assert(box->height == 1);
48335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák      assert(box->depth == 1);
49335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák
50335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák      memcpy(map, data, box->width);
51335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák   }
52335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák   else {
53335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák      const uint8_t *src_data = data;
54335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák      unsigned i;
55335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák
56335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák      for (i = 0; i < box->depth; i++) {
57335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák         util_copy_rect(map,
58335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        resource->format,
59335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        transfer->stride, /* bytes */
60335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        0, 0,
61335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        box->width,
62335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        box->height,
63335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        src_data,
64335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        stride,       /* bytes */
65335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák                        0, 0);
66335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák         map += transfer->layer_stride;
67335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák         src_data += layer_stride;
68335facb502199353e6f73c8ba20a2bb4ff7bf336Marek Olšák      }
694c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   }
70287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
71287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellout:
72287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (map)
73287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_transfer_unmap(pipe, transfer);
74287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
75287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (transfer)
76287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_transfer_destroy(pipe, transfer);
77287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
78287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
79287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
80287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellboolean u_default_resource_get_handle(struct pipe_screen *screen,
814c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      struct pipe_resource *resource,
824c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      struct winsys_handle *handle)
83287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
84287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return FALSE;
85287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
86287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
87287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
88287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
89287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellvoid u_default_transfer_flush_region( struct pipe_context *pipe,
904c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      struct pipe_transfer *transfer,
914c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                      const struct pipe_box *box)
92287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
93287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   /* This is a no-op implementation, nothing to do.
94287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    */
95287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
96287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
97287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
984c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                              struct pipe_resource *resource,
994c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                              unsigned level,
1004c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                              unsigned usage,
1014c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                              const struct pipe_box *box)
102287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
103287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_transfer *transfer = CALLOC_STRUCT(pipe_transfer);
104287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (transfer == NULL)
105287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      return NULL;
106287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
107287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   transfer->resource = resource;
1084c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   transfer->level = level;
109287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   transfer->usage = usage;
110287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   transfer->box = *box;
111287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
112287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   /* Note strides are zero, this is ok for buffers, but not for
113287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * textures 2d & higher at least.
114287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    */
115287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return transfer;
116287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
117287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
118287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellvoid u_default_transfer_unmap( struct pipe_context *pipe,
1194c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                               struct pipe_transfer *transfer )
120287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
121287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
122287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
123287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellvoid u_default_transfer_destroy(struct pipe_context *pipe,
1244c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                struct pipe_transfer *transfer)
125287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
126287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   FREE(transfer);
127287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
128