172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse/* 272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * 472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a 572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * copy of this software and associated documentation files (the "Software"), 672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * to deal in the Software without restriction, including without limitation 772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * on the rights to use, copy, modify, merge, publish, distribute, sub 872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * license, and/or sell copies of the Software, and to permit persons to whom 972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * the Software is furnished to do so, subject to the following conditions: 1072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * 1172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * The above copyright notice and this permission notice (including the next 1272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * paragraph) shall be included in all copies or substantial portions of the 1372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Software. 1472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * 1572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 1972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * USE OR OTHER DEALINGS IN THE SOFTWARE. 2272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * 2372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Authors: 2472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Jerome Glisse 2572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Corbin Simpson <MostAwesomeDude@gmail.com> 2672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse */ 27330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák#include "r600_pipe.h" 2802f8f134643f631364ca621fe0b6d6b72449e00cMarek Olšák#include "util/u_upload_mgr.h" 2905ea705c7c6212d16fcc9bcf04619ffd4311bb03Marek Olšák#include "util/u_memory.h" 3002f8f134643f631364ca621fe0b6d6b72449e00cMarek Olšák 31126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeetstatic void r600_buffer_destroy(struct pipe_screen *screen, 32126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet struct pipe_resource *buf) 33126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet{ 349f0dc855b274cb2591fc6896149f9a9cabcbcab5Marek Olšák struct r600_resource *rbuffer = r600_resource(buf); 35126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet 366101b6d442b06a347c001fe85848d636ab7df260Marek Olšák pb_reference(&rbuffer->buf, NULL); 3705ea705c7c6212d16fcc9bcf04619ffd4311bb03Marek Olšák FREE(rbuffer); 38126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet} 39126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet 40f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšákstatic struct pipe_transfer *r600_get_transfer(struct pipe_context *ctx, 41f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák struct pipe_resource *resource, 42f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák unsigned level, 43f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák unsigned usage, 44f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák const struct pipe_box *box) 45f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák{ 46e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context*)ctx; 4799c65bac341f808279a8a847158ace4f058aa72eMarek Olšák struct r600_transfer *transfer = util_slab_alloc(&rctx->pool_transfers); 48f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák 4999c65bac341f808279a8a847158ace4f058aa72eMarek Olšák assert(box->x + box->width <= resource->width0); 5099c65bac341f808279a8a847158ace4f058aa72eMarek Olšák 5199c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->transfer.resource = resource; 5299c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->transfer.level = level; 5399c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->transfer.usage = usage; 5499c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->transfer.box = *box; 5599c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->transfer.stride = 0; 5699c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->transfer.layer_stride = 0; 5799c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->transfer.data = NULL; 5899c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->staging = NULL; 5999c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->offset = 0; 60f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák 61f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák /* Note strides are zero, this is ok for buffers, but not for 62f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák * textures 2d & higher at least. 63f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák */ 6499c65bac341f808279a8a847158ace4f058aa72eMarek Olšák return &transfer->transfer; 65f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák} 66f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák 6782a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšákstatic void r600_set_constants_dirty_if_bound(struct r600_context *rctx, 6882a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák struct r600_constbuf_state *state, 6982a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák struct r600_resource *rbuffer) 7082a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák{ 7182a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák bool found = false; 7282a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák uint32_t mask = state->enabled_mask; 7382a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák 7482a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák while (mask) { 7582a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák unsigned i = u_bit_scan(&mask); 76a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák if (state->cb[i].buffer == &rbuffer->b.b) { 7782a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák found = true; 7882a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák state->dirty_mask |= 1 << i; 7982a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 8082a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 8182a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák if (found) { 8282a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák r600_constant_buffers_dirty(rctx, state); 8382a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 8482a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák} 8582a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák 86126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeetstatic void *r600_buffer_transfer_map(struct pipe_context *pipe, 87126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet struct pipe_transfer *transfer) 88126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet{ 899f0dc855b274cb2591fc6896149f9a9cabcbcab5Marek Olšák struct r600_resource *rbuffer = r600_resource(transfer->resource); 90e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context*)pipe; 91126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet uint8_t *data; 92126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet 93d3bab0c7bee7439fa834fd86a835119fc5fa3307Marek Olšák if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE && 94d3bab0c7bee7439fa834fd86a835119fc5fa3307Marek Olšák !(transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { 95d3bab0c7bee7439fa834fd86a835119fc5fa3307Marek Olšák assert(transfer->usage & PIPE_TRANSFER_WRITE); 9682a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák 9782a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* Check if mapping this buffer would cause waiting for the GPU. */ 98d3bab0c7bee7439fa834fd86a835119fc5fa3307Marek Olšák if (rctx->ws->cs_is_buffer_referenced(rctx->cs, rbuffer->cs_buf, RADEON_USAGE_READWRITE) || 99d3bab0c7bee7439fa834fd86a835119fc5fa3307Marek Olšák rctx->ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) { 100585baac652ffa172fb3fbbdd4c7559d03b7c27efMarek Olšák unsigned i, mask; 10182a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák 10282a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* Discard the buffer. */ 10382a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák pb_reference(&rbuffer->buf, NULL); 10482a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák 10582a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* Create a new one in the same pipe_resource. */ 10682a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* XXX We probably want a different alignment for buffers and textures. */ 107a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák r600_init_resource(rctx->screen, rbuffer, rbuffer->b.b.width0, 4096, 108a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuffer->b.b.bind, rbuffer->b.b.usage); 10982a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák 11082a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* We changed the buffer, now we need to bind it where the old one was bound. */ 11182a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* Vertex buffers. */ 112585baac652ffa172fb3fbbdd4c7559d03b7c27efMarek Olšák mask = rctx->vertex_buffer_state.enabled_mask; 113585baac652ffa172fb3fbbdd4c7559d03b7c27efMarek Olšák while (mask) { 114585baac652ffa172fb3fbbdd4c7559d03b7c27efMarek Olšák i = u_bit_scan(&mask); 115585baac652ffa172fb3fbbdd4c7559d03b7c27efMarek Olšák if (rctx->vertex_buffer_state.vb[i].buffer == &rbuffer->b.b) { 116585baac652ffa172fb3fbbdd4c7559d03b7c27efMarek Olšák rctx->vertex_buffer_state.dirty_mask |= 1 << i; 117585baac652ffa172fb3fbbdd4c7559d03b7c27efMarek Olšák r600_vertex_buffers_dirty(rctx); 11882a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 11982a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 12082a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* Streamout buffers. */ 12182a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák for (i = 0; i < rctx->num_so_targets; i++) { 122a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák if (rctx->so_targets[i]->b.buffer == &rbuffer->b.b) { 12382a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák r600_context_streamout_end(rctx); 12482a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák rctx->streamout_start = TRUE; 12582a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák rctx->streamout_append_bitmask = ~0; 12682a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 12782a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 12882a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák /* Constant buffers. */ 12982a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák r600_set_constants_dirty_if_bound(rctx, &rctx->vs_constbuf_state, rbuffer); 13082a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák r600_set_constants_dirty_if_bound(rctx, &rctx->ps_constbuf_state, rbuffer); 13182a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 13282a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák } 133b3b5bb9ddb05989b2dc5fc17f88491bbd0e6ecacMarek Olšák#if 0 /* this is broken (see Bug 53130) */ 13499c65bac341f808279a8a847158ace4f058aa72eMarek Olšák else if ((transfer->usage & PIPE_TRANSFER_DISCARD_RANGE) && 13599c65bac341f808279a8a847158ace4f058aa72eMarek Olšák !(transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) && 13699c65bac341f808279a8a847158ace4f058aa72eMarek Olšák rctx->screen->has_streamout && 13799c65bac341f808279a8a847158ace4f058aa72eMarek Olšák /* The buffer range must be aligned to 4. */ 13899c65bac341f808279a8a847158ace4f058aa72eMarek Olšák transfer->box.x % 4 == 0 && transfer->box.width % 4 == 0) { 13999c65bac341f808279a8a847158ace4f058aa72eMarek Olšák assert(transfer->usage & PIPE_TRANSFER_WRITE); 14099c65bac341f808279a8a847158ace4f058aa72eMarek Olšák 14199c65bac341f808279a8a847158ace4f058aa72eMarek Olšák /* Check if mapping this buffer would cause waiting for the GPU. */ 14299c65bac341f808279a8a847158ace4f058aa72eMarek Olšák if (rctx->ws->cs_is_buffer_referenced(rctx->cs, rbuffer->cs_buf, RADEON_USAGE_READWRITE) || 14399c65bac341f808279a8a847158ace4f058aa72eMarek Olšák rctx->ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) { 14499c65bac341f808279a8a847158ace4f058aa72eMarek Olšák /* Do a wait-free write-only transfer using a temporary buffer. */ 14599c65bac341f808279a8a847158ace4f058aa72eMarek Olšák struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; 14699c65bac341f808279a8a847158ace4f058aa72eMarek Olšák 14799c65bac341f808279a8a847158ace4f058aa72eMarek Olšák rtransfer->staging = (struct r600_resource*) 14899c65bac341f808279a8a847158ace4f058aa72eMarek Olšák pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, 14999c65bac341f808279a8a847158ace4f058aa72eMarek Olšák PIPE_USAGE_STAGING, transfer->box.width); 15099c65bac341f808279a8a847158ace4f058aa72eMarek Olšák return rctx->ws->buffer_map(rtransfer->staging->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); 15199c65bac341f808279a8a847158ace4f058aa72eMarek Olšák } 15299c65bac341f808279a8a847158ace4f058aa72eMarek Olšák } 153b3b5bb9ddb05989b2dc5fc17f88491bbd0e6ecacMarek Olšák#endif 15482a7fe6f5c93e6787f99124974af0dbcafef5fb1Marek Olšák 1550a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák data = rctx->ws->buffer_map(rbuffer->cs_buf, rctx->cs, transfer->usage); 156126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet if (!data) 157126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet return NULL; 158126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet 159126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet return (uint8_t*)data + transfer->box.x; 160126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet} 161126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet 162126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeetstatic void r600_buffer_transfer_unmap(struct pipe_context *pipe, 163126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet struct pipe_transfer *transfer) 164126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet{ 16599c65bac341f808279a8a847158ace4f058aa72eMarek Olšák struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; 16699c65bac341f808279a8a847158ace4f058aa72eMarek Olšák 16799c65bac341f808279a8a847158ace4f058aa72eMarek Olšák if (rtransfer->staging) { 16899c65bac341f808279a8a847158ace4f058aa72eMarek Olšák struct pipe_box box; 16999c65bac341f808279a8a847158ace4f058aa72eMarek Olšák u_box_1d(0, transfer->box.width, &box); 17099c65bac341f808279a8a847158ace4f058aa72eMarek Olšák 17199c65bac341f808279a8a847158ace4f058aa72eMarek Olšák /* Copy the staging buffer into the original one. */ 17299c65bac341f808279a8a847158ace4f058aa72eMarek Olšák r600_copy_buffer(pipe, transfer->resource, transfer->box.x, 17399c65bac341f808279a8a847158ace4f058aa72eMarek Olšák &rtransfer->staging->b.b, &box); 17499c65bac341f808279a8a847158ace4f058aa72eMarek Olšák pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL); 17599c65bac341f808279a8a847158ace4f058aa72eMarek Olšák } 176126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet} 177126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet 178f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšákstatic void r600_transfer_destroy(struct pipe_context *ctx, 179f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák struct pipe_transfer *transfer) 180f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák{ 181e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct r600_context *rctx = (struct r600_context*)ctx; 182f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák util_slab_free(&rctx->pool_transfers, transfer); 183f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák} 184f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák 185126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeetstatic const struct u_resource_vtbl r600_buffer_vtbl = 186126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet{ 187126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet u_default_resource_get_handle, /* get_handle */ 188126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet r600_buffer_destroy, /* resource_destroy */ 189f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák r600_get_transfer, /* get_transfer */ 190f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák r600_transfer_destroy, /* transfer_destroy */ 191126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet r600_buffer_transfer_map, /* transfer_map */ 192bf4fedcef3e345f5117232d58bd9000c2441de74Marek Olšák NULL, /* transfer_flush_region */ 193126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet r600_buffer_transfer_unmap, /* transfer_unmap */ 194ab1328882101f67335a332e940fea92eeaf70e12Marek Olšák NULL /* transfer_inline_write */ 195126e98966d5396ed251a34e3c39f11b36351a579Henri Verbeet}; 196b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšák 1976101b6d442b06a347c001fe85848d636ab7df260Marek Olšákbool r600_init_resource(struct r600_screen *rscreen, 1986101b6d442b06a347c001fe85848d636ab7df260Marek Olšák struct r600_resource *res, 1996101b6d442b06a347c001fe85848d636ab7df260Marek Olšák unsigned size, unsigned alignment, 2006101b6d442b06a347c001fe85848d636ab7df260Marek Olšák unsigned bind, unsigned usage) 2016101b6d442b06a347c001fe85848d636ab7df260Marek Olšák{ 20293f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák uint32_t initial_domain, domains; 20393f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák 20493f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák /* Staging resources particpate in transfers and blits only 20593f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák * and are used for uploads and downloads from regular 20693f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák * resources. We generate them internally for some transfers. 20793f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák */ 20893f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák if (usage == PIPE_USAGE_STAGING) { 20993f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák domains = RADEON_DOMAIN_GTT; 21093f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák initial_domain = RADEON_DOMAIN_GTT; 21193f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák } else { 21293f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM; 21393f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák 21493f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák switch(usage) { 21593f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák case PIPE_USAGE_DYNAMIC: 21693f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák case PIPE_USAGE_STREAM: 21793f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák case PIPE_USAGE_STAGING: 21893f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák initial_domain = RADEON_DOMAIN_GTT; 21993f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák break; 22093f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák case PIPE_USAGE_DEFAULT: 22193f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák case PIPE_USAGE_STATIC: 22293f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák case PIPE_USAGE_IMMUTABLE: 22393f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák default: 22493f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák initial_domain = RADEON_DOMAIN_VRAM; 22593f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák break; 22693f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák } 22793f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák } 22893f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák 22993f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment, bind, initial_domain); 2306101b6d442b06a347c001fe85848d636ab7df260Marek Olšák if (!res->buf) { 2316101b6d442b06a347c001fe85848d636ab7df260Marek Olšák return false; 2326101b6d442b06a347c001fe85848d636ab7df260Marek Olšák } 2336101b6d442b06a347c001fe85848d636ab7df260Marek Olšák 2346101b6d442b06a347c001fe85848d636ab7df260Marek Olšák res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf); 23593f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák res->domains = domains; 2366101b6d442b06a347c001fe85848d636ab7df260Marek Olšák return true; 2376101b6d442b06a347c001fe85848d636ab7df260Marek Olšák} 2386101b6d442b06a347c001fe85848d636ab7df260Marek Olšák 239b8fb1d75ce95fe5d404b301ab31ca0c323967d14Marek Olšákstruct pipe_resource *r600_buffer_create(struct pipe_screen *screen, 24078354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák const struct pipe_resource *templ, 24178354011f99c4103345f8f32e10b0b4b884ebdafMarek Olšák unsigned alignment) 24272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse{ 243f0b202ec73855bd9e1b29909c8ac90393043cb8bMarek Olšák struct r600_screen *rscreen = (struct r600_screen*)screen; 2449f0dc855b274cb2591fc6896149f9a9cabcbcab5Marek Olšák struct r600_resource *rbuffer; 24572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse 24605ea705c7c6212d16fcc9bcf04619ffd4311bb03Marek Olšák rbuffer = MALLOC_STRUCT(r600_resource); 24772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse 248a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuffer->b.b = *templ; 249a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák pipe_reference_init(&rbuffer->b.b.reference, 1); 250a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuffer->b.b.screen = screen; 251a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák rbuffer->b.vtbl = &r600_buffer_vtbl; 252aa8a2224a3df111a1613f0baefebc00883e1b70bMarek Olšák 2536101b6d442b06a347c001fe85848d636ab7df260Marek Olšák if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, templ->bind, templ->usage)) { 25405ea705c7c6212d16fcc9bcf04619ffd4311bb03Marek Olšák FREE(rbuffer); 25572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse return NULL; 25672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse } 257a52b3338c6e51421e3836ae210cd98d9c1ec337bMarek Olšák return &rbuffer->b.b; 25872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse} 259