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 357e752760d410e72cc766691bee207729f28a920aMarek Olšákvoid r300_upload_index_buffer(struct r300_context *r300, 367e752760d410e72cc766691bee207729f28a920aMarek Olšák struct pipe_resource **index_buffer, 377e752760d410e72cc766691bee207729f28a920aMarek Olšák unsigned index_size, unsigned *start, 38bf469f4edc60bd1c5fd770cb231b8d5ab801427fMarek Olšák unsigned count, const uint8_t *ptr) 3968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 407e752760d410e72cc766691bee207729f28a920aMarek Olšák unsigned index_offset; 417e752760d410e72cc766691bee207729f28a920aMarek Olšák 427e752760d410e72cc766691bee207729f28a920aMarek Olšák *index_buffer = NULL; 437e752760d410e72cc766691bee207729f28a920aMarek Olšák 44e54cc2c070b30dd9b14bf9aedf93138b660c867fMarek Olšák u_upload_data(r300->uploader, 4506286110b4fc0ff80ae21bb3d8ff9909db1f5d47Marek Olšák 0, count * index_size, 467e752760d410e72cc766691bee207729f28a920aMarek Olšák ptr + (*start * index_size), 477e752760d410e72cc766691bee207729f28a920aMarek Olšák &index_offset, 48f94d390213308d4aca1515c75acc6865ebb45796Marek Olšák index_buffer); 497e752760d410e72cc766691bee207729f28a920aMarek Olšák 507e752760d410e72cc766691bee207729f28a920aMarek Olšák *start = index_offset / index_size; 5168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 5268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 53287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void r300_buffer_destroy(struct pipe_screen *screen, 54287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *buf) 5568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 5656ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák struct r300_resource *rbuf = r300_resource(buf); 5768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 5821b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák if (rbuf->malloced_buffer) 5921b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák FREE(rbuf->malloced_buffer); 603eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák 615862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák if (rbuf->buf) 62d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák pb_reference(&rbuf->buf, NULL); 635862b6ed6196572be0462da913d9e45b4d05f240Marek Olšák 64f808984f438b827afff6fdbe52ac52dee8781d03Marek Olšák FREE(rbuf); 657b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák} 667b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák 677b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšákstatic struct pipe_transfer* 686a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákr300_buffer_get_transfer(struct pipe_context *context, 696a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák struct pipe_resource *resource, 706a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák unsigned level, 716a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák unsigned usage, 726a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák const struct pipe_box *box) 737b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák{ 747b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák struct r300_context *r300 = r300_context(context); 757b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák struct pipe_transfer *transfer = 7680f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák util_slab_alloc(&r300->pool_transfers); 777b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák 787b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák transfer->resource = resource; 794c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger transfer->level = level; 807b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák transfer->usage = usage; 817b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák transfer->box = *box; 827b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák transfer->stride = 0; 834c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger transfer->layer_stride = 0; 847b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák transfer->data = NULL; 857b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák 867b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák /* Note strides are zero, this is ok for buffers, but not for 877b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák * textures 2d & higher at least. 887b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák */ 897b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák return transfer; 907b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák} 917b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák 926a46fce14f38adf72925842edf9829c00d1ee800Marek Olšákstatic void r300_buffer_transfer_destroy(struct pipe_context *pipe, 936a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák struct pipe_transfer *transfer) 947b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák{ 957b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák struct r300_context *r300 = r300_context(pipe); 9680f24c1575688e9cd4a5a811137f43b7e0a661bbMarek Olšák util_slab_free(&r300->pool_transfers, transfer); 9768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 9868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 9968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void * 100d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákr300_buffer_transfer_map( struct pipe_context *pipe, 101d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák struct pipe_transfer *transfer ) 10268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 103fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák struct r300_context *r300 = r300_context(pipe); 104d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák struct r300_screen *r300screen = r300_screen(pipe->screen); 105d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák struct radeon_winsys *rws = r300screen->rws; 10656ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák struct r300_resource *rbuf = r300_resource(transfer->resource); 107d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák uint8_t *map; 108ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák enum pipe_transfer_usage usage; 10968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 11021b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák if (rbuf->malloced_buffer) 11121b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák return (uint8_t *) rbuf->malloced_buffer + transfer->box.x; 11268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 113ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák /* Buffers are never used for write, therefore mapping for read can be 114ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák * unsynchronized. */ 115ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák usage = transfer->usage; 116ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák if (!(usage & PIPE_TRANSFER_WRITE)) { 117ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák usage |= PIPE_TRANSFER_UNSYNCHRONIZED; 118ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák } 119ec4851253bbf7fd7d11c5570f19f9733a885e471Marek Olšák 1200a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák map = rws->buffer_map(rbuf->cs_buf, r300->cs, usage); 121d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák 122d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák if (map == NULL) 123d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák return NULL; 124d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák 125d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák return map + transfer->box.x; 12668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 12768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 128d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákstatic void r300_buffer_transfer_unmap( struct pipe_context *pipe, 129d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák struct pipe_transfer *transfer ) 13068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 131498e71c156c9292a30081ebd92f519f882ef7fabMarek Olšák /* no-op */ 132287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell} 13368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 134d17d03a8dccb4bad25211693320459420409d997Henri Verbeetstatic const struct u_resource_vtbl r300_buffer_vtbl = 135287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 13656ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák NULL, /* get_handle */ 1377b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák r300_buffer_destroy, /* resource_destroy */ 1386a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák r300_buffer_get_transfer, /* get_transfer */ 1396a46fce14f38adf72925842edf9829c00d1ee800Marek Olšák r300_buffer_transfer_destroy, /* transfer_destroy */ 1407b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák r300_buffer_transfer_map, /* transfer_map */ 14156ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák NULL, /* transfer_flush_region */ 1427b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák r300_buffer_transfer_unmap, /* transfer_unmap */ 143a784d86508a4b609d12ca07986d43005ff2686aeMarek Olšák NULL /* transfer_inline_write */ 144287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}; 145287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 146287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_buffer_create(struct pipe_screen *screen, 147bb4f5fff0c782f35353e8bfc1b1227e3cc3d5986Marek Olšák const struct pipe_resource *templ) 14868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 14968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_screen *r300screen = r300_screen(screen); 15056ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák struct r300_resource *rbuf; 151ee678895e903f3ecbbd95b4584dbfbb127f9d4f0Marek Olšák unsigned alignment = 16; 15268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 153f808984f438b827afff6fdbe52ac52dee8781d03Marek Olšák rbuf = MALLOC_STRUCT(r300_resource); 154287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 155a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuf->b.b = *templ; 156a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuf->b.vtbl = &r300_buffer_vtbl; 157a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák pipe_reference_init(&rbuf->b.b.reference, 1); 158a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuf->b.b.screen = screen; 15993f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák rbuf->domain = RADEON_DOMAIN_GTT; 1607b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák rbuf->buf = NULL; 16121b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák rbuf->malloced_buffer = NULL; 162b6b76cbb20b3d9467011231069e23972b98afa49Marek Olšák 16321b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák /* Alloc constant buffers and SWTCL buffers in RAM. */ 16421b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák if (templ->bind & PIPE_BIND_CONSTANT_BUFFER || 16521b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák (!r300screen->caps.has_tcl && 16621b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák (templ->bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)))) { 16721b012d3b022c1c55358226f7bcc52fe50078123Marek Olšák rbuf->malloced_buffer = MALLOC(templ->width0); 168a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák return &rbuf->b.b; 1693eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák } 1703eb557778376bcbbc6f25da88ffbaa269607254cMarek Olšák 171ee678895e903f3ecbbd95b4584dbfbb127f9d4f0Marek Olšák rbuf->buf = 172ee678895e903f3ecbbd95b4584dbfbb127f9d4f0Marek Olšák r300screen->rws->buffer_create(r300screen->rws, 173a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuf->b.b.width0, alignment, 174a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuf->b.b.bind, rbuf->domain); 175ee678895e903f3ecbbd95b4584dbfbb127f9d4f0Marek Olšák if (!rbuf->buf) { 176f808984f438b827afff6fdbe52ac52dee8781d03Marek Olšák FREE(rbuf); 1777b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák return NULL; 1787b31b235d069ab4154bfc4b1eacde6368852aaeeMarek Olšák } 179287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 180ee678895e903f3ecbbd95b4584dbfbb127f9d4f0Marek Olšák rbuf->cs_buf = 181ee678895e903f3ecbbd95b4584dbfbb127f9d4f0Marek Olšák r300screen->rws->buffer_get_cs_handle(rbuf->buf); 182ee678895e903f3ecbbd95b4584dbfbb127f9d4f0Marek Olšák 183a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák return &rbuf->b.b; 18468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 185