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