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