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