1bf215546Sopenharmony_ci#include "pipe/p_context.h"
2bf215546Sopenharmony_ci#include "util/u_surface.h"
3bf215546Sopenharmony_ci#include "util/u_inlines.h"
4bf215546Sopenharmony_ci#include "util/u_transfer.h"
5bf215546Sopenharmony_ci#include "util/u_memory.h"
6bf215546Sopenharmony_ci
7bf215546Sopenharmony_civoid u_default_buffer_subdata(struct pipe_context *pipe,
8bf215546Sopenharmony_ci                              struct pipe_resource *resource,
9bf215546Sopenharmony_ci                              unsigned usage, unsigned offset,
10bf215546Sopenharmony_ci                              unsigned size, const void *data)
11bf215546Sopenharmony_ci{
12bf215546Sopenharmony_ci   struct pipe_transfer *transfer = NULL;
13bf215546Sopenharmony_ci   struct pipe_box box;
14bf215546Sopenharmony_ci   uint8_t *map = NULL;
15bf215546Sopenharmony_ci
16bf215546Sopenharmony_ci   assert(!(usage & PIPE_MAP_READ));
17bf215546Sopenharmony_ci
18bf215546Sopenharmony_ci   /* the write flag is implicit by the nature of buffer_subdata */
19bf215546Sopenharmony_ci   usage |= PIPE_MAP_WRITE;
20bf215546Sopenharmony_ci
21bf215546Sopenharmony_ci   /* buffer_subdata implicitly discards the rewritten buffer range.
22bf215546Sopenharmony_ci    * PIPE_MAP_DIRECTLY supresses that.
23bf215546Sopenharmony_ci    */
24bf215546Sopenharmony_ci   if (!(usage & PIPE_MAP_DIRECTLY)) {
25bf215546Sopenharmony_ci      if (offset == 0 && size == resource->width0) {
26bf215546Sopenharmony_ci         usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
27bf215546Sopenharmony_ci      } else {
28bf215546Sopenharmony_ci         usage |= PIPE_MAP_DISCARD_RANGE;
29bf215546Sopenharmony_ci      }
30bf215546Sopenharmony_ci   }
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci   u_box_1d(offset, size, &box);
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci   map = pipe->buffer_map(pipe, resource, 0, usage, &box, &transfer);
35bf215546Sopenharmony_ci   if (!map)
36bf215546Sopenharmony_ci      return;
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   memcpy(map, data, size);
39bf215546Sopenharmony_ci   pipe_buffer_unmap(pipe, transfer);
40bf215546Sopenharmony_ci}
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_civoid u_default_clear_buffer(struct pipe_context *pipe,
43bf215546Sopenharmony_ci                            struct pipe_resource *resource,
44bf215546Sopenharmony_ci                            unsigned offset, unsigned size,
45bf215546Sopenharmony_ci                            const void *clear_value,
46bf215546Sopenharmony_ci                            int clear_value_size)
47bf215546Sopenharmony_ci{
48bf215546Sopenharmony_ci   struct pipe_transfer *transfer = NULL;
49bf215546Sopenharmony_ci   struct pipe_box box;
50bf215546Sopenharmony_ci   uint8_t *map = NULL;
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   /* the write flag is implicit by the nature of buffer_subdata */
53bf215546Sopenharmony_ci   unsigned usage = PIPE_MAP_WRITE;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   /* clear_buffer implicitly discards the rewritten buffer range. */
56bf215546Sopenharmony_ci   if (offset == 0 && size == resource->width0) {
57bf215546Sopenharmony_ci      usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
58bf215546Sopenharmony_ci   } else {
59bf215546Sopenharmony_ci      usage |= PIPE_MAP_DISCARD_RANGE;
60bf215546Sopenharmony_ci   }
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci   u_box_1d(offset, size, &box);
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci   map = pipe->buffer_map(pipe, resource, 0, usage, &box, &transfer);
65bf215546Sopenharmony_ci   if (!map)
66bf215546Sopenharmony_ci      return;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   assert(clear_value_size > 0);
69bf215546Sopenharmony_ci   for (unsigned off = 0; off < size; off += clear_value_size)
70bf215546Sopenharmony_ci      memcpy(map + off, clear_value, MIN2(clear_value_size, size - off));
71bf215546Sopenharmony_ci   pipe_buffer_unmap(pipe, transfer);
72bf215546Sopenharmony_ci}
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_civoid u_default_texture_subdata(struct pipe_context *pipe,
75bf215546Sopenharmony_ci                               struct pipe_resource *resource,
76bf215546Sopenharmony_ci                               unsigned level,
77bf215546Sopenharmony_ci                               unsigned usage,
78bf215546Sopenharmony_ci                               const struct pipe_box *box,
79bf215546Sopenharmony_ci                               const void *data,
80bf215546Sopenharmony_ci                               unsigned stride,
81bf215546Sopenharmony_ci                               unsigned layer_stride)
82bf215546Sopenharmony_ci{
83bf215546Sopenharmony_ci   struct pipe_transfer *transfer = NULL;
84bf215546Sopenharmony_ci   const uint8_t *src_data = data;
85bf215546Sopenharmony_ci   uint8_t *map = NULL;
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   assert(!(usage & PIPE_MAP_READ));
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   /* the write flag is implicit by the nature of texture_subdata */
90bf215546Sopenharmony_ci   usage |= PIPE_MAP_WRITE;
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   /* texture_subdata implicitly discards the rewritten buffer range */
93bf215546Sopenharmony_ci   usage |= PIPE_MAP_DISCARD_RANGE;
94bf215546Sopenharmony_ci
95bf215546Sopenharmony_ci   map = pipe->texture_map(pipe,
96bf215546Sopenharmony_ci                            resource,
97bf215546Sopenharmony_ci                            level,
98bf215546Sopenharmony_ci                            usage,
99bf215546Sopenharmony_ci                            box, &transfer);
100bf215546Sopenharmony_ci   if (!map)
101bf215546Sopenharmony_ci      return;
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci   util_copy_box(map,
104bf215546Sopenharmony_ci                 resource->format,
105bf215546Sopenharmony_ci                 transfer->stride, /* bytes */
106bf215546Sopenharmony_ci                 transfer->layer_stride, /* bytes */
107bf215546Sopenharmony_ci                 0, 0, 0,
108bf215546Sopenharmony_ci                 box->width,
109bf215546Sopenharmony_ci                 box->height,
110bf215546Sopenharmony_ci                 box->depth,
111bf215546Sopenharmony_ci                 src_data,
112bf215546Sopenharmony_ci                 stride,       /* bytes */
113bf215546Sopenharmony_ci                 layer_stride, /* bytes */
114bf215546Sopenharmony_ci                 0, 0, 0);
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci   pipe_texture_unmap(pipe, transfer);
117bf215546Sopenharmony_ci}
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_civoid u_default_transfer_flush_region(UNUSED struct pipe_context *pipe,
120bf215546Sopenharmony_ci                                     UNUSED struct pipe_transfer *transfer,
121bf215546Sopenharmony_ci                                     UNUSED const struct pipe_box *box)
122bf215546Sopenharmony_ci{
123bf215546Sopenharmony_ci   /* This is a no-op implementation, nothing to do.
124bf215546Sopenharmony_ci    */
125bf215546Sopenharmony_ci}
126