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