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