80
72
static void *r600_buffer_transfer_map(struct pipe_context *pipe,
81
73
struct pipe_transfer *transfer)
83
struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
75
struct r600_resource *rbuffer = r600_resource(transfer->resource);
76
struct r600_pipe_context *rctx = (struct r600_pipe_context*)pipe;
86
if (rbuffer->r.b.user_ptr)
87
return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x;
79
if (rbuffer->b.user_ptr)
80
return (uint8_t*)rbuffer->b.user_ptr + transfer->box.x;
89
data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, transfer->usage, pipe);
82
data = rctx->ws->buffer_map(rbuffer->buf, rctx->ctx.cs, transfer->usage);
128
121
unsigned layer_stride)
130
struct radeon *ws = (struct radeon*)pipe->winsys;
131
struct r600_resource_buffer *rbuffer = r600_buffer(resource);
123
struct r600_pipe_context *rctx = (struct r600_pipe_context*)pipe;
124
struct r600_resource *rbuffer = r600_resource(resource);
132
125
uint8_t *map = NULL;
134
assert(rbuffer->r.b.user_ptr == NULL);
127
assert(rbuffer->b.user_ptr == NULL);
136
map = r600_bo_map(ws, rbuffer->r.bo,
137
PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage,
129
map = rctx->ws->buffer_map(rbuffer->buf, rctx->ctx.cs,
130
PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE | usage);
140
132
memcpy(map + box->x, data, box->width);
143
r600_bo_unmap(ws, rbuffer->r.bo);
134
rctx->ws->buffer_unmap(rbuffer->buf);
146
137
static const struct u_resource_vtbl r600_buffer_vtbl =
155
146
r600_buffer_transfer_inline_write /* transfer_inline_write */
149
bool r600_init_resource(struct r600_screen *rscreen,
150
struct r600_resource *res,
151
unsigned size, unsigned alignment,
152
unsigned bind, unsigned usage)
154
uint32_t initial_domain, domains;
156
/* Staging resources particpate in transfers and blits only
157
* and are used for uploads and downloads from regular
158
* resources. We generate them internally for some transfers.
160
if (usage == PIPE_USAGE_STAGING) {
161
domains = RADEON_DOMAIN_GTT;
162
initial_domain = RADEON_DOMAIN_GTT;
164
domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
167
case PIPE_USAGE_DYNAMIC:
168
case PIPE_USAGE_STREAM:
169
case PIPE_USAGE_STAGING:
170
initial_domain = RADEON_DOMAIN_GTT;
172
case PIPE_USAGE_DEFAULT:
173
case PIPE_USAGE_STATIC:
174
case PIPE_USAGE_IMMUTABLE:
176
initial_domain = RADEON_DOMAIN_VRAM;
181
res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment, bind, initial_domain);
186
res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf);
187
res->domains = domains;
158
191
struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
159
192
const struct pipe_resource *templ)
161
194
struct r600_screen *rscreen = (struct r600_screen*)screen;
162
struct r600_resource_buffer *rbuffer;
195
struct r600_resource *rbuffer;
164
196
/* XXX We probably want a different alignment for buffers and textures. */
165
197
unsigned alignment = 4096;
167
199
rbuffer = util_slab_alloc(&rscreen->pool_buffers);
169
rbuffer->magic = R600_BUFFER_MAGIC;
170
rbuffer->r.b.b.b = *templ;
171
pipe_reference_init(&rbuffer->r.b.b.b.reference, 1);
172
rbuffer->r.b.b.b.screen = screen;
173
rbuffer->r.b.b.vtbl = &r600_buffer_vtbl;
174
rbuffer->r.b.user_ptr = NULL;
175
rbuffer->r.size = rbuffer->r.b.b.b.width0;
176
rbuffer->r.bo_size = rbuffer->r.size;
178
bo = r600_bo((struct radeon*)screen->winsys,
179
rbuffer->r.b.b.b.width0,
180
alignment, rbuffer->r.b.b.b.bind,
181
rbuffer->r.b.b.b.usage);
201
rbuffer->b.b.b = *templ;
202
pipe_reference_init(&rbuffer->b.b.b.reference, 1);
203
rbuffer->b.b.b.screen = screen;
204
rbuffer->b.b.vtbl = &r600_buffer_vtbl;
205
rbuffer->b.user_ptr = NULL;
207
if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, templ->bind, templ->usage)) {
208
util_slab_free(&rscreen->pool_buffers, rbuffer);
188
return &rbuffer->r.b.b.b;
211
return &rbuffer->b.b.b;
191
214
struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
195
218
struct r600_screen *rscreen = (struct r600_screen*)screen;
196
struct r600_resource_buffer *rbuffer;
219
struct r600_resource *rbuffer;
198
221
rbuffer = util_slab_alloc(&rscreen->pool_buffers);
200
rbuffer->magic = R600_BUFFER_MAGIC;
201
pipe_reference_init(&rbuffer->r.b.b.b.reference, 1);
202
rbuffer->r.b.b.vtbl = &r600_buffer_vtbl;
203
rbuffer->r.b.b.b.screen = screen;
204
rbuffer->r.b.b.b.target = PIPE_BUFFER;
205
rbuffer->r.b.b.b.format = PIPE_FORMAT_R8_UNORM;
206
rbuffer->r.b.b.b.usage = PIPE_USAGE_IMMUTABLE;
207
rbuffer->r.b.b.b.bind = bind;
208
rbuffer->r.b.b.b.width0 = bytes;
209
rbuffer->r.b.b.b.height0 = 1;
210
rbuffer->r.b.b.b.depth0 = 1;
211
rbuffer->r.b.b.b.array_size = 1;
212
rbuffer->r.b.b.b.flags = 0;
213
rbuffer->r.b.user_ptr = ptr;
214
rbuffer->r.bo = NULL;
215
rbuffer->r.bo_size = 0;
216
return &rbuffer->r.b.b.b;
219
struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
220
struct winsys_handle *whandle)
222
struct radeon *rw = (struct radeon*)screen->winsys;
223
struct r600_resource *rbuffer;
224
struct r600_bo *bo = NULL;
226
bo = r600_bo_handle(rw, whandle->handle, NULL);
231
rbuffer = CALLOC_STRUCT(r600_resource);
232
if (rbuffer == NULL) {
233
r600_bo_reference(rw, &bo, NULL);
237
223
pipe_reference_init(&rbuffer->b.b.b.reference, 1);
224
rbuffer->b.b.vtbl = &r600_buffer_vtbl;
225
rbuffer->b.b.b.screen = screen;
238
226
rbuffer->b.b.b.target = PIPE_BUFFER;
239
rbuffer->b.b.b.screen = screen;
240
rbuffer->b.b.vtbl = &r600_buffer_vtbl;
227
rbuffer->b.b.b.format = PIPE_FORMAT_R8_UNORM;
228
rbuffer->b.b.b.usage = PIPE_USAGE_IMMUTABLE;
229
rbuffer->b.b.b.bind = bind;
230
rbuffer->b.b.b.width0 = bytes;
231
rbuffer->b.b.b.height0 = 1;
232
rbuffer->b.b.b.depth0 = 1;
233
rbuffer->b.b.b.array_size = 1;
234
rbuffer->b.b.b.flags = 0;
235
rbuffer->b.user_ptr = ptr;
242
237
return &rbuffer->b.b.b;
245
void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw)
240
void r600_upload_index_buffer(struct r600_pipe_context *rctx,
241
struct pipe_index_buffer *ib, unsigned count)
247
struct r600_resource_buffer *rbuffer = r600_buffer(draw->index_buffer);
243
struct r600_resource *rbuffer = r600_resource(ib->buffer);
250
u_upload_data(rctx->vbuf_mgr->uploader, 0,
251
draw->info.count * draw->index_size,
252
rbuffer->r.b.user_ptr,
253
&draw->index_buffer_offset,
254
&draw->index_buffer, &flushed);
245
u_upload_data(rctx->vbuf_mgr->uploader, 0, count * ib->index_size,
246
rbuffer->b.user_ptr, &ib->offset, &ib->buffer);
257
void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource_buffer **rbuffer,
249
void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource **rbuffer,
258
250
uint32_t *const_offset)
260
if ((*rbuffer)->r.b.user_ptr) {
261
uint8_t *ptr = (*rbuffer)->r.b.user_ptr;
262
unsigned size = (*rbuffer)->r.b.b.b.width0;
252
if ((*rbuffer)->b.user_ptr) {
253
uint8_t *ptr = (*rbuffer)->b.user_ptr;
254
unsigned size = (*rbuffer)->b.b.b.width0;
280
271
u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset,
281
(struct pipe_resource**)rbuffer, &flushed);
272
(struct pipe_resource**)rbuffer);
285
276
u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset,
286
(struct pipe_resource**)rbuffer, &flushed);
277
(struct pipe_resource**)rbuffer);
289
280
*const_offset = 0;