nvc0: generate shader header for geometry programs
[mesa.git] / src / gallium / drivers / nvc0 / nvc0_buffer.c
1
2 #include "util/u_inlines.h"
3 #include "util/u_memory.h"
4 #include "util/u_math.h"
5
6 #define NOUVEAU_NVC0
7 #include "nouveau/nouveau_screen.h"
8 #include "nouveau/nouveau_winsys.h"
9 #undef NOUVEAU_NVC0
10
11 #include "nvc0_context.h"
12 #include "nvc0_resource.h"
13
14 static void
15 nvc0_buffer_destroy(struct pipe_screen *pscreen,
16 struct pipe_resource *presource)
17 {
18 struct nvc0_resource *res = nvc0_resource(presource);
19
20 if (res->bo)
21 nouveau_screen_bo_release(pscreen, res->bo);
22
23 if (res->data)
24 FREE(res->data);
25
26 FREE(res);
27 }
28
29 static void *
30 nvc0_buffer_transfer_map(struct pipe_context *pipe,
31 struct pipe_transfer *transfer)
32 {
33 struct nvc0_resource *res = nvc0_resource(transfer->resource);
34 uint8_t *map;
35 uint32_t flags;
36
37 if (res->base.bind & PIPE_BIND_VERTEX_BUFFER)
38 nvc0_context(pipe)->vbo_dirty = TRUE;
39
40 // #ifdef NOUVEAU_USERPSACE_MM
41 if (res->base.bind & PIPE_BIND_CONSTANT_BUFFER)
42 return res->data + transfer->box.x;
43 // #endif
44 flags = nouveau_screen_transfer_flags(transfer->usage);
45
46 map = nouveau_screen_bo_map_range(pipe->screen,
47 res->bo,
48 transfer->box.x, transfer->box.width,
49 flags);
50 if (!map)
51 return NULL;
52
53 return map + transfer->box.x;
54 }
55
56
57
58 static void
59 nvc0_buffer_transfer_flush_region(struct pipe_context *pipe,
60 struct pipe_transfer *transfer,
61 const struct pipe_box *box)
62 {
63 struct nvc0_resource *res = nvc0_resource(transfer->resource);
64
65 #ifdef NOUVEAU_USERPSACE_MM
66 if (!res->bo)
67 return;
68 #endif
69 nouveau_screen_bo_map_flush_range(pipe->screen,
70 res->bo,
71 transfer->box.x + box->x,
72 box->width);
73 }
74
75 static void
76 nvc0_buffer_transfer_unmap(struct pipe_context *pipe,
77 struct pipe_transfer *transfer)
78 {
79 struct nvc0_resource *res = nvc0_resource(transfer->resource);
80
81 // #ifdef NOUVEAU_USERPSACE_MM
82 if (res->data)
83 return;
84 // #endif
85 nouveau_screen_bo_unmap(pipe->screen, res->bo);
86 }
87
88 const struct u_resource_vtbl nvc0_buffer_vtbl =
89 {
90 u_default_resource_get_handle, /* get_handle */
91 nvc0_buffer_destroy, /* resource_destroy */
92 NULL, /* is_resource_referenced */
93 u_default_get_transfer, /* get_transfer */
94 u_default_transfer_destroy, /* transfer_destroy */
95 nvc0_buffer_transfer_map, /* transfer_map */
96 nvc0_buffer_transfer_flush_region, /* transfer_flush_region */
97 nvc0_buffer_transfer_unmap, /* transfer_unmap */
98 u_default_transfer_inline_write /* transfer_inline_write */
99 };
100
101 struct pipe_resource *
102 nvc0_buffer_create(struct pipe_screen *pscreen,
103 const struct pipe_resource *templ)
104 {
105 struct nvc0_resource *buffer;
106
107 buffer = CALLOC_STRUCT(nvc0_resource);
108 if (!buffer)
109 return NULL;
110
111 buffer->base = *templ;
112 buffer->vtbl = &nvc0_buffer_vtbl;
113 pipe_reference_init(&buffer->base.reference, 1);
114 buffer->base.screen = pscreen;
115
116 if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER)
117 buffer->data = MALLOC(buffer->base.width0);
118
119 buffer->bo = nouveau_screen_bo_new(pscreen,
120 16,
121 buffer->base.usage,
122 buffer->base.bind,
123 buffer->base.width0);
124 if (buffer->bo == NULL)
125 goto fail;
126
127 return &buffer->base;
128
129 fail:
130 FREE(buffer);
131 return NULL;
132 }
133
134
135 struct pipe_resource *
136 nvc0_user_buffer_create(struct pipe_screen *pscreen,
137 void *ptr,
138 unsigned bytes,
139 unsigned bind)
140 {
141 struct nvc0_resource *buffer;
142
143 buffer = CALLOC_STRUCT(nvc0_resource);
144 if (!buffer)
145 return NULL;
146
147 pipe_reference_init(&buffer->base.reference, 1);
148 buffer->vtbl = &nvc0_buffer_vtbl;
149 buffer->base.screen = pscreen;
150 buffer->base.format = PIPE_FORMAT_R8_UNORM;
151 buffer->base.usage = PIPE_USAGE_IMMUTABLE;
152 buffer->base.bind = bind;
153 buffer->base.width0 = bytes;
154 buffer->base.height0 = 1;
155 buffer->base.depth0 = 1;
156
157 buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
158 if (!buffer->bo)
159 goto fail;
160
161 return &buffer->base;
162
163 fail:
164 FREE(buffer);
165 return NULL;
166 }