Squashed commit of the following:
[profile/ivi/mesa.git] / src / gallium / drivers / nv50 / nv50_buffer.c
1
2 #include "util/u_inlines.h"
3 #include "util/u_memory.h"
4 #include "util/u_math.h"
5
6 #include "nouveau/nouveau_screen.h"
7 #include "nouveau/nouveau_winsys.h"
8 #include "nv50_resource.h"
9
10
11
12 static void nv50_buffer_destroy(struct pipe_screen *pscreen,
13                                 struct pipe_resource *presource)
14 {
15         struct nv50_resource *buffer = nv50_resource(presource);
16
17         nouveau_screen_bo_release(pscreen, buffer->bo);
18         FREE(buffer);
19 }
20
21
22
23
24 /* Utility functions for transfer create/destroy are hooked in and
25  * just record the arguments to those functions.
26  */
27 static void *
28 nv50_buffer_transfer_map( struct pipe_context *pipe,
29                           struct pipe_transfer *transfer )
30 {
31         struct nv50_resource *buffer = nv50_resource(transfer->resource);
32         uint8_t *map;
33
34         map = nouveau_screen_bo_map_range( pipe->screen,
35                                            buffer->bo,
36                                            transfer->box.x,
37                                            transfer->box.width,
38                                            nouveau_screen_transfer_flags(transfer->usage) );
39         if (map == NULL)
40                 return NULL;
41         
42         return map + transfer->box.x;
43 }
44
45
46
47 static void nv50_buffer_transfer_flush_region( struct pipe_context *pipe,
48                                                struct pipe_transfer *transfer,
49                                                const struct pipe_box *box)
50 {
51         struct nv50_resource *buffer = nv50_resource(transfer->resource);
52
53         nouveau_screen_bo_map_flush_range(pipe->screen,
54                                           buffer->bo,
55                                           transfer->box.x + box->x,
56                                           box->width);
57 }
58
59 static void nv50_buffer_transfer_unmap( struct pipe_context *pipe,
60                                         struct pipe_transfer *transfer )
61 {
62         struct nv50_resource *buffer = nv50_resource(transfer->resource);
63
64         nouveau_screen_bo_unmap(pipe->screen, buffer->bo);
65 }
66
67
68
69
70 struct u_resource_vtbl nv50_buffer_vtbl = 
71 {
72         u_default_resource_get_handle,      /* get_handle */
73         nv50_buffer_destroy,                /* resource_destroy */
74         NULL,                               /* is_resource_referenced */
75         u_default_get_transfer,             /* get_transfer */
76         u_default_transfer_destroy,         /* transfer_destroy */
77         nv50_buffer_transfer_map,           /* transfer_map */
78         nv50_buffer_transfer_flush_region,  /* transfer_flush_region */
79         nv50_buffer_transfer_unmap,         /* transfer_unmap */
80         u_default_transfer_inline_write     /* transfer_inline_write */
81 };
82
83
84
85
86 struct pipe_resource *
87 nv50_buffer_create(struct pipe_screen *pscreen,
88                    const struct pipe_resource *template)
89 {
90         struct nv50_resource *buffer;
91
92         buffer = CALLOC_STRUCT(nv50_resource);
93         if (!buffer)
94                 return NULL;
95
96         buffer->base = *template;
97         buffer->vtbl = &nv50_buffer_vtbl;
98         pipe_reference_init(&buffer->base.reference, 1);
99         buffer->base.screen = pscreen;
100
101         buffer->bo = nouveau_screen_bo_new(pscreen,
102                                            16,
103                                            buffer->base._usage,
104                                            buffer->base.bind,
105                                            buffer->base.width0);
106
107         if (buffer->bo == NULL)
108                 goto fail;
109
110         return &buffer->base;
111
112 fail:
113         FREE(buffer);
114         return NULL;
115 }
116
117
118 struct pipe_resource *
119 nv50_user_buffer_create(struct pipe_screen *pscreen,
120                         void *ptr,
121                         unsigned bytes,
122                         unsigned bind)
123 {
124         struct nv50_resource *buffer;
125
126         buffer = CALLOC_STRUCT(nv50_resource);
127         if (!buffer)
128                 return NULL;
129
130         pipe_reference_init(&buffer->base.reference, 1);
131         buffer->vtbl = &nv50_buffer_vtbl;
132         buffer->base.screen = pscreen;
133         buffer->base.format = PIPE_FORMAT_R8_UNORM;
134         buffer->base._usage = PIPE_USAGE_IMMUTABLE;
135         buffer->base.bind = bind;
136         buffer->base.width0 = bytes;
137         buffer->base.height0 = 1;
138         buffer->base.depth0 = 1;
139
140         buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
141         if (!buffer->bo)
142                 goto fail;
143         
144         return &buffer->base;
145
146 fail:
147         FREE(buffer);
148         return NULL;
149 }
150