r300_screen_buffer.c revision 0b4df63609e9fb25319debd56142a90b11d75671
168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie/*
268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Copyright 2010 Red Hat Inc.
368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a
568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * copy of this software and associated documentation files (the "Software"),
668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * to deal in the Software without restriction, including without limitation
768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * on the rights to use, copy, modify, merge, publish, distribute, sub
868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * license, and/or sell copies of the Software, and to permit persons to whom
968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * the Software is furnished to do so, subject to the following conditions:
1068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
1168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * The above copyright notice and this permission notice (including the next
1268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * paragraph) shall be included in all copies or substantial portions of the
1368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Software.
1468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
1568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
1968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * USE OR OTHER DEALINGS IN THE SOFTWARE.
2268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie *
2368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie * Authors: Dave Airlie
2468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie */
250b4df63609e9fb25319debd56142a90b11d75671Marek Olšák
2668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include <stdio.h>
2768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
2868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_inlines.h"
2968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_format.h"
3068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_memory.h"
3168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_upload_mgr.h"
3268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_math.h"
3368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
3468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "r300_screen_buffer.h"
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
830b4df63609e9fb25319debd56142a90b11d75671Marek Olšák/* External helper, not required to implement 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	if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) {
94287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell	    struct pipe_resource *upload_buffer = NULL;
9568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    unsigned offset = 0; /*r300->vertex_buffer[i].buffer_offset * 4;*/
96287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell	    unsigned size = r300->vertex_buffer[i].buffer->width0;
9768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    unsigned upload_offset;
9868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    ret = u_upload_buffer(r300->upload_vb,
9968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie				  offset, size,
10068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie				  r300->vertex_buffer[i].buffer,
10168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie				  &upload_offset, &upload_buffer);
10268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    if (ret)
10368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		return ret;
10468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
105287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell	    pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
10668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    r300->vertex_buffer[i].buffer = upload_buffer;
10768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    r300->vertex_buffer[i].buffer_offset = upload_offset;
10868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	}
10968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
11068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    return ret;
11168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
11268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
11368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic struct r300_winsys_buffer *
11468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlier300_winsys_buffer_create(struct r300_screen *r300screen,
11568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie			  unsigned alignment,
11668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie			  unsigned usage,
11768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie			  unsigned size)
11868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
11968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
12068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_buffer *buf;
12168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
12268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    buf = rws->buffer_create(rws, alignment, usage, size);
12368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    return buf;
12468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
12568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
12668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void r300_winsys_buffer_destroy(struct r300_screen *r300screen,
12768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie				       struct r300_buffer *rbuf)
12868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
12968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
13068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
13168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (rbuf->buf) {
13268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	rws->buffer_reference(rws, &rbuf->buf, NULL);
13368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	rbuf->buf = NULL;
13468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
13568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
13668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
137287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void r300_buffer_destroy(struct pipe_screen *screen,
138287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				struct pipe_resource *buf)
13968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
140287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_screen *r300screen = r300_screen(screen);
14168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_buffer *rbuf = r300_buffer(buf);
14268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
14368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    r300_winsys_buffer_destroy(r300screen, rbuf);
14468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    FREE(rbuf);
14568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
14668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
14768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliestatic void *
148d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákr300_buffer_transfer_map( struct pipe_context *pipe,
149d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák			  struct pipe_transfer *transfer )
15068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
151d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_screen *r300screen = r300_screen(pipe->screen);
15268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
153d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
154d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    uint8_t *map;
155d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    boolean flush = FALSE;
156d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned i;
15768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
15868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (rbuf->user_buffer)
159d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák        return rbuf->user_buffer + transfer->box.x;
16068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
161287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
16268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	goto just_map;
163287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    }
16468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
16568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    /* check if the mapping is to a range we already flushed */
166d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    if (transfer->usage & PIPE_TRANSFER_DISCARD) {
16768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	for (i = 0; i < rbuf->num_ranges; i++) {
168d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák	    if ((transfer->box.x >= rbuf->ranges[i].start) &&
169d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák		(transfer->box.x < rbuf->ranges[i].end))
170d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák		flush = TRUE;
17168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
17268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    if (flush) {
17368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		/* unreference this hw buffer and allocate a new one */
17468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rws->buffer_reference(rws, &rbuf->buf, NULL);
17568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
17668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rbuf->num_ranges = 0;
17768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rbuf->map = NULL;
17868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		rbuf->buf = r300_winsys_buffer_create(r300screen,
179287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell						      16,
180287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell						      rbuf->b.b.bind, /* XXX */
181287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell						      rbuf->b.b.width0);
18268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie		break;
18368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    }
18468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	}
18568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
18668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airliejust_map:
187d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    map = rws->buffer_map(rws, rbuf->buf, transfer->usage);
188d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
189d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    if (map == NULL)
190d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák        return NULL;
191d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
192d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    /* map_buffer() returned a pointer to the beginning of the buffer,
193d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     * but transfers are expected to return a pointer to just the
194d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     * region specified in the box.
195d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák     */
196d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    return map + transfer->box.x;
19768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
19868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
199d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákstatic void r300_buffer_transfer_flush_region( struct pipe_context *pipe,
200d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák					       struct pipe_transfer *transfer,
201d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák					       const struct pipe_box *box)
20268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
203d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
204d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned i;
205d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned offset = transfer->box.x + box->x;
206d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    unsigned length = box->width;
207d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák
208d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    assert(box->x + box->width <= transfer->box.width);
20968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
21068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    if (rbuf->user_buffer)
21168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	return;
21268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
213287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER)
21468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	return;
21568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
21668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    /* mark the range as used */
21768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    for(i = 0; i < rbuf->num_ranges; ++i) {
218d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák	if(offset <= rbuf->ranges[i].end && rbuf->ranges[i].start <= (offset+box->width)) {
21968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    rbuf->ranges[i].start = MIN2(rbuf->ranges[i].start, offset);
22068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    rbuf->ranges[i].end   = MAX2(rbuf->ranges[i].end, (offset+length));
22168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	    return;
22268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie	}
22368e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    }
22468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
22568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->ranges[rbuf->num_ranges].start = offset;
22668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->ranges[rbuf->num_ranges].end = offset+length;
22768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    rbuf->num_ranges++;
22868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
22968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
230d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšákstatic void r300_buffer_transfer_unmap( struct pipe_context *pipe,
231d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák			    struct pipe_transfer *transfer )
23268e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
233d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_screen *r300screen = r300_screen(pipe->screen);
23468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_winsys_screen *rws = r300screen->rws;
235d3e7dfc1fd7753d6305afb402e432ff45a7c0707Marek Olšák    struct r300_buffer *rbuf = r300_buffer(transfer->resource);
23668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
237287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (rbuf->buf) {
238287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell        rws->buffer_unmap(rws, rbuf->buf);
239287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    }
240287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
24168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
242287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct u_resource_vtbl r300_buffer_vtbl =
243287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
244287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_resource_get_handle,      /* get_handle */
245287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   r300_buffer_destroy,		     /* resource_destroy */
246287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   r300_buffer_is_referenced,	     /* is_buffer_referenced */
247287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_get_transfer,	     /* get_transfer */
248287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_transfer_destroy,	     /* transfer_destroy */
249287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   r300_buffer_transfer_map,	     /* transfer_map */
250287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   r300_buffer_transfer_flush_region,  /* transfer_flush_region */
251287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   r300_buffer_transfer_unmap,	     /* transfer_unmap */
252287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_transfer_inline_write   /* transfer_inline_write */
253287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell};
254287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
255287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
256bb4f5fff0c782f35353e8bfc1b1227e3cc3d5986Marek Olšák					 const struct pipe_resource *templ)
25768e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
25868e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie    struct r300_screen *r300screen = r300_screen(screen);
259287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_buffer *rbuf;
260287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    unsigned alignment = 16;
26168e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
262287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf = CALLOC_STRUCT(r300_buffer);
263287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (!rbuf)
264287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell	goto error1;
265287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
266287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->magic = R300_BUFFER_MAGIC;
267287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
268bb4f5fff0c782f35353e8bfc1b1227e3cc3d5986Marek Olšák    rbuf->b.b = *templ;
269287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.vtbl = &r300_buffer_vtbl;
270287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    pipe_reference_init(&rbuf->b.b.reference, 1);
271287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.screen = screen;
272287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
273287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (rbuf->b.b.bind & R300_BIND_OQBO)
2740b4df63609e9fb25319debd56142a90b11d75671Marek Olšák        alignment = 4096;
275287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
276287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->buf = r300_winsys_buffer_create(r300screen,
277287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					  alignment,
278287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					  rbuf->b.b.bind,
279287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					  rbuf->b.b.width0);
280287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
281287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (!rbuf->buf)
282287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell	goto error2;
283287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
284287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return &rbuf->b.b;
285287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellerror2:
286287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    FREE(rbuf);
287287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellerror1:
288287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return NULL;
28968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
29068e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
291287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
292287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      void *ptr,
293287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      unsigned bytes,
294287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					      unsigned bind)
29568e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie{
296287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct r300_buffer *rbuf;
297287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
298287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf = CALLOC_STRUCT(r300_buffer);
299287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    if (!rbuf)
300287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell	goto no_rbuf;
301287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
302287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->magic = R300_BUFFER_MAGIC;
303287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
304287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    pipe_reference_init(&rbuf->b.b.reference, 1);
305287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.vtbl = &r300_buffer_vtbl;
306287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.screen = screen;
307287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
308287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b._usage = PIPE_USAGE_IMMUTABLE;
309287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.bind = bind;
310287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.width0 = bytes;
311287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.height0 = 1;
312287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->b.b.depth0 = 1;
313287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
314287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    rbuf->user_buffer = ptr;
315287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return &rbuf->b.b;
316287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
317287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellno_rbuf:
318287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    return NULL;
31968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie}
320