r300_screen_buffer.c revision b606c8a015a0e304110b48c81b3bf06701f6cae1
168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie/*
268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Copyright 2010 Red Hat Inc.
368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a
568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * copy of this software and associated documentation files (the "Software"),
668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * to deal in the Software without restriction, including without limitation
768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * on the rights to use, copy, modify, merge, publish, distribute, sub
868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * license, and/or sell copies of the Software, and to permit persons to whom
968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * the Software is furnished to do so, subject to the following conditions:
1068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
1168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * The above copyright notice and this permission notice (including the next
1268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * paragraph) shall be included in all copies or substantial portions of the
1368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Software.
1468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
1568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
1968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * USE OR OTHER DEALINGS IN THE SOFTWARE.
2268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
2368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Authors: Dave Airlie
2468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie */
250b4df63609e9fb25319debd56142a90b11d75671Marek Olšák
2668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include <stdio.h>
2768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
2868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_inlines.h"
2968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_memory.h"
3068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_upload_mgr.h"
3168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_math.h"
3268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
3368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "r300_screen_buffer.h"
3468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "r300_winsys.h"
3568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
3624ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšákunsigned r300_buffer_is_referenced(struct pipe_context *context,
3724ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšák				   struct pipe_resource *buf,
3824ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšák                                   enum r300_reference_domain domain)
3968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
40287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_context *r300 = r300_context(context);
4168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_buffer *rbuf = r300_buffer(buf);
42287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
4368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (r300_buffer_is_user_buffer(buf))
44287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 	return PIPE_UNREFERENCED;
45287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
463ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák    if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain))
47287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell        return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
4868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
49287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return PIPE_UNREFERENCED;
5068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
51287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
5224ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšákstatic unsigned r300_buffer_is_referenced_by_cs(struct pipe_context *context,
5324ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšák                                                struct pipe_resource *buf,
544c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                                unsigned level, int layer)
5524ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšák{
5624ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšák    return r300_buffer_is_referenced(context, buf, R300_REF_CS);
5724ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšák}
5824ceef7a6969ccb2243e7bb32f86d6429d9689b9Marek Olšák
597e752760d410e72cc766691bee207729f28a920aMarek Olšákvoid r300_upload_index_buffer(struct r300_context *r300,
607e752760d410e72cc766691bee207729f28a920aMarek Olšák			      struct pipe_resource **index_buffer,
617e752760d410e72cc766691bee207729f28a920aMarek Olšák			      unsigned index_size, unsigned *start,
627e752760d410e72cc766691bee207729f28a920aMarek Olšák			      unsigned count)
6368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
647e752760d410e72cc766691bee207729f28a920aMarek Olšák    unsigned index_offset;
657e752760d410e72cc766691bee207729f28a920aMarek Olšák    uint8_t *ptr = r300_buffer(*index_buffer)->user_buffer;
667e752760d410e72cc766691bee207729f28a920aMarek Olšák
677e752760d410e72cc766691bee207729f28a920aMarek Olšák    *index_buffer = NULL;
687e752760d410e72cc766691bee207729f28a920aMarek Olšák
697e752760d410e72cc766691bee207729f28a920aMarek Olšák    u_upload_data(r300->upload_ib,
707e752760d410e72cc766691bee207729f28a920aMarek Olšák                  count * index_size,
717e752760d410e72cc766691bee207729f28a920aMarek Olšák                  ptr + (*start * index_size),
727e752760d410e72cc766691bee207729f28a920aMarek Olšák                  &index_offset,
737e752760d410e72cc766691bee207729f28a920aMarek Olšák                  index_buffer);
747e752760d410e72cc766691bee207729f28a920aMarek Olšák
757e752760d410e72cc766691bee207729f28a920aMarek Olšák    *start = index_offset / index_size;
7668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
7768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
787e752760d410e72cc766691bee207729f28a920aMarek Olšákvoid r300_upload_user_buffers(struct r300_context *r300)
7968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
807e752760d410e72cc766691bee207729f28a920aMarek Olšák    int i, nr = r300->velems->count;
8168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
8268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    for (i = 0; i < nr; i++) {
831384a7bccab3d5b36729d59944a76538375f5494Marek Olšák        struct pipe_vertex_buffer *vb =
841384a7bccab3d5b36729d59944a76538375f5494Marek Olšák            &r300->vertex_buffer[r300->velems->velem[i].vertex_buffer_index];
851384a7bccab3d5b36729d59944a76538375f5494Marek Olšák
861384a7bccab3d5b36729d59944a76538375f5494Marek Olšák        if (r300_buffer_is_user_buffer(vb->buffer)) {
877e752760d410e72cc766691bee207729f28a920aMarek Olšák            u_upload_data(r300->upload_vb,
887e752760d410e72cc766691bee207729f28a920aMarek Olšák                          vb->buffer->width0,
897e752760d410e72cc766691bee207729f28a920aMarek Olšák                          r300_buffer(vb->buffer)->user_buffer,
907e752760d410e72cc766691bee207729f28a920aMarek Olšák                          &vb->buffer_offset, &vb->buffer);
917e752760d410e72cc766691bee207729f28a920aMarek Olšák
924953ba6a717ad1d3aa4426d147b52d05932c47abMarek Olšák            r300->validate_buffers = TRUE;
931384a7bccab3d5b36729d59944a76538375f5494Marek Olšák        }
9468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
9568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
9668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
97287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void r300_buffer_destroy(struct pipe_screen *screen,
98287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				struct pipe_resource *buf)
9968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
100287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_screen *r300screen = r300_screen(screen);
10168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_buffer *rbuf = r300_buffer(buf);
1025862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák    struct r300_winsys_screen *rws = r300screen->rws;
10368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
1043eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (rbuf->constant_buffer)
1053eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        FREE(rbuf->constant_buffer);
1063eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák
1075862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák    if (rbuf->buf)
1085862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák        rws->buffer_reference(rws, &rbuf->buf, NULL);
1095862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák
11080f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák    util_slab_free(&r300screen->pool_buffers, rbuf);
1117b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák}
1127b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1137b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšákstatic struct pipe_transfer*
1146a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákr300_buffer_get_transfer(struct pipe_context *context,
1156a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         struct pipe_resource *resource,
1166a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         unsigned level,
1176a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         unsigned usage,
1186a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         const struct pipe_box *box)
1197b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák{
1207b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   struct r300_context *r300 = r300_context(context);
1217b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   struct pipe_transfer *transfer =
12280f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák         util_slab_alloc(&r300->pool_transfers);
1237b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1247b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->resource = resource;
1254c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   transfer->level = level;
1267b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->usage = usage;
1277b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->box = *box;
1287b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->stride = 0;
1294c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   transfer->layer_stride = 0;
1307b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->data = NULL;
1317b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1327b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   /* Note strides are zero, this is ok for buffers, but not for
1337b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    * textures 2d & higher at least.
1347b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    */
1357b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   return transfer;
1367b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák}
1377b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1386a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákstatic void r300_buffer_transfer_destroy(struct pipe_context *pipe,
1396a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                         struct pipe_transfer *transfer)
1407b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák{
1417b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   struct r300_context *r300 = r300_context(pipe);
14280f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák   util_slab_free(&r300->pool_transfers, transfer);
14368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
14468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
14568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void *
146d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákr300_buffer_transfer_map( struct pipe_context *pipe,
147d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák			  struct pipe_transfer *transfer )
14868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
149fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    struct r300_context *r300 = r300_context(pipe);
150d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_screen *r300screen = r300_screen(pipe->screen);
15168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
152d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
153d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    uint8_t *map;
154d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    boolean flush = FALSE;
155d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned i;
15668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
15768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (rbuf->user_buffer)
1580268e8984cfee9dca38ec5e74af7a562377bf53aVinson Lee        return (uint8_t *) rbuf->user_buffer + transfer->box.x;
1593eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (rbuf->constant_buffer)
1603eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        return (uint8_t *) rbuf->constant_buffer + transfer->box.x;
16168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
16268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    /* check if the mapping is to a range we already flushed */
163d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    if (transfer->usage & PIPE_TRANSFER_DISCARD) {
16468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	for (i = 0; i < rbuf->num_ranges; i++) {
165d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák	    if ((transfer->box.x >= rbuf->ranges[i].start) &&
166d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák		(transfer->box.x < rbuf->ranges[i].end))
167d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák		flush = TRUE;
16868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
16968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    if (flush) {
17068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		/* unreference this hw buffer and allocate a new one */
17168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rws->buffer_reference(rws, &rbuf->buf, NULL);
17268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
17368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rbuf->num_ranges = 0;
174fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                rbuf->buf =
175fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                    r300screen->rws->buffer_create(r300screen->rws,
176fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->b.b.width0, 16,
177fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->b.b.bind,
178fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->b.b.usage,
179fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->domain);
1803ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák                rbuf->cs_buf =
1813ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák                    r300screen->rws->buffer_get_cs_handle(r300screen->rws,
1823ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák                                                          rbuf->buf);
18368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		break;
18468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    }
18568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	}
18668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
187b939f83eb7af8f818c638453b2d2522b2362a831Marek Olšák
188fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage);
189d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
190d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    if (map == NULL)
191d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák        return NULL;
192d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
193d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    /* map_buffer() returned a pointer to the beginning of the buffer,
194d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     * but transfers are expected to return a pointer to just the
195d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     * region specified in the box.
196d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     */
197d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    return map + transfer->box.x;
19868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
19968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
200d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákstatic void r300_buffer_transfer_flush_region( struct pipe_context *pipe,
201d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák					       struct pipe_transfer *transfer,
202d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák					       const struct pipe_box *box)
20368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
204d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
205d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned i;
206d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned offset = transfer->box.x + box->x;
207d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned length = box->width;
208d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
209d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    assert(box->x + box->width <= transfer->box.width);
21068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
21168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (rbuf->user_buffer)
21268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	return;
2133eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (rbuf->constant_buffer)
2143eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        return;
21568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
21668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    /* mark the range as used */
21768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    for(i = 0; i < rbuf->num_ranges; ++i) {
218d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák	if(offset <= rbuf->ranges[i].end && rbuf->ranges[i].start <= (offset+box->width)) {
21968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    rbuf->ranges[i].start = MIN2(rbuf->ranges[i].start, offset);
22068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    rbuf->ranges[i].end   = MAX2(rbuf->ranges[i].end, (offset+length));
22168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    return;
22268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	}
22368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
22468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
22568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->ranges[rbuf->num_ranges].start = offset;
22668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->ranges[rbuf->num_ranges].end = offset+length;
22768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->num_ranges++;
22868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
22968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
230d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákstatic void r300_buffer_transfer_unmap( struct pipe_context *pipe,
231d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák			    struct pipe_transfer *transfer )
23268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
233d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_screen *r300screen = r300_screen(pipe->screen);
23468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
235d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
23668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
237287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (rbuf->buf) {
238287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell        rws->buffer_unmap(rws, rbuf->buf);
239287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    }
240287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
24168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
2426a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákstatic void r300_buffer_transfer_inline_write(struct pipe_context *pipe,
2436a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              struct pipe_resource *resource,
2446a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned level,
2456a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned usage,
2466a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              const struct pipe_box *box,
2476a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              const void *data,
2486a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned stride,
2496a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned layer_stride)
2506a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák{
251b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    struct r300_context *r300 = r300_context(pipe);
252b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    struct r300_winsys_screen *rws = r300->screen->rws;
2536a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    struct r300_buffer *rbuf = r300_buffer(resource);
2546a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    uint8_t *map = NULL;
2556a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
2566a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    if (rbuf->constant_buffer) {
2576a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák        memcpy(rbuf->constant_buffer + box->x, data, box->width);
2586a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák        return;
2596a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    }
260b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    assert(rbuf->user_buffer == NULL);
2616a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
262b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    map = rws->buffer_map(rws, rbuf->buf, r300->cs,
263b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák                          PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage);
2646a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
265b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    memcpy(map + box->x, data, box->width);
2666a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
267b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    rws->buffer_unmap(rws, rbuf->buf);
2686a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák}
2696a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
270b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšákstruct u_resource_vtbl r300_buffer_vtbl =
271287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
272287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_resource_get_handle,      /* get_handle */
2737b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_destroy,                /* resource_destroy */
2747b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_is_referenced_by_cs,    /* is_buffer_referenced */
2756a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák   r300_buffer_get_transfer,           /* get_transfer */
2766a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák   r300_buffer_transfer_destroy,       /* transfer_destroy */
2777b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_transfer_map,           /* transfer_map */
278287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   r300_buffer_transfer_flush_region,  /* transfer_flush_region */
2797b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_transfer_unmap,         /* transfer_unmap */
2806a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák   r300_buffer_transfer_inline_write   /* transfer_inline_write */
281287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell};
282287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
283287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
284bb4f5fff0c782f35353e8bfc1b1227e3cc3d5986Marek Olšák					 const struct pipe_resource *templ)
28568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
28668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_screen *r300screen = r300_screen(screen);
287287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_buffer *rbuf;
288287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    unsigned alignment = 16;
28968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
29080f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák    rbuf = util_slab_alloc(&r300screen->pool_buffers);
291287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
292287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->magic = R300_BUFFER_MAGIC;
293287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
294bb4f5fff0c782f35353e8bfc1b1227e3cc3d5986Marek Olšák    rbuf->b.b = *templ;
295287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.vtbl = &r300_buffer_vtbl;
296287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    pipe_reference_init(&rbuf->b.b.reference, 1);
297287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.screen = screen;
298b6b76cbb20b3d9467011231069e23972b98afa49Marek Olšák    rbuf->domain = R300_DOMAIN_GTT;
2997b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->num_ranges = 0;
3007b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->buf = NULL;
3017b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->constant_buffer = NULL;
3027b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->user_buffer = NULL;
303b6b76cbb20b3d9467011231069e23972b98afa49Marek Olšák
3043eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    /* Alloc constant buffers in RAM. */
3053eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) {
3063eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        rbuf->constant_buffer = MALLOC(templ->width0);
3073eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        return &rbuf->b.b;
3083eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    }
3093eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák
310fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    rbuf->buf =
311fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        r300screen->rws->buffer_create(r300screen->rws,
312fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                       rbuf->b.b.width0, alignment,
313fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                       rbuf->b.b.bind, rbuf->b.b.usage,
314fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                       rbuf->domain);
3153ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák    rbuf->cs_buf =
3163ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák        r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf);
317287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
3187b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    if (!rbuf->buf) {
31980f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák        util_slab_free(&r300screen->pool_buffers, rbuf);
3207b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák        return NULL;
3217b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    }
322287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
323287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return &rbuf->b.b;
32468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
32568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
326287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
327287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      void *ptr,
328287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      unsigned bytes,
329287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      unsigned bind)
33068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
3317b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    struct r300_screen *r300screen = r300_screen(screen);
332287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_buffer *rbuf;
333287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
33480f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák    rbuf = util_slab_alloc(&r300screen->pool_buffers);
335287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
336287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->magic = R300_BUFFER_MAGIC;
337287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
338287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    pipe_reference_init(&rbuf->b.b.reference, 1);
339287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.vtbl = &r300_buffer_vtbl;
340287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.screen = screen;
3417b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->b.b.target = PIPE_BUFFER;
342287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
343a2a01853f3f40b4ef8b3f01503391877960bdaeeBrian Paul    rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
344287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.bind = bind;
345287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.width0 = bytes;
346287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.height0 = 1;
347287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.depth0 = 1;
3484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    rbuf->b.b.array_size = 1;
3497b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->b.b.flags = 0;
350b6b76cbb20b3d9467011231069e23972b98afa49Marek Olšák    rbuf->domain = R300_DOMAIN_GTT;
3517b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->num_ranges = 0;
3527b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->buf = NULL;
3537b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->constant_buffer = NULL;
354287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->user_buffer = ptr;
355287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return &rbuf->b.b;
35668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
357