~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/gallium/drivers/r600/r600_buffer.c

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 */
27
27
#include <byteswap.h>
28
28
 
29
 
#include <pipe/p_screen.h>
30
 
#include <util/u_format.h>
31
 
#include <util/u_math.h>
32
 
#include <util/u_inlines.h>
33
 
#include <util/u_memory.h>
 
29
#include "pipe/p_screen.h"
 
30
#include "util/u_format.h"
 
31
#include "util/u_math.h"
 
32
#include "util/u_inlines.h"
 
33
#include "util/u_memory.h"
34
34
#include "util/u_upload_mgr.h"
35
35
 
36
 
#include "state_tracker/drm_driver.h"
37
 
 
38
 
#include <xf86drm.h>
39
 
#include "radeon_drm.h"
40
 
 
41
36
#include "r600.h"
42
37
#include "r600_pipe.h"
43
38
 
45
40
                                struct pipe_resource *buf)
46
41
{
47
42
        struct r600_screen *rscreen = (struct r600_screen*)screen;
48
 
        struct r600_resource_buffer *rbuffer = r600_buffer(buf);
 
43
        struct r600_resource *rbuffer = r600_resource(buf);
49
44
 
50
 
        if (rbuffer->r.bo) {
51
 
                r600_bo_reference((struct radeon*)screen->winsys, &rbuffer->r.bo, NULL);
52
 
        }
53
 
        rbuffer->r.bo = NULL;
 
45
        pb_reference(&rbuffer->buf, NULL);
54
46
        util_slab_free(&rscreen->pool_buffers, rbuffer);
55
47
}
56
48
 
80
72
static void *r600_buffer_transfer_map(struct pipe_context *pipe,
81
73
                                      struct pipe_transfer *transfer)
82
74
{
83
 
        struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
 
75
        struct r600_resource *rbuffer = r600_resource(transfer->resource);
 
76
        struct r600_pipe_context *rctx = (struct r600_pipe_context*)pipe;
84
77
        uint8_t *data;
85
78
 
86
 
        if (rbuffer->r.b.user_ptr)
87
 
                return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x;
 
79
        if (rbuffer->b.user_ptr)
 
80
                return (uint8_t*)rbuffer->b.user_ptr + transfer->box.x;
88
81
 
89
 
        data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, transfer->usage, pipe);
 
82
        data = rctx->ws->buffer_map(rbuffer->buf, rctx->ctx.cs, transfer->usage);
90
83
        if (!data)
91
84
                return NULL;
92
85
 
96
89
static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
97
90
                                        struct pipe_transfer *transfer)
98
91
{
99
 
        struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
 
92
        struct r600_resource *rbuffer = r600_resource(transfer->resource);
 
93
        struct r600_pipe_context *rctx = (struct r600_pipe_context*)pipe;
100
94
 
101
 
        if (rbuffer->r.b.user_ptr)
 
95
        if (rbuffer->b.user_ptr)
102
96
                return;
103
97
 
104
 
        if (rbuffer->r.bo)
105
 
                r600_bo_unmap((struct radeon*)pipe->winsys, rbuffer->r.bo);
 
98
        rctx->ws->buffer_unmap(rbuffer->buf);
106
99
}
107
100
 
108
101
static void r600_buffer_transfer_flush_region(struct pipe_context *pipe,
127
120
                                                unsigned stride,
128
121
                                                unsigned layer_stride)
129
122
{
130
 
        struct radeon *ws = (struct radeon*)pipe->winsys;
131
 
        struct r600_resource_buffer *rbuffer = r600_buffer(resource);
 
123
        struct r600_pipe_context *rctx = (struct r600_pipe_context*)pipe;
 
124
        struct r600_resource *rbuffer = r600_resource(resource);
132
125
        uint8_t *map = NULL;
133
126
 
134
 
        assert(rbuffer->r.b.user_ptr == NULL);
 
127
        assert(rbuffer->b.user_ptr == NULL);
135
128
 
136
 
        map = r600_bo_map(ws, rbuffer->r.bo,
137
 
                          PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage,
138
 
                          pipe);
 
129
        map = rctx->ws->buffer_map(rbuffer->buf, rctx->ctx.cs,
 
130
                                   PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE | usage);
139
131
 
140
132
        memcpy(map + box->x, data, box->width);
141
133
 
142
 
        if (rbuffer->r.bo)
143
 
                r600_bo_unmap(ws, rbuffer->r.bo);
 
134
        rctx->ws->buffer_unmap(rbuffer->buf);
144
135
}
145
136
 
146
137
static const struct u_resource_vtbl r600_buffer_vtbl =
155
146
        r600_buffer_transfer_inline_write       /* transfer_inline_write */
156
147
};
157
148
 
 
149
bool r600_init_resource(struct r600_screen *rscreen,
 
150
                        struct r600_resource *res,
 
151
                        unsigned size, unsigned alignment,
 
152
                        unsigned bind, unsigned usage)
 
153
{
 
154
        uint32_t initial_domain, domains;
 
155
 
 
156
        /* Staging resources particpate in transfers and blits only
 
157
         * and are used for uploads and downloads from regular
 
158
         * resources.  We generate them internally for some transfers.
 
159
         */
 
160
        if (usage == PIPE_USAGE_STAGING) {
 
161
                domains = RADEON_DOMAIN_GTT;
 
162
                initial_domain = RADEON_DOMAIN_GTT;
 
163
        } else {
 
164
                domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
 
165
 
 
166
                switch(usage) {
 
167
                case PIPE_USAGE_DYNAMIC:
 
168
                case PIPE_USAGE_STREAM:
 
169
                case PIPE_USAGE_STAGING:
 
170
                        initial_domain = RADEON_DOMAIN_GTT;
 
171
                        break;
 
172
                case PIPE_USAGE_DEFAULT:
 
173
                case PIPE_USAGE_STATIC:
 
174
                case PIPE_USAGE_IMMUTABLE:
 
175
                default:
 
176
                        initial_domain = RADEON_DOMAIN_VRAM;
 
177
                        break;
 
178
                }
 
179
        }
 
180
 
 
181
        res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment, bind, initial_domain);
 
182
        if (!res->buf) {
 
183
                return false;
 
184
        }
 
185
 
 
186
        res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf);
 
187
        res->domains = domains;
 
188
        return true;
 
189
}
 
190
 
158
191
struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
159
192
                                         const struct pipe_resource *templ)
160
193
{
161
194
        struct r600_screen *rscreen = (struct r600_screen*)screen;
162
 
        struct r600_resource_buffer *rbuffer;
163
 
        struct r600_bo *bo;
 
195
        struct r600_resource *rbuffer;
164
196
        /* XXX We probably want a different alignment for buffers and textures. */
165
197
        unsigned alignment = 4096;
166
198
 
167
199
        rbuffer = util_slab_alloc(&rscreen->pool_buffers);
168
200
 
169
 
        rbuffer->magic = R600_BUFFER_MAGIC;
170
 
        rbuffer->r.b.b.b = *templ;
171
 
        pipe_reference_init(&rbuffer->r.b.b.b.reference, 1);
172
 
        rbuffer->r.b.b.b.screen = screen;
173
 
        rbuffer->r.b.b.vtbl = &r600_buffer_vtbl;
174
 
        rbuffer->r.b.user_ptr = NULL;
175
 
        rbuffer->r.size = rbuffer->r.b.b.b.width0;
176
 
        rbuffer->r.bo_size = rbuffer->r.size;
177
 
 
178
 
        bo = r600_bo((struct radeon*)screen->winsys,
179
 
                     rbuffer->r.b.b.b.width0,
180
 
                     alignment, rbuffer->r.b.b.b.bind,
181
 
                     rbuffer->r.b.b.b.usage);
182
 
 
183
 
        if (bo == NULL) {
184
 
                FREE(rbuffer);
 
201
        rbuffer->b.b.b = *templ;
 
202
        pipe_reference_init(&rbuffer->b.b.b.reference, 1);
 
203
        rbuffer->b.b.b.screen = screen;
 
204
        rbuffer->b.b.vtbl = &r600_buffer_vtbl;
 
205
        rbuffer->b.user_ptr = NULL;
 
206
 
 
207
        if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, templ->bind, templ->usage)) {
 
208
                util_slab_free(&rscreen->pool_buffers, rbuffer);
185
209
                return NULL;
186
210
        }
187
 
        rbuffer->r.bo = bo;
188
 
        return &rbuffer->r.b.b.b;
 
211
        return &rbuffer->b.b.b;
189
212
}
190
213
 
191
214
struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
193
216
                                              unsigned bind)
194
217
{
195
218
        struct r600_screen *rscreen = (struct r600_screen*)screen;
196
 
        struct r600_resource_buffer *rbuffer;
 
219
        struct r600_resource *rbuffer;
197
220
 
198
221
        rbuffer = util_slab_alloc(&rscreen->pool_buffers);
199
222
 
200
 
        rbuffer->magic = R600_BUFFER_MAGIC;
201
 
        pipe_reference_init(&rbuffer->r.b.b.b.reference, 1);
202
 
        rbuffer->r.b.b.vtbl = &r600_buffer_vtbl;
203
 
        rbuffer->r.b.b.b.screen = screen;
204
 
        rbuffer->r.b.b.b.target = PIPE_BUFFER;
205
 
        rbuffer->r.b.b.b.format = PIPE_FORMAT_R8_UNORM;
206
 
        rbuffer->r.b.b.b.usage = PIPE_USAGE_IMMUTABLE;
207
 
        rbuffer->r.b.b.b.bind = bind;
208
 
        rbuffer->r.b.b.b.width0 = bytes;
209
 
        rbuffer->r.b.b.b.height0 = 1;
210
 
        rbuffer->r.b.b.b.depth0 = 1;
211
 
        rbuffer->r.b.b.b.array_size = 1;
212
 
        rbuffer->r.b.b.b.flags = 0;
213
 
        rbuffer->r.b.user_ptr = ptr;
214
 
        rbuffer->r.bo = NULL;
215
 
        rbuffer->r.bo_size = 0;
216
 
        return &rbuffer->r.b.b.b;
217
 
}
218
 
 
219
 
struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
220
 
                                              struct winsys_handle *whandle)
221
 
{
222
 
        struct radeon *rw = (struct radeon*)screen->winsys;
223
 
        struct r600_resource *rbuffer;
224
 
        struct r600_bo *bo = NULL;
225
 
 
226
 
        bo = r600_bo_handle(rw, whandle->handle, NULL);
227
 
        if (bo == NULL) {
228
 
                return NULL;
229
 
        }
230
 
 
231
 
        rbuffer = CALLOC_STRUCT(r600_resource);
232
 
        if (rbuffer == NULL) {
233
 
                r600_bo_reference(rw, &bo, NULL);
234
 
                return NULL;
235
 
        }
236
 
 
237
223
        pipe_reference_init(&rbuffer->b.b.b.reference, 1);
 
224
        rbuffer->b.b.vtbl = &r600_buffer_vtbl;
 
225
        rbuffer->b.b.b.screen = screen;
238
226
        rbuffer->b.b.b.target = PIPE_BUFFER;
239
 
        rbuffer->b.b.b.screen = screen;
240
 
        rbuffer->b.b.vtbl = &r600_buffer_vtbl;
241
 
        rbuffer->bo = bo;
 
227
        rbuffer->b.b.b.format = PIPE_FORMAT_R8_UNORM;
 
228
        rbuffer->b.b.b.usage = PIPE_USAGE_IMMUTABLE;
 
229
        rbuffer->b.b.b.bind = bind;
 
230
        rbuffer->b.b.b.width0 = bytes;
 
231
        rbuffer->b.b.b.height0 = 1;
 
232
        rbuffer->b.b.b.depth0 = 1;
 
233
        rbuffer->b.b.b.array_size = 1;
 
234
        rbuffer->b.b.b.flags = 0;
 
235
        rbuffer->b.user_ptr = ptr;
 
236
        rbuffer->buf = NULL;
242
237
        return &rbuffer->b.b.b;
243
238
}
244
239
 
245
 
void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw)
 
240
void r600_upload_index_buffer(struct r600_pipe_context *rctx,
 
241
                              struct pipe_index_buffer *ib, unsigned count)
246
242
{
247
 
        struct r600_resource_buffer *rbuffer = r600_buffer(draw->index_buffer);
248
 
        boolean flushed;
 
243
        struct r600_resource *rbuffer = r600_resource(ib->buffer);
249
244
 
250
 
        u_upload_data(rctx->vbuf_mgr->uploader, 0,
251
 
                      draw->info.count * draw->index_size,
252
 
                      rbuffer->r.b.user_ptr,
253
 
                      &draw->index_buffer_offset,
254
 
                      &draw->index_buffer, &flushed);
 
245
        u_upload_data(rctx->vbuf_mgr->uploader, 0, count * ib->index_size,
 
246
                      rbuffer->b.user_ptr, &ib->offset, &ib->buffer);
255
247
}
256
248
 
257
 
void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource_buffer **rbuffer,
 
249
void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource **rbuffer,
258
250
                             uint32_t *const_offset)
259
251
{
260
 
        if ((*rbuffer)->r.b.user_ptr) {
261
 
                uint8_t *ptr = (*rbuffer)->r.b.user_ptr;
262
 
                unsigned size = (*rbuffer)->r.b.b.b.width0;
263
 
                boolean flushed;
 
252
        if ((*rbuffer)->b.user_ptr) {
 
253
                uint8_t *ptr = (*rbuffer)->b.user_ptr;
 
254
                unsigned size = (*rbuffer)->b.b.b.width0;
264
255
 
265
256
                *rbuffer = NULL;
266
257
 
278
269
                        }
279
270
 
280
271
                        u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset,
281
 
                                      (struct pipe_resource**)rbuffer, &flushed);
 
272
                                      (struct pipe_resource**)rbuffer);
282
273
 
283
274
                        free(tmpPtr);
284
275
                } else {
285
276
                        u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset,
286
 
                                      (struct pipe_resource**)rbuffer, &flushed);
 
277
                                      (struct pipe_resource**)rbuffer);
287
278
                }
288
279
        } else {
289
280
                *const_offset = 0;