summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_screen_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_screen_buffer.c')
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c149
1 files changed, 93 insertions, 56 deletions
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index 7959e6a2f9..37a080ba48 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -43,7 +43,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context,
if (r300_buffer_is_user_buffer(buf))
return PIPE_UNREFERENCED;
- if (r300->rws->is_buffer_referenced(r300->rws, rbuf->buf, domain))
+ if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->buf, domain))
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
return PIPE_UNREFERENCED;
@@ -62,7 +62,8 @@ int r300_upload_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned index_size,
unsigned start,
- unsigned count)
+ unsigned count,
+ unsigned *out_offset)
{
struct pipe_resource *upload_buffer = NULL;
unsigned index_offset = start * index_size;
@@ -79,7 +80,10 @@ int r300_upload_index_buffer(struct r300_context *r300,
goto done;
}
*index_buffer = upload_buffer;
- }
+ *out_offset = index_offset / index_size;
+ } else
+ *out_offset = start;
+
done:
// if (upload_buffer)
// pipe_resource_reference(&upload_buffer, NULL);
@@ -119,31 +123,59 @@ int r300_upload_user_buffers(struct r300_context *r300)
return ret;
}
-static void r300_winsys_buffer_destroy(struct r300_screen *r300screen,
- struct r300_buffer *rbuf)
+static void r300_buffer_destroy(struct pipe_screen *screen,
+ struct pipe_resource *buf)
{
+ struct r300_screen *r300screen = r300_screen(screen);
+ struct r300_buffer *rbuf = r300_buffer(buf);
struct r300_winsys_screen *rws = r300screen->rws;
- if (rbuf->buf) {
- rws->buffer_reference(rws, &rbuf->buf, NULL);
- rbuf->buf = NULL;
- }
+ if (rbuf->constant_buffer)
+ FREE(rbuf->constant_buffer);
+
+ if (rbuf->buf)
+ rws->buffer_reference(rws, &rbuf->buf, NULL);
+
+ util_mempool_free(&r300screen->pool_buffers, rbuf);
}
-static void r300_buffer_destroy(struct pipe_screen *screen,
- struct pipe_resource *buf)
+static struct pipe_transfer*
+r300_default_get_transfer(struct pipe_context *context,
+ struct pipe_resource *resource,
+ struct pipe_subresource sr,
+ unsigned usage,
+ const struct pipe_box *box)
{
- struct r300_screen *r300screen = r300_screen(screen);
- struct r300_buffer *rbuf = r300_buffer(buf);
+ struct r300_context *r300 = r300_context(context);
+ struct pipe_transfer *transfer =
+ util_mempool_malloc(&r300->pool_transfers);
+
+ transfer->resource = resource;
+ transfer->sr = sr;
+ transfer->usage = usage;
+ transfer->box = *box;
+ transfer->stride = 0;
+ transfer->slice_stride = 0;
+ transfer->data = NULL;
+
+ /* Note strides are zero, this is ok for buffers, but not for
+ * textures 2d & higher at least.
+ */
+ return transfer;
+}
- r300_winsys_buffer_destroy(r300screen, rbuf);
- FREE(rbuf);
+static void r300_default_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ util_mempool_free(&r300->pool_transfers, transfer);
}
static void *
r300_buffer_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
+ struct r300_context *r300 = r300_context(pipe);
struct r300_screen *r300screen = r300_screen(pipe->screen);
struct r300_winsys_screen *rws = r300screen->rws;
struct r300_buffer *rbuf = r300_buffer(transfer->resource);
@@ -153,10 +185,8 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
if (rbuf->user_buffer)
return (uint8_t *) rbuf->user_buffer + transfer->box.x;
-
- if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
- goto just_map;
- }
+ if (rbuf->constant_buffer)
+ return (uint8_t *) rbuf->constant_buffer + transfer->box.x;
/* check if the mapping is to a range we already flushed */
if (transfer->usage & PIPE_TRANSFER_DISCARD) {
@@ -170,16 +200,18 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
rws->buffer_reference(rws, &rbuf->buf, NULL);
rbuf->num_ranges = 0;
- rbuf->buf = r300screen->rws->buffer_create(r300screen->rws, 16,
- rbuf->b.b.bind,
- rbuf->domain,
- rbuf->b.b.width0);
+ rbuf->buf =
+ r300screen->rws->buffer_create(r300screen->rws,
+ rbuf->b.b.width0, 16,
+ rbuf->b.b.bind,
+ rbuf->b.b.usage,
+ rbuf->domain);
break;
}
}
}
-just_map:
- map = rws->buffer_map(rws, rbuf->buf, transfer->usage);
+
+ map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage);
if (map == NULL)
return NULL;
@@ -204,9 +236,8 @@ static void r300_buffer_transfer_flush_region( struct pipe_context *pipe,
if (rbuf->user_buffer)
return;
-
- if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER)
- return;
+ if (rbuf->constant_buffer)
+ return;
/* mark the range as used */
for(i = 0; i < rbuf->num_ranges; ++i) {
@@ -237,14 +268,14 @@ static void r300_buffer_transfer_unmap( struct pipe_context *pipe,
struct u_resource_vtbl r300_buffer_vtbl =
{
u_default_resource_get_handle, /* get_handle */
- r300_buffer_destroy, /* resource_destroy */
- r300_buffer_is_referenced_by_cs, /* is_buffer_referenced */
- u_default_get_transfer, /* get_transfer */
- u_default_transfer_destroy, /* transfer_destroy */
- r300_buffer_transfer_map, /* transfer_map */
+ r300_buffer_destroy, /* resource_destroy */
+ r300_buffer_is_referenced_by_cs, /* is_buffer_referenced */
+ r300_default_get_transfer, /* get_transfer */
+ r300_default_transfer_destroy, /* transfer_destroy */
+ r300_buffer_transfer_map, /* transfer_map */
r300_buffer_transfer_flush_region, /* transfer_flush_region */
- r300_buffer_transfer_unmap, /* transfer_unmap */
- u_default_transfer_inline_write /* transfer_inline_write */
+ r300_buffer_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
};
struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
@@ -254,9 +285,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
struct r300_buffer *rbuf;
unsigned alignment = 16;
- rbuf = CALLOC_STRUCT(r300_buffer);
- if (!rbuf)
- goto error1;
+ rbuf = util_mempool_malloc(&r300screen->pool_buffers);
rbuf->magic = R300_BUFFER_MAGIC;
@@ -265,21 +294,29 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
pipe_reference_init(&rbuf->b.b.reference, 1);
rbuf->b.b.screen = screen;
rbuf->domain = R300_DOMAIN_GTT;
+ rbuf->num_ranges = 0;
+ rbuf->buf = NULL;
+ rbuf->constant_buffer = NULL;
+ rbuf->user_buffer = NULL;
+
+ /* Alloc constant buffers in RAM. */
+ if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) {
+ rbuf->constant_buffer = MALLOC(templ->width0);
+ return &rbuf->b.b;
+ }
- rbuf->buf = r300screen->rws->buffer_create(r300screen->rws,
- alignment,
- rbuf->b.b.bind,
- rbuf->domain,
- rbuf->b.b.width0);
+ rbuf->buf =
+ r300screen->rws->buffer_create(r300screen->rws,
+ rbuf->b.b.width0, alignment,
+ rbuf->b.b.bind, rbuf->b.b.usage,
+ rbuf->domain);
- if (!rbuf->buf)
- goto error2;
+ if (!rbuf->buf) {
+ util_mempool_free(&r300screen->pool_buffers, rbuf);
+ return NULL;
+ }
return &rbuf->b.b;
-error2:
- FREE(rbuf);
-error1:
- return NULL;
}
struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
@@ -287,28 +324,28 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
unsigned bytes,
unsigned bind)
{
+ struct r300_screen *r300screen = r300_screen(screen);
struct r300_buffer *rbuf;
- rbuf = CALLOC_STRUCT(r300_buffer);
- if (!rbuf)
- goto no_rbuf;
+ rbuf = util_mempool_malloc(&r300screen->pool_buffers);
rbuf->magic = R300_BUFFER_MAGIC;
pipe_reference_init(&rbuf->b.b.reference, 1);
rbuf->b.vtbl = &r300_buffer_vtbl;
rbuf->b.b.screen = screen;
+ rbuf->b.b.target = PIPE_BUFFER;
rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
rbuf->b.b.bind = bind;
rbuf->b.b.width0 = bytes;
rbuf->b.b.height0 = 1;
rbuf->b.b.depth0 = 1;
+ rbuf->b.b.flags = 0;
rbuf->domain = R300_DOMAIN_GTT;
-
+ rbuf->num_ranges = 0;
+ rbuf->buf = NULL;
+ rbuf->constant_buffer = NULL;
rbuf->user_buffer = ptr;
return &rbuf->b.b;
-
-no_rbuf:
- return NULL;
}