Squashed commit of the following:
[mesa.git] / src / gallium / drivers / i965 / brw_resource_buffer.c
1
2 #include "util/u_memory.h"
3 #include "util/u_math.h"
4
5 #include "pipe/p_state.h"
6 #include "pipe/p_defines.h"
7 #include "util/u_inlines.h"
8
9 #include "brw_resource.h"
10 #include "brw_context.h"
11 #include "brw_batchbuffer.h"
12 #include "brw_winsys.h"
13
14 static boolean
15 brw_buffer_get_handle(struct pipe_screen *screen,
16 struct pipe_resource *resource,
17 struct winsys_handle *handle)
18 {
19 return FALSE;
20 }
21
22
23 static void
24 brw_buffer_destroy(struct pipe_screen *screen,
25 struct pipe_resource *resource)
26 {
27 struct brw_buffer *buf = brw_buffer( resource );
28
29 bo_reference(&buf->bo, NULL);
30 FREE(buf);
31 }
32
33
34 static void *
35 brw_buffer_transfer_map( struct pipe_context *pipe,
36 struct pipe_transfer *transfer)
37 {
38 struct brw_screen *bscreen = brw_screen(pipe->screen);
39 struct brw_winsys_screen *sws = bscreen->sws;
40 struct brw_buffer *buf = brw_buffer(transfer->resource);
41 unsigned offset = transfer->box.x;
42 unsigned length = transfer->box.width;
43 unsigned usage = transfer->usage;
44 uint8_t *map;
45
46 if (buf->user_buffer)
47 map = buf->user_buffer;
48 else
49 map = sws->bo_map( buf->bo,
50 BRW_DATA_OTHER,
51 offset,
52 length,
53 (usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE,
54 (usage & PIPE_TRANSFER_DISCARD) ? TRUE : FALSE,
55 (usage & PIPE_TRANSFER_FLUSH_EXPLICIT) ? TRUE : FALSE);
56
57 return map + offset;
58 }
59
60
61 static void
62 brw_buffer_transfer_flush_region( struct pipe_context *pipe,
63 struct pipe_transfer *transfer,
64 const struct pipe_box *box)
65 {
66 struct brw_screen *bscreen = brw_screen(pipe->screen);
67 struct brw_winsys_screen *sws = bscreen->sws;
68 struct brw_buffer *buf = brw_buffer(transfer->resource);
69 unsigned offset = box->x;
70 unsigned length = box->width;
71
72 if (buf->user_buffer)
73 return;
74
75 sws->bo_flush_range( buf->bo,
76 offset,
77 length );
78 }
79
80
81 static void
82 brw_buffer_transfer_unmap( struct pipe_context *pipe,
83 struct pipe_transfer *transfer)
84 {
85 struct brw_screen *bscreen = brw_screen(pipe->screen);
86 struct brw_winsys_screen *sws = bscreen->sws;
87 struct brw_buffer *buf = brw_buffer( transfer->resource );
88
89 if (buf->bo)
90 sws->bo_unmap(buf->bo);
91 }
92
93
94 static unsigned brw_buffer_is_referenced( struct pipe_context *pipe,
95 struct pipe_resource *resource,
96 unsigned face,
97 unsigned level)
98 {
99 struct brw_context *brw = brw_context(pipe);
100 struct brw_winsys_buffer *batch_bo = brw->batch->buf;
101 struct brw_buffer *buf = brw_buffer(resource);
102
103 if (buf->bo == NULL)
104 return PIPE_UNREFERENCED;
105
106 if (!brw_screen(pipe->screen)->sws->bo_references( batch_bo, buf->bo ))
107 return PIPE_UNREFERENCED;
108
109 return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
110 }
111
112
113 struct u_resource_vtbl brw_buffer_vtbl =
114 {
115 brw_buffer_get_handle, /* get_handle */
116 brw_buffer_destroy, /* resource_destroy */
117 brw_buffer_is_referenced, /* is_resource_referenced */
118 u_default_get_transfer, /* get_transfer */
119 u_default_transfer_destroy, /* transfer_destroy */
120 brw_buffer_transfer_map, /* transfer_map */
121 brw_buffer_transfer_flush_region, /* transfer_flush_region */
122 brw_buffer_transfer_unmap, /* transfer_unmap */
123 u_default_transfer_inline_write /* transfer_inline_write */
124 };
125
126
127 struct pipe_resource *
128 brw_buffer_create(struct pipe_screen *screen,
129 const struct pipe_resource *template)
130 {
131 struct brw_screen *bscreen = brw_screen(screen);
132 struct brw_winsys_screen *sws = bscreen->sws;
133 struct brw_buffer *buf;
134 unsigned buffer_type;
135 enum pipe_error ret;
136
137 buf = CALLOC_STRUCT(brw_buffer);
138 if (!buf)
139 return NULL;
140
141 buf->b.b = *template;
142 buf->b.vtbl = &brw_buffer_vtbl;
143 pipe_reference_init(&buf->b.b.reference, 1);
144 buf->b.b.screen = screen;
145
146 switch (template->bind & (PIPE_BIND_VERTEX_BUFFER |
147 PIPE_BIND_INDEX_BUFFER |
148 PIPE_BIND_CONSTANT_BUFFER))
149 {
150 case PIPE_BIND_VERTEX_BUFFER:
151 case PIPE_BIND_INDEX_BUFFER:
152 case (PIPE_BIND_VERTEX_BUFFER|PIPE_BIND_INDEX_BUFFER):
153 buffer_type = BRW_BUFFER_TYPE_VERTEX;
154 break;
155
156 case PIPE_BIND_CONSTANT_BUFFER:
157 buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS;
158 break;
159
160 default:
161 buffer_type = BRW_BUFFER_TYPE_GENERIC;
162 break;
163 }
164
165 ret = sws->bo_alloc( sws, buffer_type,
166 template->width0,
167 64, /* alignment */
168 &buf->bo );
169 if (ret != PIPE_OK)
170 return NULL;
171
172 return &buf->b.b;
173 }
174
175
176 struct pipe_resource *
177 brw_user_buffer_create(struct pipe_screen *screen,
178 void *ptr,
179 unsigned bytes,
180 unsigned bind)
181 {
182 struct brw_buffer *buf;
183
184 buf = CALLOC_STRUCT(brw_buffer);
185 if (!buf)
186 return NULL;
187
188 pipe_reference_init(&buf->b.b.reference, 1);
189 buf->b.vtbl = &brw_buffer_vtbl;
190 buf->b.b.screen = screen;
191 buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */
192 buf->b.b._usage = PIPE_USAGE_IMMUTABLE;
193 buf->b.b.bind = bind;
194 buf->b.b.width0 = bytes;
195 buf->b.b.height0 = 1;
196 buf->b.b.depth0 = 1;
197
198 buf->user_buffer = ptr;
199
200 return &buf->b.b;
201 }