r300_screen_buffer.c revision 31afa7616e3c11e9874f3297ac66ebdd50a67186
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;
6631afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák    boolean flushed;
677e752760d410e72cc766691bee207729f28a920aMarek Olšák
687e752760d410e72cc766691bee207729f28a920aMarek Olšák    *index_buffer = NULL;
697e752760d410e72cc766691bee207729f28a920aMarek Olšák
707e752760d410e72cc766691bee207729f28a920aMarek Olšák    u_upload_data(r300->upload_ib,
7106286110b4fc0ff80ae21bb3d8ff9909db1f5d47Marek Olšák                  0, count * index_size,
727e752760d410e72cc766691bee207729f28a920aMarek Olšák                  ptr + (*start * index_size),
737e752760d410e72cc766691bee207729f28a920aMarek Olšák                  &index_offset,
7406286110b4fc0ff80ae21bb3d8ff9909db1f5d47Marek Olšák                  index_buffer, &flushed);
757e752760d410e72cc766691bee207729f28a920aMarek Olšák
767e752760d410e72cc766691bee207729f28a920aMarek Olšák    *start = index_offset / index_size;
7731afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák
7831afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák    if (flushed || !r300->upload_ib_validated) {
7931afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák        r300->upload_ib_validated = FALSE;
8031afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák        r300->validate_buffers = TRUE;
8131afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák    }
8268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
8368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
847e752760d410e72cc766691bee207729f28a920aMarek Olšákvoid r300_upload_user_buffers(struct r300_context *r300)
8568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
867e752760d410e72cc766691bee207729f28a920aMarek Olšák    int i, nr = r300->velems->count;
8706286110b4fc0ff80ae21bb3d8ff9909db1f5d47Marek Olšák    boolean flushed;
8868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
8968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    for (i = 0; i < nr; i++) {
901384a7bccab3d5b36729d59944a76538375f5494Marek Olšák        struct pipe_vertex_buffer *vb =
911384a7bccab3d5b36729d59944a76538375f5494Marek Olšák            &r300->vertex_buffer[r300->velems->velem[i].vertex_buffer_index];
921384a7bccab3d5b36729d59944a76538375f5494Marek Olšák
931384a7bccab3d5b36729d59944a76538375f5494Marek Olšák        if (r300_buffer_is_user_buffer(vb->buffer)) {
947e752760d410e72cc766691bee207729f28a920aMarek Olšák            u_upload_data(r300->upload_vb,
9506286110b4fc0ff80ae21bb3d8ff9909db1f5d47Marek Olšák                          0, vb->buffer->width0,
967e752760d410e72cc766691bee207729f28a920aMarek Olšák                          r300_buffer(vb->buffer)->user_buffer,
9706286110b4fc0ff80ae21bb3d8ff9909db1f5d47Marek Olšák                          &vb->buffer_offset, &vb->buffer, &flushed);
987e752760d410e72cc766691bee207729f28a920aMarek Olšák
9933e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák            r300->vertex_arrays_dirty = TRUE;
10031afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák
10131afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák            if (flushed || !r300->upload_vb_validated) {
10231afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák                r300->upload_vb_validated = FALSE;
10331afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák                r300->validate_buffers = TRUE;
10431afa7616e3c11e9874f3297ac66ebdd50a67186Marek Olšák            }
1051384a7bccab3d5b36729d59944a76538375f5494Marek Olšák        }
10668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
10768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
10868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
109287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void r300_buffer_destroy(struct pipe_screen *screen,
110287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				struct pipe_resource *buf)
11168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
112287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_screen *r300screen = r300_screen(screen);
11368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_buffer *rbuf = r300_buffer(buf);
1145862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák    struct r300_winsys_screen *rws = r300screen->rws;
11568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
1163eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (rbuf->constant_buffer)
1173eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        FREE(rbuf->constant_buffer);
1183eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák
1195862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák    if (rbuf->buf)
1205862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák        rws->buffer_reference(rws, &rbuf->buf, NULL);
1215862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák
12280f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák    util_slab_free(&r300screen->pool_buffers, rbuf);
1237b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák}
1247b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1257b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšákstatic struct pipe_transfer*
1266a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákr300_buffer_get_transfer(struct pipe_context *context,
1276a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         struct pipe_resource *resource,
1286a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         unsigned level,
1296a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         unsigned usage,
1306a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                         const struct pipe_box *box)
1317b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák{
1327b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   struct r300_context *r300 = r300_context(context);
1337b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   struct pipe_transfer *transfer =
13480f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák         util_slab_alloc(&r300->pool_transfers);
1357b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1367b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->resource = resource;
1374c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   transfer->level = level;
1387b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->usage = usage;
1397b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->box = *box;
1407b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->stride = 0;
1414c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   transfer->layer_stride = 0;
1427b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   transfer->data = NULL;
1437b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1447b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   /* Note strides are zero, this is ok for buffers, but not for
1457b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    * textures 2d & higher at least.
1467b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    */
1477b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   return transfer;
1487b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák}
1497b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák
1506a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákstatic void r300_buffer_transfer_destroy(struct pipe_context *pipe,
1516a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                         struct pipe_transfer *transfer)
1527b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák{
1537b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   struct r300_context *r300 = r300_context(pipe);
15480f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák   util_slab_free(&r300->pool_transfers, transfer);
15568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
15668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
15768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void *
158d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákr300_buffer_transfer_map( struct pipe_context *pipe,
159d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák			  struct pipe_transfer *transfer )
16068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
161fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    struct r300_context *r300 = r300_context(pipe);
162d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_screen *r300screen = r300_screen(pipe->screen);
16368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
164d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
165d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    uint8_t *map;
166d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    boolean flush = FALSE;
167d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned i;
16868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
16968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (rbuf->user_buffer)
1700268e8984cfee9dca38ec5e74af7a562377bf53aVinson Lee        return (uint8_t *) rbuf->user_buffer + transfer->box.x;
1713eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (rbuf->constant_buffer)
1723eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        return (uint8_t *) rbuf->constant_buffer + transfer->box.x;
17368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
17468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    /* check if the mapping is to a range we already flushed */
175d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    if (transfer->usage & PIPE_TRANSFER_DISCARD) {
17668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	for (i = 0; i < rbuf->num_ranges; i++) {
177d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák	    if ((transfer->box.x >= rbuf->ranges[i].start) &&
178d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák		(transfer->box.x < rbuf->ranges[i].end))
179d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák		flush = TRUE;
18068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
18168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    if (flush) {
18268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		/* unreference this hw buffer and allocate a new one */
18368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rws->buffer_reference(rws, &rbuf->buf, NULL);
18468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
18568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rbuf->num_ranges = 0;
186fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                rbuf->buf =
187fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                    r300screen->rws->buffer_create(r300screen->rws,
188fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->b.b.width0, 16,
189fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->b.b.bind,
190fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->b.b.usage,
191fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                                   rbuf->domain);
1923ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák                rbuf->cs_buf =
1933ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák                    r300screen->rws->buffer_get_cs_handle(r300screen->rws,
1943ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák                                                          rbuf->buf);
19568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		break;
19668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    }
19768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	}
19868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
199b939f83eb7af8f818c638453b2d2522b2362a831Marek Olšák
200fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage);
201d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
202d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    if (map == NULL)
203d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák        return NULL;
204d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
205d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    /* map_buffer() returned a pointer to the beginning of the buffer,
206d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     * but transfers are expected to return a pointer to just the
207d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     * region specified in the box.
208d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     */
209d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    return map + transfer->box.x;
21068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
21168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
212d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákstatic void r300_buffer_transfer_flush_region( struct pipe_context *pipe,
213d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák					       struct pipe_transfer *transfer,
214d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák					       const struct pipe_box *box)
21568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
216d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
217d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned i;
218d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned offset = transfer->box.x + box->x;
219d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned length = box->width;
220d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
221d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    assert(box->x + box->width <= transfer->box.width);
22268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
22368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (rbuf->user_buffer)
22468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	return;
2253eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (rbuf->constant_buffer)
2263eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        return;
22768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
22868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    /* mark the range as used */
22968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    for(i = 0; i < rbuf->num_ranges; ++i) {
230d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák	if(offset <= rbuf->ranges[i].end && rbuf->ranges[i].start <= (offset+box->width)) {
23168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    rbuf->ranges[i].start = MIN2(rbuf->ranges[i].start, offset);
23268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    rbuf->ranges[i].end   = MAX2(rbuf->ranges[i].end, (offset+length));
23368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    return;
23468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	}
23568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
23668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
23768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->ranges[rbuf->num_ranges].start = offset;
23868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->ranges[rbuf->num_ranges].end = offset+length;
23968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->num_ranges++;
24068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
24168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
242d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákstatic void r300_buffer_transfer_unmap( struct pipe_context *pipe,
243d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák			    struct pipe_transfer *transfer )
24468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
245d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_screen *r300screen = r300_screen(pipe->screen);
24668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
247d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
24868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
249287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (rbuf->buf) {
250287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell        rws->buffer_unmap(rws, rbuf->buf);
251287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    }
252287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
25368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
2546a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákstatic void r300_buffer_transfer_inline_write(struct pipe_context *pipe,
2556a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              struct pipe_resource *resource,
2566a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned level,
2576a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned usage,
2586a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              const struct pipe_box *box,
2596a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              const void *data,
2606a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned stride,
2616a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák                                              unsigned layer_stride)
2626a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák{
263b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    struct r300_context *r300 = r300_context(pipe);
264b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    struct r300_winsys_screen *rws = r300->screen->rws;
2656a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    struct r300_buffer *rbuf = r300_buffer(resource);
2666a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    uint8_t *map = NULL;
2676a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
2686a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    if (rbuf->constant_buffer) {
2696a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák        memcpy(rbuf->constant_buffer + box->x, data, box->width);
2706a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák        return;
2716a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák    }
272b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    assert(rbuf->user_buffer == NULL);
2736a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
274b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    map = rws->buffer_map(rws, rbuf->buf, r300->cs,
275b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák                          PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage);
2766a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
277b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    memcpy(map + box->x, data, box->width);
2786a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
279b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšák    rws->buffer_unmap(rws, rbuf->buf);
2806a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák}
2816a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák
282b606c8a015a0e304110b48c81b3bf06701f6cae1Marek Olšákstruct u_resource_vtbl r300_buffer_vtbl =
283287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
284287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_resource_get_handle,      /* get_handle */
2857b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_destroy,                /* resource_destroy */
2867b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_is_referenced_by_cs,    /* is_buffer_referenced */
2876a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák   r300_buffer_get_transfer,           /* get_transfer */
2886a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák   r300_buffer_transfer_destroy,       /* transfer_destroy */
2897b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_transfer_map,           /* transfer_map */
290287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   r300_buffer_transfer_flush_region,  /* transfer_flush_region */
2917b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák   r300_buffer_transfer_unmap,         /* transfer_unmap */
2926a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák   r300_buffer_transfer_inline_write   /* transfer_inline_write */
293287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell};
294287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
295287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
296bb4f5fff0c782f35353e8bfc1b1227e3cc3d5986Marek Olšák					 const struct pipe_resource *templ)
29768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
29868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_screen *r300screen = r300_screen(screen);
299287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_buffer *rbuf;
300287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    unsigned alignment = 16;
30168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
30280f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák    rbuf = util_slab_alloc(&r300screen->pool_buffers);
303287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
304287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->magic = R300_BUFFER_MAGIC;
305287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
306bb4f5fff0c782f35353e8bfc1b1227e3cc3d5986Marek Olšák    rbuf->b.b = *templ;
307287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.vtbl = &r300_buffer_vtbl;
308287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    pipe_reference_init(&rbuf->b.b.reference, 1);
309287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.screen = screen;
310b6b76cbb20b3d9467011231069e23972b98afa49Marek Olšák    rbuf->domain = R300_DOMAIN_GTT;
3117b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->num_ranges = 0;
3127b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->buf = NULL;
3137b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->constant_buffer = NULL;
3147b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->user_buffer = NULL;
315b6b76cbb20b3d9467011231069e23972b98afa49Marek Olšák
3163eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    /* Alloc constant buffers in RAM. */
3173eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) {
3183eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        rbuf->constant_buffer = MALLOC(templ->width0);
3193eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák        return &rbuf->b.b;
3203eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák    }
3213eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák
322fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    rbuf->buf =
323fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        r300screen->rws->buffer_create(r300screen->rws,
324fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                       rbuf->b.b.width0, alignment,
325fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                       rbuf->b.b.bind, rbuf->b.b.usage,
326fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák                                       rbuf->domain);
3273ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák    rbuf->cs_buf =
3283ba8843307a909f35f2a04e6be6dcadd760ad82bMarek Olšák        r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf);
329287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
3307b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    if (!rbuf->buf) {
33180f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák        util_slab_free(&r300screen->pool_buffers, rbuf);
3327b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák        return NULL;
3337b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    }
334287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
335287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return &rbuf->b.b;
33668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
33768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
338287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
339287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      void *ptr,
340287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      unsigned bytes,
341287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      unsigned bind)
34268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
3437b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    struct r300_screen *r300screen = r300_screen(screen);
344287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_buffer *rbuf;
345287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
34680f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák    rbuf = util_slab_alloc(&r300screen->pool_buffers);
347287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
348287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->magic = R300_BUFFER_MAGIC;
349287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
350287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    pipe_reference_init(&rbuf->b.b.reference, 1);
351287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.vtbl = &r300_buffer_vtbl;
352287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.screen = screen;
3537b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->b.b.target = PIPE_BUFFER;
354287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
355a2a01853f3f40b4ef8b3f01503391877960bdaeeBrian Paul    rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
356287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.bind = bind;
357287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.width0 = bytes;
358287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.height0 = 1;
359287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.depth0 = 1;
3604c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    rbuf->b.b.array_size = 1;
3617b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->b.b.flags = 0;
362b6b76cbb20b3d9467011231069e23972b98afa49Marek Olšák    rbuf->domain = R300_DOMAIN_GTT;
3637b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->num_ranges = 0;
3647b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->buf = NULL;
3657b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák    rbuf->constant_buffer = NULL;
366287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->user_buffer = ptr;
367287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return &rbuf->b.b;
36868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
369