r300_screen_buffer.c revision 06286110b4fc0ff80ae21bb3d8ff9909db1f5d47
1253066d716e3039522eeb7b072811cccd89b4a82José Fonseca/* 2253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * Copyright 2010 Red Hat Inc. 3253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * 4253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 5253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * copy of this software and associated documentation files (the "Software"), 6253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * to deal in the Software without restriction, including without limitation 7253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * on the rights to use, copy, modify, merge, publish, distribute, sub 8253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * license, and/or sell copies of the Software, and to permit persons to whom 9253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * the Software is furnished to do so, subject to the following conditions: 10253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * 11253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * The above copyright notice and this permission notice (including the next 12253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * paragraph) shall be included in all copies or substantial portions of the 13253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * Software. 14253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * 15253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * USE OR OTHER DEALINGS IN THE SOFTWARE. 22253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * 23253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * Authors: Dave Airlie 24253066d716e3039522eeb7b072811cccd89b4a82José Fonseca */ 25253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 26253066d716e3039522eeb7b072811cccd89b4a82José Fonseca#include <stdio.h> 27253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 28253066d716e3039522eeb7b072811cccd89b4a82José Fonseca#include "util/u_inlines.h" 29253066d716e3039522eeb7b072811cccd89b4a82José Fonseca#include "util/u_memory.h" 30253066d716e3039522eeb7b072811cccd89b4a82José Fonseca#include "util/u_upload_mgr.h" 31253066d716e3039522eeb7b072811cccd89b4a82José Fonseca#include "util/u_math.h" 32253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 33253066d716e3039522eeb7b072811cccd89b4a82José Fonseca#include "r300_screen_buffer.h" 34253066d716e3039522eeb7b072811cccd89b4a82José Fonseca#include "r300_winsys.h" 35253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 36253066d716e3039522eeb7b072811cccd89b4a82José Fonsecaunsigned r300_buffer_is_referenced(struct pipe_context *context, 37253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_resource *buf, 38c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca enum r300_reference_domain domain) 39253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 40253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_context *r300 = r300_context(context); 41d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz struct r300_buffer *rbuf = r300_buffer(buf); 42d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz 43d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz if (r300_buffer_is_user_buffer(buf)) 44d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz return PIPE_UNREFERENCED; 45d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz 46253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain)) 47253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; 48253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 49253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return PIPE_UNREFERENCED; 50253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 51253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 52253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic unsigned r300_buffer_is_referenced_by_cs(struct pipe_context *context, 53253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_resource *buf, 54253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned level, int layer) 55253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 56253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return r300_buffer_is_referenced(context, buf, R300_REF_CS); 57253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 58253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 59253066d716e3039522eeb7b072811cccd89b4a82José Fonsecavoid r300_upload_index_buffer(struct r300_context *r300, 60253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_resource **index_buffer, 61253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned index_size, unsigned *start, 62253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned count) 63253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 64253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned index_offset; 65253066d716e3039522eeb7b072811cccd89b4a82José Fonseca boolean flushed; 66253066d716e3039522eeb7b072811cccd89b4a82José Fonseca uint8_t *ptr = r300_buffer(*index_buffer)->user_buffer; 67253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 68253066d716e3039522eeb7b072811cccd89b4a82José Fonseca *index_buffer = NULL; 69253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 70253066d716e3039522eeb7b072811cccd89b4a82José Fonseca u_upload_data(r300->upload_ib, 71253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 0, count * index_size, 72253066d716e3039522eeb7b072811cccd89b4a82José Fonseca ptr + (*start * index_size), 73253066d716e3039522eeb7b072811cccd89b4a82José Fonseca &index_offset, 74253066d716e3039522eeb7b072811cccd89b4a82José Fonseca index_buffer, &flushed); 75253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 76253066d716e3039522eeb7b072811cccd89b4a82José Fonseca *start = index_offset / index_size; 77253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 78253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 79253066d716e3039522eeb7b072811cccd89b4a82José Fonsecavoid r300_upload_user_buffers(struct r300_context *r300) 80253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 81253066d716e3039522eeb7b072811cccd89b4a82José Fonseca int i, nr = r300->velems->count; 82253066d716e3039522eeb7b072811cccd89b4a82José Fonseca boolean flushed; 83253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 84253066d716e3039522eeb7b072811cccd89b4a82José Fonseca for (i = 0; i < nr; i++) { 85253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_vertex_buffer *vb = 86253066d716e3039522eeb7b072811cccd89b4a82José Fonseca &r300->vertex_buffer[r300->velems->velem[i].vertex_buffer_index]; 87253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 88253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (r300_buffer_is_user_buffer(vb->buffer)) { 89253066d716e3039522eeb7b072811cccd89b4a82José Fonseca u_upload_data(r300->upload_vb, 90253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 0, vb->buffer->width0, 91253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer(vb->buffer)->user_buffer, 92253066d716e3039522eeb7b072811cccd89b4a82José Fonseca &vb->buffer_offset, &vb->buffer, &flushed); 93253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 94253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300->validate_buffers = TRUE; 95253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300->vertex_arrays_dirty = TRUE; 96253066d716e3039522eeb7b072811cccd89b4a82José Fonseca } 97253066d716e3039522eeb7b072811cccd89b4a82José Fonseca } 98253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 99253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 100253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic void r300_buffer_destroy(struct pipe_screen *screen, 101253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_resource *buf) 102253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 103253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_screen *r300screen = r300_screen(screen); 104253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_buffer *rbuf = r300_buffer(buf); 105253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_winsys_screen *rws = r300screen->rws; 106253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 107253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (rbuf->constant_buffer) 108253066d716e3039522eeb7b072811cccd89b4a82José Fonseca FREE(rbuf->constant_buffer); 109253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 110253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (rbuf->buf) 111253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rws->buffer_reference(rws, &rbuf->buf, NULL); 112253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 113253066d716e3039522eeb7b072811cccd89b4a82José Fonseca util_slab_free(&r300screen->pool_buffers, rbuf); 114253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 115253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 116253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic struct pipe_transfer* 117253066d716e3039522eeb7b072811cccd89b4a82José Fonsecar300_buffer_get_transfer(struct pipe_context *context, 118253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_resource *resource, 119253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned level, 120253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned usage, 121253066d716e3039522eeb7b072811cccd89b4a82José Fonseca const struct pipe_box *box) 122253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 123253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_context *r300 = r300_context(context); 124253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_transfer *transfer = 125253066d716e3039522eeb7b072811cccd89b4a82José Fonseca util_slab_alloc(&r300->pool_transfers); 126253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 127253066d716e3039522eeb7b072811cccd89b4a82José Fonseca transfer->resource = resource; 128253066d716e3039522eeb7b072811cccd89b4a82José Fonseca transfer->level = level; 129253066d716e3039522eeb7b072811cccd89b4a82José Fonseca transfer->usage = usage; 130253066d716e3039522eeb7b072811cccd89b4a82José Fonseca transfer->box = *box; 131253066d716e3039522eeb7b072811cccd89b4a82José Fonseca transfer->stride = 0; 132253066d716e3039522eeb7b072811cccd89b4a82José Fonseca transfer->layer_stride = 0; 133253066d716e3039522eeb7b072811cccd89b4a82José Fonseca transfer->data = NULL; 134253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 135253066d716e3039522eeb7b072811cccd89b4a82José Fonseca /* Note strides are zero, this is ok for buffers, but not for 136253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * textures 2d & higher at least. 137253066d716e3039522eeb7b072811cccd89b4a82José Fonseca */ 138253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return transfer; 139253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 140253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 141253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic void r300_buffer_transfer_destroy(struct pipe_context *pipe, 142253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_transfer *transfer) 143253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 144253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_context *r300 = r300_context(pipe); 145253066d716e3039522eeb7b072811cccd89b4a82José Fonseca util_slab_free(&r300->pool_transfers, transfer); 146253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 147253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 148253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic void * 149253066d716e3039522eeb7b072811cccd89b4a82José Fonsecar300_buffer_transfer_map( struct pipe_context *pipe, 150253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_transfer *transfer ) 1518e2df0dcb92b7b092b35df3d35591c31d5f2ca5fRoland Scheidegger{ 152253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_context *r300 = r300_context(pipe); 153253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_screen *r300screen = r300_screen(pipe->screen); 154253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_winsys_screen *rws = r300screen->rws; 155253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_buffer *rbuf = r300_buffer(transfer->resource); 156253066d716e3039522eeb7b072811cccd89b4a82José Fonseca uint8_t *map; 157253066d716e3039522eeb7b072811cccd89b4a82José Fonseca boolean flush = FALSE; 158253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned i; 159253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 160253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (rbuf->user_buffer) 161253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return (uint8_t *) rbuf->user_buffer + transfer->box.x; 162253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (rbuf->constant_buffer) 163253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return (uint8_t *) rbuf->constant_buffer + transfer->box.x; 164253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 165253066d716e3039522eeb7b072811cccd89b4a82José Fonseca /* check if the mapping is to a range we already flushed */ 166253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (transfer->usage & PIPE_TRANSFER_DISCARD) { 167253066d716e3039522eeb7b072811cccd89b4a82José Fonseca for (i = 0; i < rbuf->num_ranges; i++) { 168253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if ((transfer->box.x >= rbuf->ranges[i].start) && 169253066d716e3039522eeb7b072811cccd89b4a82José Fonseca (transfer->box.x < rbuf->ranges[i].end)) 1705ad488908b39b8f2278a00c9d2cbce76dd925ad1Vinson Lee flush = TRUE; 171253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 172253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (flush) { 173253066d716e3039522eeb7b072811cccd89b4a82José Fonseca /* unreference this hw buffer and allocate a new one */ 174253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rws->buffer_reference(rws, &rbuf->buf, NULL); 175253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 176253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->num_ranges = 0; 177253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->buf = 178253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300screen->rws->buffer_create(r300screen->rws, 179253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.width0, 16, 180253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.bind, 181253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.usage, 182253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->domain); 183253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->cs_buf = 184253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300screen->rws->buffer_get_cs_handle(r300screen->rws, 185253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->buf); 186d9d1e39d95fef4a8da15147956ff0c3e0a188b5bJakob Bornecrantz break; 187d9d1e39d95fef4a8da15147956ff0c3e0a188b5bJakob Bornecrantz } 188253066d716e3039522eeb7b072811cccd89b4a82José Fonseca } 189253066d716e3039522eeb7b072811cccd89b4a82José Fonseca } 1908e2df0dcb92b7b092b35df3d35591c31d5f2ca5fRoland Scheidegger 1918e2df0dcb92b7b092b35df3d35591c31d5f2ca5fRoland Scheidegger map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage); 192e8983f70b41ea92a9527cb618db011b5dd136626Roland Scheidegger 1938e2df0dcb92b7b092b35df3d35591c31d5f2ca5fRoland Scheidegger if (map == NULL) 1948e2df0dcb92b7b092b35df3d35591c31d5f2ca5fRoland Scheidegger return NULL; 195253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 196253066d716e3039522eeb7b072811cccd89b4a82José Fonseca /* map_buffer() returned a pointer to the beginning of the buffer, 197253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * but transfers are expected to return a pointer to just the 198253066d716e3039522eeb7b072811cccd89b4a82José Fonseca * region specified in the box. 199253066d716e3039522eeb7b072811cccd89b4a82José Fonseca */ 2004ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca return map + transfer->box.x; 2014ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca} 2024ddd65967915ca4846f2831bc676c878a29dae4aJosé Fonseca 203253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic void r300_buffer_transfer_flush_region( struct pipe_context *pipe, 204d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz struct pipe_transfer *transfer, 205d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz const struct pipe_box *box) 206f52ab4cc22bfb6708724f3c3966ce734d605cdddJakob Bornecrantz{ 207253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_buffer *rbuf = r300_buffer(transfer->resource); 208253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned i; 209253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned offset = transfer->box.x + box->x; 210253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned length = box->width; 211253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 212253066d716e3039522eeb7b072811cccd89b4a82José Fonseca assert(box->x + box->width <= transfer->box.width); 213253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 214253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (rbuf->user_buffer) 215253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return; 216253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (rbuf->constant_buffer) 217253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return; 218253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 219d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz /* mark the range as used */ 220253066d716e3039522eeb7b072811cccd89b4a82José Fonseca for(i = 0; i < rbuf->num_ranges; ++i) { 221253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if(offset <= rbuf->ranges[i].end && rbuf->ranges[i].start <= (offset+box->width)) { 222253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->ranges[i].start = MIN2(rbuf->ranges[i].start, offset); 223253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->ranges[i].end = MAX2(rbuf->ranges[i].end, (offset+length)); 224e1741dbe45ef1f43432457fab088275ecf953d17Jakob Bornecrantz return; 225e1741dbe45ef1f43432457fab088275ecf953d17Jakob Bornecrantz } 226d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz } 227d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz 228253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->ranges[rbuf->num_ranges].start = offset; 229253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->ranges[rbuf->num_ranges].end = offset+length; 230253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->num_ranges++; 231253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 232253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 233253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic void r300_buffer_transfer_unmap( struct pipe_context *pipe, 234253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_transfer *transfer ) 235253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 236253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_screen *r300screen = r300_screen(pipe->screen); 237253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_winsys_screen *rws = r300screen->rws; 238253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_buffer *rbuf = r300_buffer(transfer->resource); 239253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 240388109c04dc92ed81d1dbe6209120c95bdbc83cdRoland Scheidegger if (rbuf->buf) { 241253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rws->buffer_unmap(rws, rbuf->buf); 2421278507e3bf2e83c7027820a0d313de267a440ffRoland Scheidegger } 2431278507e3bf2e83c7027820a0d313de267a440ffRoland Scheidegger} 244253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 245253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastatic void r300_buffer_transfer_inline_write(struct pipe_context *pipe, 246253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct pipe_resource *resource, 247253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned level, 248253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned usage, 249253066d716e3039522eeb7b072811cccd89b4a82José Fonseca const struct pipe_box *box, 250253066d716e3039522eeb7b072811cccd89b4a82José Fonseca const void *data, 251253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned stride, 252253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned layer_stride) 253253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 254253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_context *r300 = r300_context(pipe); 255253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_winsys_screen *rws = r300->screen->rws; 256253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_buffer *rbuf = r300_buffer(resource); 257d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz uint8_t *map = NULL; 258253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 259253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (rbuf->constant_buffer) { 260d2110064c2075a8537d4b7f87ba894ebaa6ccb33Jakob Bornecrantz memcpy(rbuf->constant_buffer + box->x, data, box->width); 261cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz return; 262cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4Jakob Bornecrantz } 263253066d716e3039522eeb7b072811cccd89b4a82José Fonseca assert(rbuf->user_buffer == NULL); 264253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 265253066d716e3039522eeb7b072811cccd89b4a82José Fonseca map = rws->buffer_map(rws, rbuf->buf, r300->cs, 266253066d716e3039522eeb7b072811cccd89b4a82José Fonseca PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage); 267253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 268253066d716e3039522eeb7b072811cccd89b4a82José Fonseca memcpy(map + box->x, data, box->width); 269253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 270253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rws->buffer_unmap(rws, rbuf->buf); 271253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 272253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 273253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastruct u_resource_vtbl r300_buffer_vtbl = 274253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 275253066d716e3039522eeb7b072811cccd89b4a82José Fonseca u_default_resource_get_handle, /* get_handle */ 276253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_destroy, /* resource_destroy */ 277253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_is_referenced_by_cs, /* is_buffer_referenced */ 278253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_get_transfer, /* get_transfer */ 279253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_transfer_destroy, /* transfer_destroy */ 280253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_transfer_map, /* transfer_map */ 281253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_transfer_flush_region, /* transfer_flush_region */ 282253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_transfer_unmap, /* transfer_unmap */ 283253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300_buffer_transfer_inline_write /* transfer_inline_write */ 284253066d716e3039522eeb7b072811cccd89b4a82José Fonseca}; 285253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 286253066d716e3039522eeb7b072811cccd89b4a82José Fonsecastruct pipe_resource *r300_buffer_create(struct pipe_screen *screen, 287253066d716e3039522eeb7b072811cccd89b4a82José Fonseca const struct pipe_resource *templ) 288253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 289253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_screen *r300screen = r300_screen(screen); 290253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_buffer *rbuf; 291253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned alignment = 16; 292253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 293253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf = util_slab_alloc(&r300screen->pool_buffers); 294253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 295253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->magic = R300_BUFFER_MAGIC; 296253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 297253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b = *templ; 298253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.vtbl = &r300_buffer_vtbl; 299253066d716e3039522eeb7b072811cccd89b4a82José Fonseca pipe_reference_init(&rbuf->b.b.reference, 1); 300253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.screen = screen; 301253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->domain = R300_DOMAIN_GTT; 302253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->num_ranges = 0; 303253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->buf = NULL; 304253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->constant_buffer = NULL; 305253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->user_buffer = NULL; 306253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 307253066d716e3039522eeb7b072811cccd89b4a82José Fonseca /* Alloc constant buffers in RAM. */ 308253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) { 309253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->constant_buffer = MALLOC(templ->width0); 310253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return &rbuf->b.b; 311253066d716e3039522eeb7b072811cccd89b4a82José Fonseca } 312253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 313253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->buf = 314253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300screen->rws->buffer_create(r300screen->rws, 315253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.width0, alignment, 316253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.bind, rbuf->b.b.usage, 317253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->domain); 318253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->cs_buf = 319253066d716e3039522eeb7b072811cccd89b4a82José Fonseca r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf); 320253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 321253066d716e3039522eeb7b072811cccd89b4a82José Fonseca if (!rbuf->buf) { 322253066d716e3039522eeb7b072811cccd89b4a82José Fonseca util_slab_free(&r300screen->pool_buffers, rbuf); 323253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return NULL; 324253066d716e3039522eeb7b072811cccd89b4a82José Fonseca } 325253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 326253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return &rbuf->b.b; 327253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 328eb168e26aa63f11a47d70c4555cae30691a2cd57Michel Dänzer 329eb168e26aa63f11a47d70c4555cae30691a2cd57Michel Dänzerstruct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, 330253066d716e3039522eeb7b072811cccd89b4a82José Fonseca void *ptr, 331253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned bytes, 332253066d716e3039522eeb7b072811cccd89b4a82José Fonseca unsigned bind) 333253066d716e3039522eeb7b072811cccd89b4a82José Fonseca{ 334253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_screen *r300screen = r300_screen(screen); 335253066d716e3039522eeb7b072811cccd89b4a82José Fonseca struct r300_buffer *rbuf; 336253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 337253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf = util_slab_alloc(&r300screen->pool_buffers); 338253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 339253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->magic = R300_BUFFER_MAGIC; 340253066d716e3039522eeb7b072811cccd89b4a82José Fonseca 341253066d716e3039522eeb7b072811cccd89b4a82José Fonseca pipe_reference_init(&rbuf->b.b.reference, 1); 3427f41f5447c8f9113c8956901e1c5fff6081ecd94Keith Whitwell rbuf->b.vtbl = &r300_buffer_vtbl; 3437f41f5447c8f9113c8956901e1c5fff6081ecd94Keith Whitwell rbuf->b.b.screen = screen; 3447f41f5447c8f9113c8956901e1c5fff6081ecd94Keith Whitwell rbuf->b.b.target = PIPE_BUFFER; 3457f41f5447c8f9113c8956901e1c5fff6081ecd94Keith Whitwell rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; 3467f41f5447c8f9113c8956901e1c5fff6081ecd94Keith Whitwell rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE; 347253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.bind = bind; 348253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.width0 = bytes; 349253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.height0 = 1; 350253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.depth0 = 1; 351253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.array_size = 1; 352253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->b.b.flags = 0; 353253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->domain = R300_DOMAIN_GTT; 354253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->num_ranges = 0; 355253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->buf = NULL; 356253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->constant_buffer = NULL; 357253066d716e3039522eeb7b072811cccd89b4a82José Fonseca rbuf->user_buffer = ptr; 358253066d716e3039522eeb7b072811cccd89b4a82José Fonseca return &rbuf->b.b; 359253066d716e3039522eeb7b072811cccd89b4a82José Fonseca} 360253066d716e3039522eeb7b072811cccd89b4a82José Fonseca