r300_screen_buffer.c revision 287c94ea4987033f9c99a2f91c5750c9083504ca
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 */ 2568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include <stdio.h> 2668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 2768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_inlines.h" 2868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_format.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 3568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "r300_winsys.h" 3668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 37287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic unsigned r300_buffer_is_referenced(struct pipe_context *context, 38287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *buf, 39287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell unsigned face, unsigned level) 4068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 41287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct r300_context *r300 = r300_context(context); 4268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_buffer *rbuf = r300_buffer(buf); 43287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 4468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (r300_buffer_is_user_buffer(buf)) 45287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return PIPE_UNREFERENCED; 46287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 47287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (r300->rws->is_buffer_referenced(r300->rws, rbuf->buf)) 48287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; 4968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 50287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return PIPE_UNREFERENCED; 5168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 52287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 53287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/* External helper, not required to implent u_resource_vtbl: 54287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */ 5568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlieint r300_upload_index_buffer(struct r300_context *r300, 56287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource **index_buffer, 5768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned index_size, 5868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned start, 5968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned count) 6068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 61287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *upload_buffer = NULL; 6268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned index_offset = start * index_size; 6368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie int ret = 0; 6468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 6568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (r300_buffer_is_user_buffer(*index_buffer)) { 6668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie ret = u_upload_buffer(r300->upload_ib, 6768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie index_offset, 6868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie count * index_size, 6968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *index_buffer, 7068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie &index_offset, 7168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie &upload_buffer); 7268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (ret) { 7368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie goto done; 7468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 7568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *index_buffer = upload_buffer; 7668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 7768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie done: 7868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie // if (upload_buffer) 79287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell // pipe_resource_reference(&upload_buffer, NULL); 8068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return ret; 8168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 8268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 83287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/* External helper, not required to implent u_resource_vtbl: 84287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */ 8568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlieint r300_upload_user_buffers(struct r300_context *r300) 8668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 8768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie enum pipe_error ret = PIPE_OK; 8868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie int i, nr; 8968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 9068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie nr = r300->vertex_buffer_count; 9168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 9268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie for (i = 0; i < nr; i++) { 9368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 9468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) { 95287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *upload_buffer = NULL; 9668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned offset = 0; /*r300->vertex_buffer[i].buffer_offset * 4;*/ 97287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell unsigned size = r300->vertex_buffer[i].buffer->width0; 9868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned upload_offset; 9968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie ret = u_upload_buffer(r300->upload_vb, 10068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie offset, size, 10168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie r300->vertex_buffer[i].buffer, 10268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie &upload_offset, &upload_buffer); 10368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (ret) 10468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return ret; 10568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 106287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL); 10768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie r300->vertex_buffer[i].buffer = upload_buffer; 10868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie r300->vertex_buffer[i].buffer_offset = upload_offset; 10968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 11068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 11168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return ret; 11268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 11368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 11468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic struct r300_winsys_buffer * 11568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlier300_winsys_buffer_create(struct r300_screen *r300screen, 11668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned alignment, 11768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned usage, 11868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned size) 11968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 12068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_winsys_screen *rws = r300screen->rws; 12168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_winsys_buffer *buf; 12268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 12368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie buf = rws->buffer_create(rws, alignment, usage, size); 12468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return buf; 12568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 12668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 12768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void r300_winsys_buffer_destroy(struct r300_screen *r300screen, 12868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_buffer *rbuf) 12968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 13068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_winsys_screen *rws = r300screen->rws; 13168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 13268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (rbuf->buf) { 13368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rws->buffer_reference(rws, &rbuf->buf, NULL); 13468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->buf = NULL; 13568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 13668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 13768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 13868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 139287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void r300_buffer_destroy(struct pipe_screen *screen, 140287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *buf) 14168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 142287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct r300_screen *r300screen = r300_screen(screen); 14368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_buffer *rbuf = r300_buffer(buf); 14468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 14568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie r300_winsys_buffer_destroy(r300screen, rbuf); 14668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie FREE(rbuf); 14768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 14868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 14968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void * 15068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlier300_buffer_map_range(struct pipe_screen *screen, 151287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *buf, 15268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned offset, unsigned length, 15368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned usage ) 15468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 15568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_screen *r300screen = r300_screen(screen); 15668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_winsys_screen *rws = r300screen->rws; 15768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_buffer *rbuf = r300_buffer(buf); 15868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie void *map; 15968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie int flush = 0; 16068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie int i; 16168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 16268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (rbuf->user_buffer) 16368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return rbuf->user_buffer; 16468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 165287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) { 16668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie goto just_map; 167287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell } 16868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 16968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie /* check if the mapping is to a range we already flushed */ 170287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (usage & PIPE_TRANSFER_DISCARD) { 17168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie for (i = 0; i < rbuf->num_ranges; i++) { 17268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 17368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if ((offset >= rbuf->ranges[i].start) && 17468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie (offset < rbuf->ranges[i].end)) 17568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie flush = 1; 17668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 17768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (flush) { 17868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie /* unreference this hw buffer and allocate a new one */ 17968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rws->buffer_reference(rws, &rbuf->buf, NULL); 18068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 18168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->num_ranges = 0; 18268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->map = NULL; 18368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->buf = r300_winsys_buffer_create(r300screen, 184287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 16, 185287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.bind, /* XXX */ 186287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.width0); 18768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie break; 18868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 18968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 19068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 19168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliejust_map: 192bc5778e2023543e5049ab41398aa28fb0709f5f2Marek Olšák map = rws->buffer_map(rws, rbuf->buf, usage); 19368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 19468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return map; 19568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 19668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 19768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void 19868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlier300_buffer_flush_mapped_range( struct pipe_screen *screen, 199287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *buf, 20068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned offset, 20168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie unsigned length ) 20268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 20368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_buffer *rbuf = r300_buffer(buf); 20468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie int i; 20568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 20668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if (rbuf->user_buffer) 20768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return; 20868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 209287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) 21068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return; 21168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 21268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie /* mark the range as used */ 21368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie for(i = 0; i < rbuf->num_ranges; ++i) { 21468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie if(offset <= rbuf->ranges[i].end && rbuf->ranges[i].start <= (offset+length)) { 21568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->ranges[i].start = MIN2(rbuf->ranges[i].start, offset); 21668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->ranges[i].end = MAX2(rbuf->ranges[i].end, (offset+length)); 21768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie return; 21868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 21968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie } 22068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 22168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->ranges[rbuf->num_ranges].start = offset; 22268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->ranges[rbuf->num_ranges].end = offset+length; 22368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie rbuf->num_ranges++; 22468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 22568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 226287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 227287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void 228287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellr300_buffer_unmap(struct pipe_screen *screen, 229287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_resource *buf) 23068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 23168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_screen *r300screen = r300_screen(screen); 23268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_winsys_screen *rws = r300screen->rws; 23368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_buffer *rbuf = r300_buffer(buf); 23468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 235287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (rbuf->buf) { 236287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rws->buffer_unmap(rws, rbuf->buf); 237287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell } 238287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell} 23968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 24068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 241287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 242287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 243287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/* As a first step, keep the original code intact, implement buffer 244287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * transfers in terms of the old map/unmap functions. 245287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * 246287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * Utility functions for transfer create/destroy are hooked in and 247287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * just record the arguments to those functions. 248287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */ 249287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void * 250287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellr300_buffer_transfer_map( struct pipe_context *pipe, 251287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_transfer *transfer ) 252287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 253287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell uint8_t *map = r300_buffer_map_range( pipe->screen, 254287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell transfer->resource, 255287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell transfer->box.x, 256287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell transfer->box.width, 257287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell transfer->usage ); 258287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (map == NULL) 259287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return NULL; 260287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 261287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell /* map_buffer() returned a pointer to the beginning of the buffer, 262287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * but transfers are expected to return a pointer to just the 263287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * region specified in the box. 264287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */ 265287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return map + transfer->box.x; 26668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 26768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 268287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 269287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 270287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void r300_buffer_transfer_flush_region( struct pipe_context *pipe, 271287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_transfer *transfer, 272287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell const struct pipe_box *box) 273287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 274287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell assert(box->x + box->width <= transfer->box.width); 275287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 276287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell r300_buffer_flush_mapped_range(pipe->screen, 277287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell transfer->resource, 278287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell transfer->box.x + box->x, 279287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell box->width); 280287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell} 281287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 282287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void r300_buffer_transfer_unmap( struct pipe_context *pipe, 283287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct pipe_transfer *transfer ) 284287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 285287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell r300_buffer_unmap(pipe->screen, 286287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell transfer->resource); 287287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell} 288287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 289287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 290287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 291287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 292287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct u_resource_vtbl r300_buffer_vtbl = 293287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{ 294287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell u_default_resource_get_handle, /* get_handle */ 295287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell r300_buffer_destroy, /* resource_destroy */ 296287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell r300_buffer_is_referenced, /* is_buffer_referenced */ 297287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell u_default_get_transfer, /* get_transfer */ 298287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell u_default_transfer_destroy, /* transfer_destroy */ 299287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell r300_buffer_transfer_map, /* transfer_map */ 300287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell r300_buffer_transfer_flush_region, /* transfer_flush_region */ 301287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell r300_buffer_transfer_unmap, /* transfer_unmap */ 302287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell u_default_transfer_inline_write /* transfer_inline_write */ 303287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}; 304287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 305287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 306287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 307287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 308287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_buffer_create(struct pipe_screen *screen, 309287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell const struct pipe_resource *template) 31068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 31168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie struct r300_screen *r300screen = r300_screen(screen); 312287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct r300_buffer *rbuf; 313287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell unsigned alignment = 16; 31468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 315287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf = CALLOC_STRUCT(r300_buffer); 316287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (!rbuf) 317287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell goto error1; 318287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 319287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->magic = R300_BUFFER_MAGIC; 320287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 321287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b = *template; 322287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.vtbl = &r300_buffer_vtbl; 323287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_reference_init(&rbuf->b.b.reference, 1); 324287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.screen = screen; 325287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 326287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (rbuf->b.b.bind & R300_BIND_OQBO) 327287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell alignment = 4096; 328287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 329287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->buf = r300_winsys_buffer_create(r300screen, 330287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell alignment, 331287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.bind, 332287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.width0); 333287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 334287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (!rbuf->buf) 335287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell goto error2; 336287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 337287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return &rbuf->b.b; 338287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellerror2: 339287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell FREE(rbuf); 340287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellerror1: 341287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return NULL; 34268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 34368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie 344287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 345287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, 346287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell void *ptr, 347287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell unsigned bytes, 348287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell unsigned bind) 34968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{ 350287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell struct r300_buffer *rbuf; 351287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 352287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf = CALLOC_STRUCT(r300_buffer); 353287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell if (!rbuf) 354287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell goto no_rbuf; 355287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 356287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->magic = R300_BUFFER_MAGIC; 357287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 358287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell pipe_reference_init(&rbuf->b.b.reference, 1); 359287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.vtbl = &r300_buffer_vtbl; 360287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.screen = screen; 361287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; 362287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b._usage = PIPE_USAGE_IMMUTABLE; 363287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.bind = bind; 364287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.width0 = bytes; 365287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.height0 = 1; 366287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->b.b.depth0 = 1; 367287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 368287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell rbuf->user_buffer = ptr; 369287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return &rbuf->b.b; 370287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 371287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellno_rbuf: 372287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell return NULL; 37368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie} 374287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell 375