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